7.3 Packages
In
this section, we
discuss the optional packages that are available with PEAR, how to
find out about them, how to find new ones, and how to install the
ones you need. However, our focus is the optional HTML
Integrated Template (IT) package
, which is used to separate
HTML presentation from PHP code. We show you how to use templates in
an application, present working examples, and detail the key
functions from the package and its extended child ITX
templates. A longer template case study is presented in
Chapter 16.
After our discussion of the IT package, we list the other packages
that are available, and point to where selected packages are used in
other chapters of this book.
7.3.1 Installing, Upgrading, and Understanding Packages
This section describes how to install and upgrade PEAR packages, and
how to find out more information about them. For
Unix platforms,
including Mac OS X, the instructions are valid for PHP 4.3.0 or later
versions. For Microsoft Windows, PEAR installation and upgrade is
available after PHP 4.3.2.
7.3.1.1 Finding out about packages
At
the time of writing, the PEAR documentation available at http://pear.php.net/manual/en/ was
incomplete. However, you'll find some useful
information there, particularly about the core components and a
handful of the popular optional packages.
To go beyond the limited documentation, the first step is to access
the package browser at http://pear.php.net/packages.php or search
for a known package directly at http://pear.php.net/package-search.php. You
can also access the same information using the PEAR installer, as
described later in this section. This process provides you with
concise information that sums up a package, and often a link to the
project's homepage that may contain more details and
code examples.
To begin to use a package, the best approach is to install it, review
the source code of the package, and read any relevant postings to the
php.pear.general newsgroup which
is accessible at http://news.php.net/. To review the source
code, you can follow two approaches: first, visit the source at
http://cvs.php.net/cvs.php/pear/;
or, second, view it on your system after the install process using
the approach described later in this section. This process can
sometimes be laborious but it's worth remembering
that many of these packages are new, emerging, and supported to
different degrees by their development teams. Reading source code is
definitely worthwhile.
7.3.1.2 Using the PEAR installer
You
need an Internet connection to complete this section.
As we discussed previously, a list of the packages installed with
your PHP installation can be obtained at a shell prompt in a Unix
system (when you're logged in as root) using:
% pear list
On a Microsoft
Windows platform, you do this in a command window with:
C:\> pear.bat list
In the remainder of this section, we only list the Unix commands and
show a Unix shell prompt. To use the command in Microsoft Windows,
replace pear with
pear.bat.
To find out about one of the packages installed on your system, you
can ask for details or visit the package browser at http://pear.php.net/packages.php. For
example, to find out more about the
HTML_Template_IT package type:
% pear info HTML_Template_IT
In response, you'll get a page of information that
describes the package, its current release, licensing requirements,
and its
release state. The release state is one
of Stable, Beta,
Alpha, or Devel(opment).
The majority of packages are Stable, with the
remaining majority in Beta testing. Use
non-stable packages with caution.
If your computer has an Internet connection, you can check whether
your packages can be upgraded to later releases by typing:
% pear list-upgrades
This requests information from the pear.php.net server. In response, the pear
installer will report information such as:
Available Upgrades (stable):
============================
+-------------+---------+--------+
| Package | Version | Size |
| Archive_Tar | 1.0 | 12.4kB |
| Mail | 1.0.2 | 12.1kB |
| Net_SMTP | 1.1.2 | 5.2kB |
| PEAR | 1.0.1 | 75kB |
| XML_Parser | 1.0.1 | 4.9kB |
You can obtain the same information by browsing the packages at the
PEAR
web site http://pear.php.net/.
All information is for stable releases of packages, which can be
safely installed and used. You can choose to upgrade a specific
package or upgrade all out-of-date packages. For example, to upgrade
only the PEAR base class:
% pear upgrade PEAR
The PEAR installer retrieves the package and responds with:
downloading PEAR-1.0.1.tar ...
...done: 395,776 bytes
upgrade ok: PEAR 1.0.1
Sometimes,
the upgrade process can fail but helpful information is provided as
to why. For example, an upgrade of the Net_SMTP
package often fails for PHP 4.3.2:
% pear upgrade Net_SMTP
downloading Net_SMTP-1.1.2.tar ...
...done: 29,184 bytes
requires package `Auth_SASL'
Net_SMTP: dependencies failed
In order to proceed, the Auth_SASL package is
needed first. This can be achieved with:
% pear install Auth_SASL
You can then try again to install the Net_SMTP
package using pear upgrade.
As discussed in the previous section, viewing source code is an
excellent method to understand how a package works. After
you've installed a package, you'll
find it below the directory /usr/local/lib/php/
on most Unix systems, in /usr/local/php/lib/php
under Mac OS X, or in C:\Program
Files\EasyPHP1-7\php\pear\pear on a Microsoft Windows
system if you've followed our PHP installation
instructions in Appendix A to Appendix C. The majority of the core packages are in the
directory itself, while the optional packages are stored in
subdirectories that are named according to the package category. For
example, the IT templates that are discussed in the next section are
found in the HTML subdirectory. Other popular
package categories are listed later in Section 7.3.3.
The PEAR installer
isn't always reliable or well-configured on every
system. If you have problems installing or upgrading packages, you
can download packages from the PEAR web site and put them in the PEAR
directories manually. This is also a useful trick for getting PEAR
packages working without root or administrator user access: download
the packages you need, uncompress them, put them in a directory that
you've created, and then include the package file in
your PHP
script.
7.3.2 Using HTML Templates
Separating code from HTML can be
difficult in PHP. As we discussed in Chapter 1
and have shown so far in this book, one of the best features of PHP
is that scripts can be embedded anywhere in HTML documents. However,
this can lead to maintenance problems: if you want to redesign the
presentation of the web site, you may need to rewrite code or, at the
very least, understand how PHP and HTML are interleaved in the
application. This also makes it difficult to maintain code when it is
interleaved with presentational components.
A good solution for medium- to large-scale web database applications
is to use templates to separate markup and code.
In this section, we illustrate how PEAR Integrated
Templates (IT) can be used in PHP applications through
simple examples, and also show you an example with Extended
Integrated Templates (ITX).
There are many other good templating environments, including a few
others in PEAR itself. Outside of PEAR, the Smarty PHP
template engine
is popular and flexible, and available
from http://www.phpinsider.com/php/code/Smarty.
To use the IT and ITX packages, you need to install the package
HTML_Template_IT
. To do this, you
can follow the general instructions in the previous section or the
detailed instructions for Linux, Mac OS X, and Microsoft Windows
platforms in Appendices A to C.
7.3.2.1 Working with blocks and placeholders
In
our first example, we show you how to develop the basic components
needed in most templated PHP code: an HTML template and its
accompanying PHP script. Our aim in this example is to display a list
of customers in an HTML table environment. The customer data is
stored in a customer table in MySQL that was
created with the following statement:
CREATE TABLE customer (
cust_id int(5) NOT NULL,
surname varchar(50),
firstname varchar(50),
initial char(1),
title_id int(3),
address varchar(50),
city varchar(50),
state varchar(20),
zipcode varchar(10),
country_id int(4),
phone varchar(15),
birth_date char(10),
PRIMARY KEY (cust_id)
) type=MyISAM;
Example 7-2 is the template that acts as a
placeholder to show selected customer information. In our example,
the template is saved in the file
example.7-2.tpl and stored in a
templates directory below our main
htdocs directory that contains the PHP scripts.
Perhaps the most surprising thing about a template is that it is
usually well-formed HTML 4.01. Indeed, when it's
viewed in a Mozilla browser as shown in Figure 7-1,
it has the features of a customer listing but with only one row and
with placeholders in curly braces shown instead of the customer
details. We always use uppercase characters for our placeholders so
that they stand out in the template and in the code, but this
isn't required.
|
Placeholder and block names can consist of alphabetic and numeric
characters, as well as underscores and hyphens. Spaces and other
characters aren't allowed.
For blocks, a single space must precede and follow the keywords
BEGIN and END, and a single
space must follow the block name.
|
|
The other difference between a typical HTML page and a template is
that the template contains comments that include the tags
BEGIN and END. These comment
tags are in pairs that have matching labels that define a
block
.
In this example, there's one block that has the
label CUSTOMER.
Blocks represent units of information that are optional or can
repeat. In Example 7-2, the
CUSTOMER block surrounds a prototype data row that
is output once for each customer in the database. In our PHP script,
we control the presentation by assigning each row of data from the
database to the block, and then parsing and outputting the completed
row as HTML to the browser.
Example 7-2. A template for displaying customer details
<!DOCTYPE HTML PUBLIC
"-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html401/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>Customer Details</title>
<body>
<table>
<tr><th>Name<th>Address<th>City<th>State<th>Zipcode
<!-- BEGIN CUSTOMER -->
<tr><td>{FIRSTNAME} {SURNAME}<td>{ADDRESS}
<td>{CITY}<td>{STATE}<td>{ZIPCODE}
<!-- END CUSTOMER -->
</table>
</body>
</html>
The template, as viewed in a Mozilla browser, is shown in Figure 7-1 (to view it, we renamed the
.tpl file with an .html
extension).
The script that populates the template with the customer data is
shown in Example 7-3. To access the DBMS, no new
functionality is included: the script uses the query process
explained in Chapter 6 to connect, query, and
extract results. What is new is the use of templates: the script
itself doesn't output data using
print but instead assigns data to elements of the
customer template.
Example 7-3. A PHP script that populates the customer template in Example 7-2
<?php
require_once "HTML/Template/IT.php";
include "db.inc";
// Connect to the MySQL server
if (!($connection = @ mysql_connect($hostname, $username, $password)))
die("Cannot connect");
if (!(mysql_select_db($databaseName, $connection)))
showerror( );
// Run the query on the connection
if (!($result = @ mysql_query ("SELECT * FROM customer LIMIT 50",
$connection)))
showerror( );
// Create a new template, and specify that the template files are
// in the subdirectory "templates"
$template = new HTML_Template_IT("./templates");
// Load the customer template file
$template->loadTemplatefile("example.7-2.tpl", true, true);
while ($row = mysql_fetch_array($result))
{
// Work with the customer block
$template->setCurrentBlock("CUSTOMER");
// Assign the row data to the template placeholders
$template->setVariable("FIRSTNAME", $row["firstname"]);
$template->setVariable("SURNAME", $row["surname"]);
$template->setVariable("ADDRESS", $row["address"]);
$template->setVariable("CITY", $row["city"]);
$template->setVariable("STATE", $row["state"]);
$template->setVariable("ZIPCODE", $row["zipcode"]);
// Parse the current block
$template->parseCurrentBlock( );
}
// Output the web page
$template->show( );
?>
The code fragment:
require_once "HTML/Template/IT.php";
loads PEAR's Integrated Template class into the
script. After this, we create a new IT template
$template, and specify that the templates
we're using are found in the
templates subdirectory:
$template = new HTML_Template_IT("./templates");
(The period and forward slash in ./templates means
the templates directory is a subdirectory of the
directory that contains the PHP script.)
After that, we load in our template file from Example 7-2:
$template->loadTemplatefile("example.7-2.tpl", true, true);
The two additional parameters are discussed later in this section.
Having set up our template, we can now use it with the data from our
query. This is a three-step process:
Select the block to work with; in this example,
there's only the CUSTOMER block. Assign data to the placeholders within the block. Parse the block.
This process is repeated each time we want to output a block (which,
in this case, is a row of customer data). By default, if you
don't use a block, it's assumed you
don't want to output it and it
isn't included in the HTML output.
In our script, the repeating three-step process is encapsulated in
the following code fragment:
// Work with the customer block
$template->setCurrentBlock("CUSTOMER");
// Assign the row data to the template placeholders
$template->setVariable("FIRSTNAME", $row["firstname"]);
$template->setVariable("SURNAME", $row["surname"]);
$template->setVariable("ADDRESS", $row["address"]);
$template->setVariable("CITY", $row["city"]);
$template->setVariable("STATE", $row["state"]);
$template->setVariable("ZIPCODE", $row["zipcode"]);
// Parse the current block
$template->parseCurrentBlock( );
The parameter to HTML_Template_IT::setCurrentBlock(
) is the name of the block you want to work with in the
template file. The parameters to
HTML_Template_IT::setVariable( ) are a
placeholder name within the block, and the data to assign to the
placeholder. The method
HTML_Template_IT::parseCurrentBlock( ) processes
the currently selected block.
The script repeats the three-step process until
there's no more data to process from the query.
After that, the entire web page is output by the statement:
$template->show( );
The result of running the script and using the template is shown in
Figure 7-2.
7.3.2.2 Nested blocks
Example 7-4
shows a more complex template example.
This template is designed to display information about wine regions
and, for each region, a list of the wineries that are situated there.
We use two database tables in our example,
winery and region. These
are created with the following statements:
CREATE TABLE winery (
winery_id int(4) NOT NULL,
winery_name varchar(100) NOT NULL,
region_id int(4) NOT NULL,
PRIMARY KEY (winery_id),
);
CREATE TABLE region (
region_id int(4) NOT NULL,
region_name varchar(100) NOT NULL,
PRIMARY KEY (region_id),
);
There's a one-to-many relationship between the
tables: each winery row has a
region_id attribute that stores the identifier of
a row in the region table.
The blocks in the template in Example 7-4 are
nested. The REGION block spans most of the HTML
listing and contains within it a WINERY block. The
nesting matches the table relationship: there can be many region
blocks, and many winery blocks within each region.
Example 7-4. A template with nested blocks for showing regions and wineries
<!DOCTYPE HTML PUBLIC
"-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html401/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>Regions and Wineries</title>
<body>
<ul>
<!-- BEGIN REGION -->
<li>Region: {REGIONNAME}
<ul>
<!-- BEGIN WINERY -->
<li>{WINERYNAME}.
<!-- END WINERY -->
</ul>
<!-- END REGION -->
</ul>
</body>
</html>
Sample output from Example 7-4 is shown in Figure 7-3.
Example 7-5 shows the PHP script that works with the
template. The logic of the script flows similarly to the template.
The three-step process of selecting a block, assigning data to
placeholders, and parsing is repeated for each region in the
database. Nested inside that looping process, the same three steps
occur for the wineries within each region.
One simple rule needs to be followed when a nested template is used:
the innermost block must be parsed first, followed by the second
innermost block, and so on until the outermost block has been parsed.
In our example, this means that each repeating
WINERY block must be parsed before the
REGION block it belongs in. After all blocks that
need to be populated have been parsed, the web page is output using
HTML_Template_IT::show( ).
Example 7-5. The PHP script that works with the template in Example 7-4
<?php
require_once "HTML/Template/IT.php";
require "db.inc";
if (!($connection = @ mysql_connect($hostname, $username, $password)))
die("Cannot connect");
if (!(mysql_select_db($databaseName, $connection)))
showerror( );
if (!($regionresult = @ mysql_query ("SELECT * FROM region LIMIT 10",
$connection)))
showerror( );
$template = new HTML_Template_IT("./templates");
$template->loadTemplatefile("example.7-4.tpl", true, true);
while ($regionrow = mysql_fetch_array($regionresult))
{
$template->setCurrentBlock("REGION");
$template->setVariable("REGIONNAME", $regionrow["region_name"]);
if (!($wineryresult =
@ mysql_query ("SELECT * FROM winery
WHERE region_id = {$regionrow["region_id"]}",
$connection)))
showerror( );
while ($wineryrow = mysql_fetch_array($wineryresult))
{
$template->setCurrentBlock("WINERY");
$template->setVariable("WINERYNAME", $wineryrow["winery_name"]);
$template->parseCurrentBlock( );
}
$template->setCurrentBlock("REGION");
$template->parseCurrentBlock( );
}
$template->show( );
?>
|
Make sure you remember to use
HTML_Template_IT::setCurrentBlock( ) to select
the block before you call either
HTML_Template_IT::setVariable( ) or
HTML_Template_IT::parseCurrentBlock( ). Failing
to do so can cause unpredictable results and difficult-to-detect
errors.
Also, be careful that you don't have two blocks with
the same name. Unpredictable results are likely.
|
|
7.3.2.3 Preserving and removing blocks
In our previous example, we used
the following fragment to load a template file:
$template->loadTemplatefile("example.7-4.tpl", true, true);
The second and third parameters specify sensible default behavior for
working with unused placeholders and blocks. The second parameter
specifies that if a block isn't used in a template,
it shouldn't be output. This is useful if you have
an optional block that that's sometimes used, as we
discuss in the next section. The third parameter behaves similarly
for placeholders: when set to true, placeholders
that haven't had data assigned to them are removed
during parsing.
If you have chosen to remove empty blocks but need to preserve a
block at runtime, this is possible using the
HTML_Template_IT::touchBlock( ) method. Touching
means a block is marked as needing to be output, even if nothing has
been assigned to its placeholders. For example, to preserve a
DETAILS block you can use:
$template->touchBlock("DETAILS");
This is a useful feature in two situations: first, when you want to
output a block but don't want to assign data to its
placeholders; or, second, if a block has no placeholders and you want
it to be shown. We show you an example in the next section.
7.3.2.4 More on nesting and optional blocks
Blocks aren't always
nested: if data isn't related, it
shouldn't be nested. For example, if we wanted to
output information about the ten most popular wineries and the ten
best customers, we might use the following template:
<!DOCTYPE HTML PUBLIC
"-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html401/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>Details</title>
<body>
<h1>Our best customers</h1>
<!-- BEGIN CUSTOMER -->
Name: {FIRSTNAME SURNAME}
<!-- END CUSTOMER -->
<h1>Our most popular wineries</h1>
<!-- BEGIN WINERY -->
Name: {WINERYNAME}
<!-- END WINERY -->
</body>
</html>
In this structure, we can choose to repeat the
CUSTOMER block zero or more times, and to
independently repeat the WINERY block zero or more
times. There is no relationship between the two blocks, and it
doesn't matter whether you work with the customers
or wineries first. Unrelated, unnested blocks can be assigned and
parsed in any order. However, regardless of how you process and
assign the data, all CUSTOMER blocks will always
appear before all WINERY blocks because
that's how the template is structured.
In the previous example, if you don't assign any
data to the CUSTOMER block, the heading
Our best customers will still be output because
it isn't part of a block that you can control in
your code. Moving the heading inside the CUSTOMER
block doesn't solve the problem because the heading
would then be repeated for each customer. One solution is to add
another unnested block to the template so that the heading is
optional:
<!DOCTYPE HTML PUBLIC
"-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html401/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>Details</title>
<body>
<!-- BEGIN CUSTOMERHEADING -->
<h1>Our best customers</h1>
<!-- END CUSTOMERHEADING -->
<!-- BEGIN CUSTOMER -->
Name: {FIRSTNAME SURNAME}
<!-- END CUSTOMER -->
<h1>Our most popular wineries</h1>
<!-- BEGIN WINERY -->
Name: {WINERYNAME}
<!-- END WINERY -->
</body>
</html>
You can then use program logic to choose whether to output a
CUSTOMERHEADING or not, depending on whether there
are any CUSTOMER blocks being used. Note, however,
that the CUSTOMERHEADING block
doesn't contain any placeholders, and so with the
default behavior you'll need to call
$template->touchBlock("CUSTOMERHEADING")
so that it's displayed in the output.
Our previous example can be improved. To avoid having to use program
logic and the HTML_Template_IT::touchBlock( )
method, you can restructure the template so that
it's nested:
<!DOCTYPE HTML PUBLIC
"-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html401/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>Details</title>
<body>
<!-- BEGIN CUSTOMERHEADING -->
<h1>Our best customers</h1>
<!-- BEGIN CUSTOMER -->
Name: {FIRSTNAME SURNAME}
<!-- END CUSTOMER -->
<!-- END CUSTOMERHEADING -->
<h1>Our most popular wineries</h1>
<!-- BEGIN WINERY -->
Name: {WINERYNAME}
<!-- END WINERY -->
</body>
</html>
This works better because the CUSTOMERHEADING
block contains the CUSTOMER block. With nesting,
if the CUSTOMER block is used,
there's no need to use
HTML_Template_IT::touchBlock( ) on
CUSTOMERHEADING. Similarly, if nothing is assigned
to a CUSTOMER block,
CUSTOMERHEADING hasn't been
touched and won't be output. This is another example
of our basic relationship rule: if data is related, use nesting; if
it isn't, don't.
So far, we've dealt with related and unrelated
blocks that appear in a fixed order. Sometimes, however, you may want
to display data in an arbitrary order that you want to be flexible at
runtime. To do this, you can create a block that contains several
nested blocks at the same level. For example, if we wanted to output
several red, green, or blue messages in any order on a page, we could
use the following template:
<!DOCTYPE HTML PUBLIC
"-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html401/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>Color lines</title>
<body>
<!-- BEGIN COLORLINES -->
<!-- BEGIN RED -->
<font color="red">{MESSAGE}</font>
<!-- END RED -->
<!-- BEGIN GREEN -->
<font color="green">{MESSAGE}</font>
<!-- END GREEN -->
<!-- BEGIN BLUE -->
<font color="blue">{MESSAGE}</font>
<!-- END BLUE -->
<!-- END COLORLINES -->
</body>
</html>
So, to output a blue line, you select the BLUE
block, assign the data to MESSAGE placeholder,
parse the BLUE block, and then select and parse
the COLORLINES block. To output another color, you
repeat the same process for that different colored block. Using this
technique, the COLORLINES block repeats, but with
each repeat you can choose a different inner block. In Chapter 10 and Chapter 16, we
explain a template for displaying form widgets that uses this
technique.
7.3.2.5 Extended Integrated Templates (ITX)
Optional blocks allow most of the
flexibility you'll need to develop template
applications. However, sometimes you may need to dynamically create a
template at runtime. Usually, this is done by using a main template
file, and then adding template fragments in the PHP script. A popular
use of this technique is to store a standard header and footer for an
application in a main template file, and then to dynamically add the
page body at runtime. This is what we do in our sample application in
Chapter 16 through Chapter 20.
The Extended Integrated Template (ITX) class
extends IT templates, adding the functionality to dynamically
construct templates at runtime. The following is an example main
template file stored in the file
about_today.tpl:
<!DOCTYPE HTML PUBLIC
"-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html401/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>About Today</title>
</head>
<body>
{MESSAGE}
</body>
</html>
The placeholder MESSAGE is the position at which
our choice of template fragment is inserted. In this example, our
script will insert a different template depending on the day of the
week. If today is a weekday, the following template fragment stored
in the file weekday.tpl is inserted:
Oh no. It's {DAY}, which is a weekday.
If today is on a weekend, this fragment stored in the file
weekend.tpl is inserted:
Good news. It's {DAY}, which is on the weekend.
All of the template files are stored in the same directory.
The script that works with the templates is as follows:
<?php
require_once "HTML/Template/ITX.php";
$template = new HTML_Template_ITX('.');
$template->loadTemplatefile("about_today.tpl", true, true);
$daynumber = date("w");
// Is it a weekday?
if ($daynumber != 0 && $daynumber != 6)
// Include the weekday template fragment
$template->addBlockFile("MESSAGE", "NEWMESSAGE", "weekday.tpl");
else
// Include the weekend template fragment
$template->addBlockFile("MESSAGE", "NEWMESSAGE", "weekend.tpl");
$template->setCurrentBlock("NEWMESSAGE");
$template->setVariable("DAY", date("l"));
$template->parseCurrentBlock( );
$template->show( );
?>
Rather than work with IT.php library, this
script uses the ITX.php file. The ITX templates
provide several new methods, the most useful of which is
HTML_Template_ITX::addBlockFile( ). This method
takes three parameters: the placeholder to replace, the name of the
block to replace it with, and the template fragment file that forms
the body of the block.
In our example, depending on the day of week determined with the
date( ) function, a choice is made as to whether
to replace the MESSAGE placeholder with the
fragment weekday.tpl or the fragment
weekend.tpl; the date( )
function is discussed in Chapter 3. After the
replacement, the script proceeds in the same way as previous examples
by selecting our new block, assigning values to placeholders,
parsing, and outputting the results. The template fragments do not
include the name of the new block, this is supplied as the second
parameter to HTML_Template_ITX::addBlockFile( ).
As we've shown you, the
HTML_Template_ITX::addBlockFile( ) inserts a
file into a template at a location defined by a placeholder and then
redefines the replaced section as a block.
Blocks can also be replaced at runtime by other blocks
using the HTML_Template_ITX::replaceBlockFile( )
method that's explained in the next section.
7.3.2.6 Essential IT and ITX functions
- v oid HTML_Template_IT::HTML_Template_IT ([string root])
This is the constructor for
the HTML_Template_IT class. It is called to
create a new template and takes an optional
root directory as a parameter. If the
root directory is provided, the template
file that is loaded with
HTML_Template_IT::loadTemplateFile( ) is assumed
to be based in this directory. (The return type of
void means that the method does not return a
value.)
- Boolean HTML_Template_ITX::addBlock(string placeholder, string block, string template)
Replaces a placeholder in the current
template with a block that is stored in
the template file. The
template file should not contain the block
BEGIN and END tags: these are
created by the method and associated with the block name.
- array HTML_Template_ITX::blockExists(string block)
Returns true if the
block exists and false
otherwise.
- array HTML_Template_ITX::BlockvariableExists(string placeholder)
Returns true if the
placeholder exists and
false otherwise.
- string HTML_Template_IT::get([string block])
Returns a block after all placeholders
have been replaced. If a parameter isn't supplied,
the entire template is returned. In most applications, the template
is output using HTML_Template_IT::show( ) rather
than returned with this method. However, this method can be used, for
example, to produce template-based emails (as used in Chapter 19) or textual reports.
- array HTML_Template_ITX::getBlockList( )
Returns a list of template block names in a one-dimensional array.
- array HTML_Template_ITX::getBlockVariables(string block)
Returns a list of block placeholder names
in a one-dimensional array.
- Boolean HTML_Template_IT::loadTemplateFile(string file [, Boolean removeVars [, Boolean removeBlocks]])
Reads a template file from disk. The
directory is a concatenation of any root directory supplied to the
constructor plus the file provided. If
removeVars is true,
unassigned placeholders are deleted from the output. If
removeBlocks is set to
true, unused blocks are removed except if the
block has been accessed with HTML_Template_IT::touchBlock(
). Both optional parameters are set to
true by default. Returns true
on success and false on failure.
- void HTML_Template_IT::parse ([string block])
Process a block by replacing all
placeholders with their assigned values. If no parameter is supplied,
the entire template is parsed. Child blocks should be parsed before
their parents, that is, blocks should be processed from most- to
least-nested.
- void HTML_Template_IT::parseCurrentBlock ( )
Process the current block selected with
HTML_Template_IT::setCurrentBlock( ) by
replacing all placeholders with their assigned values. Child blocks
should be parsed before their parents, that is, blocks should be
processed from most- to least-nested.
- string HTML_Template_ITX::placeholderExists(string placeholder [, string block])
Returns the name of the first block that contains the
placeholder in the template or in an
optional block. If no block contains the
placeholder, the empty string is returned.
- Boolean HTML_Template_ITX::replaceBlock(string block, string file [, Boolean preserve])
Replaces a block in the current template
with a block of the same name that is stored in a
file. The file
should not contain the block BEGIN and
END tags: these are created by the method. The
existing assignments to placeholders can be preserved if the optional
parameter preserve is set to
true; by default it is false.
Returns true on success and
false on failure.
- Boolean HTML_Template_IT::setCurrentBlock ([string block])
Makes a block the currently selected
block. If no parameter is provided, no block is set but instead any
placeholders that are outside of blocks are made current; all of our
examples use only placeholders inside blocks, but several examples
without blocks are in later chapters. Returns true
on success and false on failure.
A call to this method should be made prior to assigning variables to
placeholders with HTML_IT_Template::setVariable(
).
- void HTML_Template_IT::setVariable(string placeholder, string variable)
Assign a variable to the
placeholder in the currently selected
block. Blocks are selected with
HTML_Template_IT::setCurrentBlock( ).
The function has an alternate, array parameter that
isn't useful for the majority of applications, and
we ignore it here.
- void HTML_Template_IT::show([string block])
Outputs a block after all replacements
have been made. Without the parameter, the complete template is
output. In our examples, the parameter is not provided and this is
the final step in working with the template.
- Boolean HTML_Template_IT::touchBlock(string block)
Preserves an empty block in the output
when no data has been assigned to its placeholders. This works even
if the third parameter to
HTML_Template_IT::loadTemplateFile( ) is set to
true. Returns true on success
and false on failure.
7.3.3 Optional Packages
Of the 154 PEAR packages at the time
of writing, this section lists the 40 most popular as determined by
download frequency at http://pear.php.net/package-stats.php. As
discussed at the beginning of this section, the complete list is
available by requesting the package installer to provide the
information or by browsing packages in the repository. Selected
packages are used in other sections of the book, and
we've noted this next to those packages.
7.3.3.1 Authentication
There are six packages available, and two
are popular.
Auth is a session-based authentication class
that supports all PEAR DB DBMSs, as well as authentication for text
files, LDAP servers, POP3 servers, IMAP servers, vpopmail accounts,
RADIUS, and SOAP. Our authentication in Chapter 11 supports similar features. Auth_HTTP provides methods for HTTP
authentication. We discuss HTTP authentication in Chapter 11.
7.3.3.2 Benchmarking
There's only one
package, and it's in the top 40.
7.3.3.3 Caching
Two
packages are available, and one is popular.
Cache stores the results of previous function
calls, script executions, and other activities so that they can be
used in the future. Caching often speeds-up program execution if
results or scripts are re-used frequently, and your web site is under
high load.
7.3.3.4 Console
Five
packages are available. The popular one is the core component
Console_Getopt for retrieving command-line
arguments from non-web scripts.
7.3.3.5 Database
There are fourteen packages, of which four
are popular.
DB is a core component described in its own
section in this chapter. DB_DataObject is an SQL builder and object
interface to database tables. DB_Pager retrieves data in chunks after a query
using PEAR DB. The aim is to allow you to retrieve and display data
for subsequent display in pages. MDB is a merging of PEAR DB and Metabase;
Metabase is an alternative to PEAR DB. The MDB package provides a
superset of the functionality of PEAR DB.
7.3.3.6 Date
There is
one package that's popular.
7.3.3.7 Filesystem
There are six packages, of which two
are popular.
Archive_Tar supports creating, listing,
extracting, and adding to tar (Unix archive) files, a common format
of zip-like archives on Unix-style systems. This is a core component
of PEAR that's used by the installer. File provides methods to read and write files,
and to deal with paths. It also provides an interface for working
with comma-separated value (CSV) files.
7.3.3.8 HTML
There are
fifteen packages, including five popular ones.
HTML_QuickForm for creating, processing, and
validating HTML form environments. We develop our own framework for
creating template-based forms in Chapter 16. HTML_Table for developing, manipulating, and
reusing HTML <table> environments. HTML_Template_IT is a templating environment
described in its own section in this chapter. It includes the
extended template package ITX. HTML_TreeMenu creates attractive menus for
display using JavaScript at the client. We discuss developing simple
menus using JavaScript in Chapter 9. Pager is a class for viewing data in pages with
previous and next buttons. We develop our own approach to this in
Chapter 17.
7.3.3.9 HTTP
There are six packages and three are
popular.
HTTP is a core component discussed at the
beginning of this chapter. HTTP_Request is designed for easy formatting of
HTTP requests, including all methods, basic authentication, proxy
authentication, and redirection. We discuss HTTP in Appendix D, HTTP authentication in Chapter 11, and redirection in Chapter 6. HTTP_Upload allows easy management of files
uploaded from browsers to web servers using form environments.
7.3.3.10 Internationalization
There's one
popular package for internationalization.
I18N is designed to help you localize
applications by determining browser language, currency, date and
time, and numbers.
7.3.3.11 Logging
There
is one package, and it's popular.
7.3.3.12 Mail
There are
six packages, and two are popular.
7.3.3.13 Networking
There are twenty-nine packages, of
which four are popular: we use the Net_DNS
package (which isn't discussed here) in Chapter 9.
Net_POP3 is a class for accessing POP3 mail
servers. Net_Socket is a core component for working with
network sockets and is described at the beginning of this chapter. Net_URL provides easy parsing of URLs, allowing
components to be extracted without difficult string processing Net_UserAgent_Detect determines the web browser,
version, and platform from the HTTP headers.
7.3.3.14 PEAR
There are three packages and two are popular.
PEAR is a set of core classes described at the
beginning of this chapter. PEAR_Frontend_Web is a web interface to the PEAR
package manager. We describe the command-line version in this
chapter, but it's likely that this package will
become popular for configuration on all platforms when it leaves the
beta-testing phase.
7.3.3.15 PHP
There are nine packages and three are popular.
apd is a profiler and debugger that helps in
optimizing code. bcompiler allows you to protect your code by
compiling it rather than distributing PHP source. PHPDoc generates documentation from source code.
7.3.3.16 XML
There are eleven packages, of which three
are popular.
XML_Parser is designed to parse XML. XML_RPC is a core package that implements
XML-RPC. XML_Tree represents XML data as a tree structure.
7.3.3.17 Web services
There are three packages, of which one
is popular.
|
No comments:
Post a Comment