Saturday, November 21, 2009

7.3 Packages











 < Day Day Up > 









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).









Figure 7-1. The customer template from Example 7-2 viewed in a Mozilla browser.







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:





  1. Select the block to work with; in this example,

    there's only the CUSTOMER block.

  2. Assign data to the placeholders within the block.

  3. 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.









Figure 7-2. The output of running Example 7-3 shown in a Mozilla web browser















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.









Figure 7-3. The output of running Example 7-4 shown in a Mozilla web browser







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.





  • Benchmark is a framework for benchmarking the

    performance of PHP functions and scripts. Its similar in style to the

    popular GNU C programming tool gprof.











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.





  • Date is classes for manipulating and working

    with dates and time zones without timestamps, and without year range

    restrictions. We use Date in Chapter 9.











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.





  • Log is a logging system that can log data to

    many different targets including PEAR DB, files, and email.











7.3.3.12 Mail






There are

six packages, and two are popular.





  • Mail is described in the core components section

    at the beginning of this chapter. It's used in Chapter 19.

  • Mail_Mime provides classes to encode and decode

    Mime-encoded attachments.











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.





  • SOAP is a client and server package for

    implementing Simple Object Access Protocol (SOAP) protocols and

    services. SOAP is an emerging standard, and a good introduction to

    SOAP is available at http://www.w3.org/TR/SOAP/.





























     < Day Day Up > 



    No comments: