1. Open the hatshop.cssfile in the hatshopfolder, and add the styles shown in the following code listing.
These styles refer to the way department names should look inside the departments list when they are unselected, unselected but with the mouse hovering over them, or selected.
.left_box p {
color: #ffffff;
font-family: arial, tahoma, verdana;
font-size: 12px;
font-weight: bold;
C H A P T E R 3 ■ C R E AT I NG T H E P R O D U C T C ATA L OG: PA RT I 96
margin: 0px 0px 5px 0px;
padding: 2px 0px 2px 12px;
}
#departments_box {
position: relative;
border: 1px solid #30b86e;
}
#departments_box p {
background: #30b86e;
} a {
color: #a6a6a6;
font-family: verdana, arial, tahoma;
font-size: 10px;
font-weight: bold;
line-height: 20px;
text-decoration: none;
} a:hover {
color: #000000;
}
a.selected {
color: #000000;
text-decoration: underline;
} ol {
list-style-type: none;
margin: 0px 5px;
padding: 0px;
}
2. Edit the presentation/page.phpfile, and add the following two lines to the constructor of the page class. These lines configure the plugin folders used by Smarty. The first one is for the internal Smarty plug- ins, and the second specifies the smarty_pluginsfolder you’ll create to hold the plugins you’ll write for HatShop.
/* Class that extends Smarty, used to process and display Smarty files */
class Page extends Smarty {
// Class constructor
public function __construct()
{
// Call Smarty's constructor parent::Smarty();
// Change the default template directories
$this->template_dir = TEMPLATE_DIR;
$this->compile_dir = COMPILE_DIR;
$this->config_dir = CONFIG_DIR;
$this->plugins_dir[0] = SMARTY_DIR . 'plugins';
$this->plugins_dir[1] = PRESENTATION_DIR . 'smarty_plugins';
} }
3. Now create the Smarty template file for the departments_listcomponentized template.Write the follow- ing lines in presentation/templates/departments_list.tpl:
{* departments_list.tpl *}
{load_departments_list assign="departments_list"}
{* Start departments list *}
<div class="left_box" id="departments_box">
<p>Choose a Department</p>
<ol>
{* Loop through the list of departments *}
{section name=i loop=$departments_list->mDepartments}
{assign var=selected_d value=""}
{* Verify if the department is selected to decide what CSS style to use *}
{if ($departments_list->mSelectedDepartment ==
$departments_list->mDepartments[i].department_id)}
{assign var=selected_d value="class=\"selected\""}
{/if}
<li>
{* Generate a link for a new department in the list *}
<a {$selected_d}
href="{$departments_list->mDepartments[i].link|escape:"html"}">
» {$departments_list->mDepartments[i].name}
</a>
</li>
{/section}
</ol>
</div>
{* End departments list *}
4. Create a folder named smarty_pluginsin the presentationfolder. This will contain the Smarty plugin files.
C H A P T E R 3 ■ C R E AT I NG T H E P R O D U C T C ATA L OG: PA RT I 98
5. Inside the smarty_pluginsfolder, create a file named function.load_departments_list.php, and add the following code to it:
<?php
// Plugin functions inside plugin files must be named: smarty_type_name function smarty_function_load_departments_list($params, $smarty) {
// Create DepartmentsList object
$departments_list = new DepartmentsList();
$departments_list->init();
// Assign template variable
$smarty->assign($params['assign'], $departments_list);
}
// Manages the departments list class DepartmentsList
{
/* Public variables available in departments_list.tpl Smarty template */
public $mDepartments;
public $mSelectedDepartment;
// Constructor reads query string parameter public function __construct()
{
/* If DepartmentID exists in the query string, we're visiting a department */
if (isset ($_GET['DepartmentID']))
$this->mSelectedDepartment = (int)$_GET['DepartmentID'];
else
$this->mSelectedDepartment = -1;
}
/* Calls business tier method to read departments list and create their links */
public function init() {
// Get the list of departments from the business tier
$this->mDepartments = Catalog::GetDepartments();
// Create the department links
for ($i = 0; $i < count($this->mDepartments); $i++)
$this->mDepartments[$i]['link'] = 'index.php?DepartmentID=' .
$this->mDepartments[$i]['department_id'];
} }
?>
6. Modify the include/app_top.phpfile to include a reference to the Catalogbusiness tier class:
<?php
// Include utility files
require_once 'include/config.php';
require_once BUSINESS_DIR . 'error_handler.php';
// Sets the error handler ErrorHandler::SetHandler();
// Load the page template
require_once PRESENTATION_DIR . 'page.php';
// Load the database handler
require_once BUSINESS_DIR . 'database_handler.php';
// Load Business Tier
require_once BUSINESS_DIR . 'catalog.php';
?>
7. Make the following modification in presentation/templates/index.tplto load the newly created departments_listcomponentized template. Search for the following code:
<div class="left_box">
Place list of departments here
</div>
and replace it with this:
{include file="departments_list.tpl"}
8. Examine the result of your work with your favorite browser by loading http://localhost/hatshop/
index.php(refer to Figure 3-14). Play a little with the page to see what happens when you click on a department or place the mouse over a link.
■ Note If you don’t get the expected output, make sure your machine is configured correctly and all PHP required modules, such as PDO, were loaded successfully. Many errors will be reported in the Apache error log file (by default,Apache2/logs/error.log).
How It Works: The departments_list Smarty Template
If the page worked as expected from the start, you’re certainly one lucky programmer! Most of the time, errors happen because of typos, so watch out for them! Database access problems are also common, so make sure you correctly configured the hatshopdatabase and the hatshopadmin user, as shown in Chapter 2. In any case, we’re lucky to have a good error-reporting mechanism, which shows a detailed error report if something goes wrong.
Figure 3-15 shows the error message I received when mistyping the database password in config.php.
C H A P T E R 3 ■ C R E AT I NG T H E P R O D U C T C ATA L OG: PA RT I 100
Figure 3-15.The error-handling code you’ve written in Chapter 2 is helpful for debugging.
If everything goes right, however, you’ll get the neat page containing a list of departments generated using a Smarty template. Each department name in the list is a link to the department’s page, which in fact is a link to the index.phppage with a DepartmentIDparameter in the query string that specifies which department was selected. Here’s an example of such a link:
http://localhost/hatshop/index.php?DepartmentID=3
When clicking a department’s link, the selected department will be displayed using a different CSS style in the list (see Figure 3-16).
Figure 3-16.Selecting a department
It is important to understand how the Smarty template file (presentation/templates/
departments_list.tpl) and its associated plugin file (presentation/smarty_plugins/
function.load_departments_list.php) work together to generate the list of departments, and use the correct style for the currently selected one.
The processing starts at function.load_departments_list.php, which is included in the index.tplfile.
The first line in departments_list.tplloads the plugin:
{load_departments_list assign="departments_list"}
The load_departments_listplugin function creates and initializes a DepartmentsListobject (this class is included in function.load_departments_list.php), which is then assigned to a variable accessible from the Smarty design template file:
function smarty_function_load_departments_list($params, $smarty) {
// Create DepartmentsList object
$departments_list = new DepartmentsList();
$departments_list->init();
// Assign template variable
$smarty->assign($params['assign'], $departments_list);
}
The init()method in DepartmentsListpopulates a public member of the class ($mDepartments) with an array containing the list of departments and another public member containing the index of the currently selected department ($mSelectedDepartment).
Back to the Smarty code now. Inside the HTML code that forms the layout of the Smarty template
(presentation/templates/departments_list.tpl), you can see the Smarty tags that do the magic:
{section name=i loop=$departments_list->mDepartments}
{assign var=selected_d value=""}
{* Verify if the department is selected to decide what CSS style to use *}
{if ($departments_list->mSelectedDepartment ==
$departments_list->mDepartments[i].department_id)}
{assign var=selected_d value="class=\"selected\""}
{/if}
{* Generate a link for a new department in the list *}
<li>
<a {$selected_d}
href="{$departments_list->mDepartments[i].link|escape:"html"}">
» {$departments_list->mDepartments[i].name}
</a>
</li>
{/section}
Smarty template sections are used for looping over arrays of data. In this case, you want to loop over the depart- ments array kept in $departmentsList->mDepartments:
C H A P T E R 3 ■ C R E AT I NG T H E P R O D U C T C ATA L OG: PA RT I 102
{section name=i loop=$departments_list->mDepartments}
...
{/section}
Inside the loop, you verify whether the current department in the loop ($departments_
list->mDepartments[i].department_id) has the IDthat was mentioned in the query string ($departments_list->mSelectedDepartment). Depending on this, you decide what style to apply to the name by saving the style name (selectedor default style) to a variable named selected_d.
This variable is then used to generate the link:
<a {$selected_d}
href="{$departments_list->mDepartments[i].link|escape:"html"}">
» {$departments_list->mDepartments[i].name}
</a>