The Smarty Template Engine


Smarty is an incredibly powerful and complex templating system available for PHP developers. It is perhaps the best common-ground solution I've ever seen and balances the separation of presentation and application logic without sacrificing usability. Although it functions on an entire template-scripting language of its own, the use of this functionality is not a requirement.

When I was first introduced to the Smarty package, I was immediately turned off to it when I saw the first complex example. This template example was truly a program in its own right, complete with control structures, internal function calls, and more. My thoughts kept coming back to the reason for template engines in the first placeto free the Web designer from having to mess around with PHP code! It seemed to me that although Smarty may have separated PHP from HTML, the solution required Web designers to learn an entirely different Smarty "scripting" language. All in all, I was very disappointed and quickly removed Smarty from my system.

Sometime later I was doing research for a column I was in the process of writing about the separation of application and business logic, and I happened to run across Smarty again. For the sake of completeness, I decided to include a little about Smarty in my articlewhich, of course, forced me to learn a bit about using it. As I got the Smarty documentation out and began playing with it, I started changing my opinion of the scripting engine. Although it did have some very complex features for a template engine, it also supported the plain old variable substitutions that you were introduced to in my discussion of QuickTemplate. The engine also supported the bare set of control structures, such as conditional statements and loops, allowing for complete separation of presentation and application logic. With all this functionality, you would expect Smarty to be slow; however, perhaps the thing that blew me away the most was that it was fastfaster than any PHP template engine I had ever seen! I have since changed my opinion of the Smarty templating system and now consider myself a die-hard fan.

How does the Smarty template engine do it? Smarty works on what (to my knowledge at least) is a unique concept to any PHP templating systemit compiles the templates into native PHP code. Hence, the first time a template page is loaded, Smarty compiles it into a PHP script first, which is saved, and then executes the template code. This makes the template almost as fast as PHP itself and incredibly scalable. To top it off, the engine was designed in such a way that the control structures it provides were converted directly into PHP code, giving them all the flexibility and power of the actual PHP equivalents without the inherent complexity.

Installing Smarty

To use Smarty, you must follow a few steps to properly install it. First, you have to download the latest version of Smarty, which can be found at http://smarty.php.net/.

After you have downloaded and extracted Smarty, a number of directories and files are created. Of all of this, only a few things are a part of the Smarty engine itselfthree classes (Smarty.class.php, Smarty_Compile.class.php, and Config_File.class.php) and the plugins directory. All three files must be copied into the include path of your PHP installation. If you do not have the capability to copy these files into a directory that is a part of the include path (for example, if you do not have access to the php.ini file or .htaccess files) you have two options:

Option 1: You can copy these files into a directory and then set the include_path at runtime by using the ini_set() and ini_get() PHP functions:

 <?php ini_set("include_path",               ini_get("include_path").";/path/to/smarty/files/"); ?> 

Option 2: You can copy these files into a directory and define the SMARTY_DIR constant to the appropriate path prior to using the Smarty engine:

 <?php define('SMARTY_DIR', '/path/to/smarty/files/'); ?> 

The next step in the installation process is to create at least three (perhaps four) directories for Smarty to use. When you create these directories, it is important to be mindful of possible security consequences and behave accordingly. Following is a listing of the directories that need to be created for use with Smarty:

NOTE

These directory names can be changed; however, if you decide to use different directory names, this change must be noted when you configure Smarty's class variables (discussed later in the chapter).


templates

This directory should reside outside of the Web tree and is used to store the templates used by Smarty.

templates_c

This directory must reside inside of the Web tree and is used to store the compiled templates (PHP scripts) that are actually executed to display the Web page. This directory must be writeable by PHP and the Web server.

configs

This directory should reside outside of the Web tree and is used to store the configuration files used by templates created in Smarty (discussed later).

cache

This directory should reside outside of the Web tree and is used to store cached templates (discussed later). This directory must be writeable by PHP/the Web server.


Each of these directories must have the appropriate permissions to be accessed by PHP (configs and templates can be read-only; the remainder require write permissions). For those not familiar with the terminology, the phrase "outside of the Web tree" means a directory that cannot be accessed through the Web server via a browser.

After you have copied the appropriate files and created the necessary directories, the next step is to configure the Smarty engine. You do this by opening the Smarty.class.php file and modifying the appropriate member variables (the ones at the top of the class). Although the class itself briefly describes each variable, following is a reference of some of the important configuration variables available to the Smarty engine:

$template_dir

The path where Smarty will search for the templates it will use; it points to the directory with the same name you should have just created (Default: templates).

$compile_dir

The path where Smarty will store compiled versions of templates (Default: templates_c).

$plugins_dir

The path(s) where Smarty will look for plug-ins for the engine. This value is a PHP array of strings, each a path where plug-ins can be found (Default: array('plugins')).

$compile_check

Determines whether Smarty will check to see if a template needs to be recompiled. If this value is not set to true, Smarty will never update/recompile modified templates (Default: TRue).


After you have completed adjusting the configuration variables, you should test Smarty to see if things are working properly. To do this, you'll need to create the two files found in Listings 7.7 and 7.8, named test_template.tpl and test_smarty.php, respectively:

Listing 7.7. Test Template for Smarty
 The value below should be 'PHP Unleashed':<BR> {$testvar}<BR><BR> The below should be a table with the numbers 1 through 10 in it: <TABLE CELLPADDING=3 BORDER=1> <TR> {section name=testsection loop=$testdata} <TD>{$testdata[testsection]}</TD> {/section} </TR> </TABLE> <BR> There are {$testvar|count_characters} characters in the phrase '{$testvar}'. 

Listing 7.8. Test Script for Smarty
 <?php     require("Smarty.class.php");     $smarty = new Smarty;     $smarty->assign("testvar", 'PHP Unleashed');     $smarty->assign("testdata", range(1,10));     $smarty->display("test_template.tpl"); ?> 

To test your installation of Smarty, place test_template.tpl into your templates (or whatever you named it) directory and place test_smarty.php in your Web tree. Then open your browser and attempt to load test_smarty.php from the Web server. You should see the following results (Figure 7.1).

Figure 7.1. Dialog box showing the results of test_smarty.php.


If the test script causes an error or otherwise fails to function properly, the first thing you should do is double-check to ensure that you have created the necessary directories properly and with the proper permissions. Also, be sure to double-check within your Smarty.class.php file to make sure the appropriate configuration variables relating to these directories have been properly set. If all else fails, check the Smarty documentation for more information. On the other hand, if the test script successfully executedcongratulations, Smarty is now installed on your server and you are ready to move on to how it works.

Basic Smarty: Variables and Modifiers

Now that you have successfully installed Smarty on your server, let's look at how to use it! To do this, we'll discuss how to accomplish simple variable replacement, as we did with my QuickTemplate script. In Smarty, as you may have noticed from the test template found in Listing 7.7, variables take the form {$variable_name} by default. Note that this is the default way to represent variables in Smarty. The braces { } used are configurable via the $left_delimiter and $right_delimiter configuration variables and are subject to change. In any case, contained within these delimiters for variables must be the $ character followed by a variable name. The rules governing what characters may constitute a variable name in Smarty are the same as those rules imposed by PHP. Like PHP, Smarty variables are also case sensitive. Following is an example of a very simple template:

 {* A very simple template *} Hello, Thank you for buying PHP Unleashed {$name}. 

NOTE

Like PHP, Smarty templates can have comments inside them. Comments are started with { * (replace the bracket with your delimiter) and ended with *} . Like comments in PHP, they are ignored and never displayed.


Here we have defined a single variable {$name}. To use this template, it must be saved in the templates directory. Although it is not a requirement, it is standard practice to save this file with the .tpl extension, signifying it as a template file. For the purposes of this example, I will assume the file has been saved as simple.tpl.

After the template has been created and saved, it's time to write the PHP script to use it. The first step when creating any PHP script that uses Smarty is to include and create an instance of the Smarty class by starting your scripts with the following:

 <?php  require('Smarty.class.php'); $smarty = new Smarty(); ?> 

From this point forward, you will work with the Smarty engine through the created instance of the Smarty class with the instance variable $smarty.

Every time you use Smarty, beyond including and creating an instance of the class, you must take a few steps for your template page to be processed. The first step is that all variables used within the template must be assigned in the Smarty engine. To do this, Smarty provides the assign() member function. This function takes a maximum of two parameters, and depending on how the function is called, two different actions are taken.

The first method of calling the assign() function is by passing a string as the first parameter and a value as the second. When called in this fashion, Smarty will assign the variable represented by the first parameter the value represented by the second. In our case, to assign a value to the Smarty variable {$name}, you would use the following:

 <?php $smarty->assign('name', 'John Coggeshall'); ?> 

The second method of calling the assign() function is useful when assigning big groups of data. This method involves only passing an associative array to the function. This array's keys represent the variable names, whereas those keys' values represent the value of those variables. For instance, if you had the variables {$foo} and {$bar} in a template, you could assign values to both template variables by calling only the assign() function once and passing an associative array:

 <?php $smarty->assign(array('foo' => 10, 'bar' => 'hello, world!')); ?> 

In this case, we have assigned the template variable {$foo} the integer value 10 and the variable {$bar} a string value of 'hello, world!'.

Although in the preceding case, we used an array to assign to individual values {$foo} and {$bar} in the Smarty engine, entire arrays can also be assigned as values. This is done in the same fashion that any other variable would be assigned, such as the following, where the variable {$myarray} is assigned an array of numbers 5 through 10:

 <?php $smarty->assign('myarray', array(5,6,7,8,9,10));  ?> 

Although arrays are worked with identically from the PHP side, accessing their values from a template is handled differently than with scalar values. When dealing with integer-based arrays such as the preceding one, using them inside a template is done in the same fashion as it would from PHPby appending the appropriate index value inside of brackets. Hence, the string {$myarray[2]} references the same value as $myarray[2] references in PHP (assuming that both instances of $myarray were equivalent arrays). However, when you're working with associative arrays, arrays function in an entirely different manner when used inside Smarty. Instead of specifying the appropriate index within brackets (which I just explained), the array variable is appended with a period followed by the name of the key. This process is shown in Listing 7.9:

Listing 7.9. Accessing Integer-Based Arrays from Smarty
 <HTML><HEAD><TITLE>{$title}</TITLE></HEAD> <BODY> The third element in the $myarray array is: {$myarray[2]}<BR> The element whose key is 'mykey' in the array $anotherarray is: {$anotherarray.mykey}<BR> </BODY> </HTML> 

As you can see, in PHP the value of the mykey key in an associative array would normally be accessed using $anotherarray['mykey']. In Smarty, this key is accessed using {$anotherarray.mykey}.

Now that you understand how to assign and work with template variables in Smarty, let's take a look at what separates Smarty variables from their PHP counterparts. Specifically, let's introduce the concept of variable modifiers.

Variable modifiers, as the name implies, are used to modify the contents of a variable to accomplish a particular goal. Using modifiers in Smarty is done from within the template file itself by following a variable name with a pipe (|) symbol and the name of the modifier. By default, Smarty comes with 19 modifiers; however, more can be added as plug-ins. For example, one modifier provided as part of the Smarty package is called the upper modifier, which capitalizes all the letters in a string. Let's apply this to the earlier example to capitalize everything in the {$name} variable:

 Hello, Thank you for buying PHP Unleashed {$name|upper}. 

In most cases, you will probably want to change the behavior of a modifier according to your needs, and to do this you will need to pass parameters to the modifier. Although not all modifiers (such as the upper modifier) allow parameters, those that do are used by appending a colon (:) character following the modifier name between each parameter. This is illustrated by the wordwrap modifier, shown in Listing 7.10, which will wrap a long string to a maximum column width:

Listing 7.10. Using the Wordwrap Variable Modifier
 <HTML><HEAD><TITLE>{$title}</TITLE></HEAD> <BODY> The following is wrapped to 30 characters:<BR><BR> {$excerpt|wordwrap:30:"<br>\n"} </BODY> </HTML> 

As you can see from Listing 7.10, along with specifying the wordwrap modifier, two parameters have been provided. The first of these parameters is the number of characters used to wrap the given text (in this case, 30 characters). The second parameter is the string to insert at every wrapping interval. Because this text is going to be displayed in a Web browser, you'll need to specify an HTML line-break tag as well as the standard newline for each split, as shown. The actual data that is being wrapped using this modifier is completely irrelevant to our discussion because all the variable manipulation has been done using template variable modifiers.

For cases where multiple modifiers are desired for a single variable, this can be done by placing another pipe after the current modifiers' parameters, as shown in Listing 7.11, which specifies a default parameter for both the {$excerpt} and {$title} template variables in case either is not provided:

Listing 7.11. Using Multiple Modifiers on One Variable
 <HTML><HEAD><TITLE>{$title|default:"No title provided"}</TITLE></HEAD> <BODY> The following is wrapped to 30 characters:<BR><BR> {$excerpt|wordwrap:30:"<br>\n"|default:"There wasn't any data!"} </BODY> </HTML> 

A complete listing of all the variable modifiers and their use can be found online at http://smarty.php.net/ in the Smarty documentation.

Now that you know how variables and variable modifiers work in Smarty, let's take a look at the one reserved variablethe {$smarty} variable.

NOTE

Don't mistake {$smarty} the template variable for $smarty the variable name associated with our instance of the Smarty engine. They are separate variables.


When you're using Smarty, a number of predefined variables are available for use within your templates. All these variables exist as keys of the {$smarty} variable. Through the use of these variables, templates have access to HTTP-request data, such as variables provided using the GET or POST methods, as well as access to a number of internal Smarty, server, and environment variables. Following is a list of information available that is relevant to us so far through the {$smarty} template variable:

{$smarty.get}

An array of variables submitted using the GET method (same as the superglobal $_GET).

{$smarty.post}

An array of variables submitted using the POST method (same as the superglobal $_POST).

{$smarty.cookie}

An array of variables received from HTTP cookies (same as the superglobal $_COOKIE).

{$smarty.server}

An array of server-related variables (same as the superglobal $_SERVER).

{$smarty.env}

An array of environment variables (same as the superglobal $_ENV).

{$smarty.session}

An array of registered PHP session variables (same as the superglobal $_SESSION).

{$smarty.request}

An array of all the variables from $_GET, $_POST, $_COOKIE, $_SERVER, and $_ENV (same as the superglobal $_REQUEST).

{$smarty.now}

The current time (in seconds from January 1, 1970). Use with the date_format variable modifier to show the current time, day, and so on.

{$smarty.template}

The name of the current template being accessed.


NOTE

The preceding list is incomplete. A few variables are not listed because their associated subject matter has not been discussed. When the time is appropriate in the chapter, they will be introduced.


Configuration Files and Functions

Now that we have covered both variables and variable modifiers in Smarty, let's take a look at some of the other capabilities. To start, let's take a look at functions in Smarty and their use in practical template-based scripts.

By default, Smarty provides approximately 12 functions that can be used in your templates. These functions provide a means for templates to use logic and other control structures, such as conditionals (if statements) and other useful features. In Smarty, functions are similar to variable modifiers in the sense that they both have predefined parameters; however, unlike modifiers, functions often manipulate blocks of HTML code (such as using a loop to create rows in a table).

Functions are defined in Smarty by encapsulating them in the same delimiters as variables; however, instead of using a colon to specify parameters, whitespace is used. Furthermore, if a function is designed to work on a block of code, the end of the block must always be defined by specifying the delimited function name with a forward slash (/) and no parameters. To start, let's take a look at the simplest of Smarty functions. These functions are designed to make the life of the Web designer easier by providing different functions to assist in developing HTML templates. The first function I'll discuss is the {literal} function.

The {literal} function is used by Smarty to denote a segment of your HTML document that should be completely ignored but still displayed. This is an important feature when working with client-side languages such as JavaScript, which may confuse Smarty during parsing. This function takes no parameters; it simply wraps whatever you would like to be ignored by Smarty in the following fashion (Listing 7.12):

Listing 7.12. Using the {literal} Smarty Function
 {literal}     <script language="JavaScript">         if(foo) {             window.status = 'Foo is true!';         }     </script> {/literal} 

NOTE

On a similar note, to properly display your delimiter character(s) without breaking your templates, Smarty provides you with two functions: {ldelim} and {rdelim}. These two functions will display your left and right delimiter strings, respectively.


Anyone experienced in working with HTML knows that whitespace between tags will often cause different browsers to render the same HTML in slightly different ways. In most cases these differences are so small that they can be safely ignored. However, at times these differences are significant. Unfortunately, removing all whitespace from HTML documents makes them incredibly difficult to read. To deal with this problem, Smarty provides the {strip} function, shown in Listing 7.13. At runtime, this function automatically removes all unnecessary whitespace from your HTML code to ensure that it displays properly on all browsers:

Listing 7.13. Using the {strip} Smarty Function
 {strip} <TABLE CELLPADDING=0 CELLSPACING=0 BORDER=0>      <TR>           <TD>Hello</TD>      </TR> </TABLE> {/strip} 

The output of Listing 7.13 to the browser will render as follows:

 <TABLE CELLPADDING=0 CELLSPACING=0 BORDER=0><TR><TD>Hello</TD></TR></TABLE> 

The last of the simple Smarty functions I'll discuss relates to embedding PHP into your templates. Although it is not recommended, Smarty does provide the means to embed PHP code directly into your templates if the need arises. This is done by using either the {php} function, which allows PHP code to be embedded directly into the template and is used in the same way as {literal}/{strip}, or {include_php}, which allows a PHP file to be included into the template. The {php} function serves as a replacement for standard PHP tags <?php ?> and has no parameters. The {include_php} function, however, has the following syntax:

 {include_php file=<filename> [once=<bool_once>] [assign=<variable>]} 

<filename> is the PHP file to include in the template, <bool_once> is a Boolean indicating whether this file should be included only once (the same as if the include_once PHP statement had been used), and <variable> is the name of the variable to assign the output from the PHP script instead of displaying it.

Now that you are familiar with the simplest functions Smarty has to offer, let's get into some of the more complex ones. Most of the functions I'll be talking about provide you with the means to embed presentation logic into your templates. Of course, when the subject of logic comes up, the conditional is never far behindso we'll start with the {if} function. The syntax for the {if} function is as follows:

 {if <conditional>}     ... {elseif <conditional>}     ... [{elseif <conditional>}]     ... [{else}]     ... {/if} 

When working with Smarty functions, any variable can be specified within the confines of the delimiters without specifying additional delimiters. For instance, when using the {if} function, the <conditional> parameter may use any template variable, as shown in Listing 7.14.

NOTE

Using template variables in Smarty functions is good for more than just conditionals! You can use them as the value of any function parameter.


Listing 7.14. Using the {if} Smarty Function
 <HTML> <HEAD><TITLE>Using the {if} function example</TITLE></HEAD> <BODY> {if $secured == true}      Welcome {$name} to the secured area! {else}      You are not authorized to be on this web page. {/if} </BODY> </HTML> 

In this case, we are using the {$secured} template variable in a conditional statement. When you're dealing with conditions in Smarty, they may be as simple or as complex as you desire and work identically to the PHP counterparts.

Another example of a Smarty function that is particularly useful is the {include} function. This function is used to include another template file in an identical fashion to the PHP include statement for PHP scripts. The syntax of the {include} function is as follows:

     {include file=<filename> [assign=<cap_variable>] [<variable>=<value> ...]} 

<filename> is the name of the template file to include and <cap_variable> is the template variable to store the output of the included file in (instead of displaying it). Optionally, any number of variable/value pairs may be specified. These variables will be created as template variables within the included template file. Shown in Listing 7.15, the following {include} function will display the template header.tpl and replace the variable within it with the specified variable (HTML comments denote the individual files):

Listing 7.15. Using the {include} Smarty Function
 <!-- This is the main template file --> {include file=header.tpl title="This is the title of the web page"} <!-- This is the header.tpl file --> <HTML><HEAD><TITLE>{$title}</TITLE></HEAD><BODY> 

NOTE

Templates loaded using the {include} function are cached if the Smarty cache is enabled. To load a file into the current template without it being cached, Smarty provides the {insert} function. This function is identical to the {include} function in every way, except that it will never be cached.


If you wanted to capture the content that would have normally have been displayed by a call to the {include} function, you can use the assign parameter to instead store that output in a template variable (for instance, assign=foo would create a variable {$foo} with the contents of the file).

When you're designing templates, having the capability to perform repetitive tasks can be a real timesaver (especially when creating things such as HTML tables). In Smarty, there are two ways to perform these repetitive tasks: the {section} and the {foreach} functions. Both functions use an array template variable and allow you to loop through integer-indexed and associative arrays, respectively. Let's start with integer-index arrays by looking at the syntax of the {section} function:

 {section name=<counter_var>          loop=<variable>          [start=<start_int>]          [step=<step_int>]          [max=<max_int>]          [show=[show_boolean]}     ... Content to Loop through ... [{sectionelse}]     ... Content to display when there are no more elements to loop through {/section} 

<counter_var> is the name (not a real variable) to use to reference the current index of the array, and <variable> is the array variable to cycle through. The first optional parameter <start_int> defines at what index value (integer) to start counting, and <step_int> defines the increment by which to count during each cycle. Of the last two optional parameters, <max_int> defines the maximum index to allow during the loop, and <show_boolean> determines whether this section is active (that is, will be shown). Any Smarty variable or function may be used within sections, such as {if} functions or even other {section} functions.

NOTE

If the show parameter of the {section} function is set to true, the {sectionelse} segment will still be displayed if provided.


When you're using the {section} function, a number of variables are at your disposal that provide you with a wealth of information regarding the function's current state. Because in most cases you will be using this function to display the formatted contents of an integer-indexed array in your Web pages, let's examine how an individual element is displayed. As you know, displaying an individual element of an array is normally done by appending brackets [ ] containing the desired integer index to the end of a variable. When working with sections, instead of hard-coding an integer index, use the string you specified in the name parameter of the function call. This is illustrated in Listing 7.16 to display the contents of the array stored in the {$myarray} variable in a table:

Listing 7.16. Using the {section} Function
 <TABLE CELLPADDING=0 CELLSPACING=0 BORDER=1> <TR> {section name=countvar loop=$myarray} <TD>{$myarray[countvar]}</TD> {/section} </TR> </TABLE> 

If you wanted to display the contents of the array twice, you could use a combination of the optional {sectionelse} segment in tandem with the max parameter, as shown in Listing 7.17:

Listing 7.17. Using {sectionelse} with {section}
 {section name=countvar loop=$myarray max=2} The Current value is: {$myarray[countvar]}<BR> {sectionelse} There are no more values to display!<BR> {/section} 

As I said earlier, when working with sections, Smarty provides a wealth of extra information for your use. All this information is stored in the special {$smarty} variable mentioned earlier in the chapter. To access these variables, use the following format:

 {$smarty.section.<section_name>.<var_name>} 

<section_name> is the same value as the name parameter for the section, and <var_name> is one of the following:

Table 7.1. $smarty Variables Available for {section}

index

The current integer index being used (this value is affected by the start, step, and max parameters).

index_prev

The previous integer index (1 if unavailable).

index_next

The next integer index that will be used.

iteration

How many times the loop has occurred. It is not affected by any parameters.

first

Boolean indicating whether this is the first cycle of the loop.

last

Boolean indicating whether this is the last cycle of the loop.

loop

This value indicates the last value that was used in the loop (can be used outside of the {section} function).

show

Indicates whether the section was executed.

total

Indicates the total number of iterations the section will loop (can be used outside of the {section} function).


For instance, to determine how many times the {section} function with the name of countvar will loop, the following could be used:

 There will be a total of {$smarty.section.countvar.total} entries below..<BR> 

As a final demonstration of the {section} function, consider the following example. In Listing 7.18, we are creating a table that will list the names of friends (provided by the back-end PHP script). In the event that the PHP script running the template does not provide the names, we'll instead display a nice message:

Listing 7.18. Using the Show Parameter of the {section} Function
 {section name=myfriends loop=$friends show=$show_friends} {if $smarty.section.myfriends.first} <TABLE CELLPADDING=0 CELLSPACING=3 BORDER=1> {/if} <TR><TD>{$friends[myfriends]}</TD></TR> {if $smarty.section.myfriends.last} </TABLE> {/if} {sectionelse} Sorry, I have no friends!! {/section} 

For situations where you would like to deal with associative arrays instead of integer-indexed arrays, Smarty provides the {foreach} function. This function operates in a similar manner to PHP's foreach statement and has the following syntax:

 {foreach from=<loop_variable>          item=<curr_variable>          [key=<key_variable>]          [name=<loop_name>]}     ... [{foreachelse}]     ... {/foreach} 

<loop_variable> is the array to loop through, <curr_variable> and <key_variable> are the names of the variables to store the value of the current variable and its key, respectively, and <loop_name> is the name of this particular {foreach} function. As was true with the {section} function, the {foreach} function also provides an optional {foreachelse} segment, which will be executed when no more elements are in the array. Listing 7.19 provides an example of its use by displaying the key/value pairs for the array {$myarray} in a table:

Listing 7.19. Using the {foreach} Smarty Function
 <TABLE CELLPADDING=0 CELLSPACING=3 BORDER=1> {foreach from=$myarray item=curr_item key=curr_key} <TR> <TD>{$curr_key}</TD><TD>{$curr_item}</TD> </TR> {foreachelse} </TABLE> {/foreach} 

As was also true with the {section} function, the {foreach} function provides a number of variables that can be used inside the {foreach} function via the {$smarty.foreach} variable. These variables are named identically to those discussed for the {section} function (except $smarty.foreach is used) with a few notable omissions. Specifically, only the iteration, first, last, show, and total values are available for the {foreach} function.

The final internal Smarty function that I will discuss is the {capture} function. This function is used to duplicate the functionality provided by the assign parameter of the {include} function without requiring an additional file. Anything that normally would have been output to the browser that is inside a {capture} function will instead be assigned to a template variable. Like all other functions, {capture} functions may be embedded within other Smarty functions. The syntax of this function is as follows:

 {capture name=<var_name>}      ... {/capture} 

<var_name> is the name with which to associate the captured output. To access the captured output, you must access the {$smarty.capture.<var_name>} variable, as shown in Listing 7.20:

Listing 7.20. Using the {capture} Smarty Function
 {capture name=mytable} {include file="gen_table.tpl"} {/capture} Here is the contents of my table: {$smarty.capture.mytable} 

Before I move on from Smarty functions, I'll finish my discussion by noting that it is not complete! I have covered only those functions that are internal to the Smarty enginebut there are many more! A number of "optional" plug-in functions (and variable modifiers for that matter) can be used with the Smarty engine. Some of the more popular plug-ins now come standard with Smarty, and information on their use can be found in the Smarty documentation. For more information or to download other useful plug-ins, you can find a listing of official Smarty plug-ins at the Smarty home page (http://smarty.php.net/).

Next, let's examine how Smarty is designed to handle data that, for the most part, is considered constant. These variables are typically things such as the background color of your Web page or other data that won't change from request to request. Although it's likely that a great portion of the data contained within a configuration file will be related and used within your templates, it's worthwhile to mention that these configuration values can also be used on the application logic side of things to store data of similar nature.

Configuration files used by Smarty are very similar in structure to the php.ini file. An example of a configuration file compatible with Smarty can be found in Listing 7.21:

Listing 7.21. A Smarty-Compatible Configuration File
 # myconfiguration.ini # Color Configuration Variables [Colors] background=#FFFFFF link=#FF0000 vlink=#FF00FF alink=#00FF00 # Some static text used in the web site [StaticText] base_url=http://www.phphaven.com/ [.DatabaseSettings] host=localhost username=user password=mypassword 

In Listing 7.21, you see that a number of configuration variables have been specified that may be useful to a Smarty-enabled website. As with the php.ini file, all section headings (enclosed in brackets [ ]) and configuration values follow the same rules as PHP variables do in terms of acceptable characters and structure. Also note that comments are specified by either the # or the ; character at the start of a line.

One of the differences between the PHP configuration file and that used with Smarty is the [.DatabaseSettings] section. Note that as previously mentioned, section headings must follow the same rules as PHP variable names; hence, this section name appears invalid (because it starts with a period). Despite seeming as though there is a misprint in this book, this is indeed intended. A period can be placed at the start of any section or configuration value to tell Smarty to "hide" those values from the template engine. When hidden, these values will not be available for use within templates, but can still be accessed from PHP itself. Therefore, they are ideal places to store potentially sensitive data (such as database usernames and passwords) without potentially exposing those values to Web designers who should not have access to those resources when working on templates.

To continue the discussion about using configuration values in templates, let's look at how to access these values from a Smarty template. To access configuration values, the configuration file must first be loaded using the {config_load} template function.

The Smarty {config_load} function has the following syntax and parameters:

 {config_load file=<filename> section=<section> scope=<scope>} 

<filename> is the name of the configuration file to load, <section> is the specific section within the configuration file to load, and <scope> defines what templates may access these variables. When you're dealing with configuration values in Smarty, there are three different scopes: local, which only creates the values for the current template file; parent, which will create the values for both the current template and the template that called it; and global, which makes the values available in any template.

After you have loaded a configuration file from your template, configuration variables are accessed by encapsulating the name of the desired value within these special brackets: {# and #}. Listing 7.22 shows how the values in the configuration file shown in Listing 7.21 would be used from a template:

NOTE

If you are using custom delimiters (anything other then the { and } brackets) you must use those instead of {# and #}. That is, if your delimiters are <!-- and -->, configuration values are specified using <!--# and #-->.


Listing 7.22. Using a Configuration File in Smarty
 {config_load file="myconfiguration.ini" section="Colors" scope="local"} <HTML> <HEAD> <BODY LINK={#link#} ALINK={#alink#} VLINK={#vlink#} BGCOLOR={#background#}> Welcome to <A HREF="{#base_url#}">PHPHaven.com!</A> </BODY> </HTML> 

As I have previously mentioned, configuration values or sections that begin with a period will not be accessible using the {config_load} function. To access these functions, you'll need to load the configuration file using the Smarty Config_File class found in the Config_File.class.php file.

The Config_File class is what Smarty uses to read configuration values from the files you create, and it can be used independently of Smarty to load values for use within PHP itself. When you use this class, a few member variables can be modified to suit your needs:

$overwrite

(Boolean) If true, configuration values with the same name will overwrite each other.

$booleanize

(Boolean) If TRue, the values of on, TRue, yes, and their counterparts will automatically be returned as a Boolean true or false in PHP.

$read_hidden

(Boolean) If false, hidden configuration values or sections (starting with a period) will be inaccessible.

$fix_newlines

(Boolean) If true, the class will automatically convert files in non-Unix formats (using \r or \r\n to signify a new line) into Unix format (using just \n for new lines).

Note: $fix_newlines does not modify the configuration file itself, only the data read from it.


In general, these configuration files can probably be left unchanged without consequence. The first step in using the Config_File class is to specify the location where it can find the configuration files it will be working with. This can either be done by passing it a path when the instance is created (using the constructor) or through the set_path() member function. Both the constructor and the set_path() function take a path as the single parameter. After the path has been set, configuration values are retrieved by using the get() member function. The syntax for this function is as follows:

 $object->get($filename[, $section[, $variable]]) 

$filename is the name of the configuration file to load (in the directory specified by either the constructor or set_path()), $section is the section to load within the configuration file, and $variable is the specific variable to load. If the $variable parameter is omitted, all the variables in the section specified will be loaded. If neither optional parameter is provided, only those configuration values not a part of a section will be returned.

NOTE

When accessing hidden sections or configuration values, do not put a period in front of the name! The Config_File class will automatically remove the period from the name of the hidden section.


Another method of returning a value from a configuration file using the Config_File class is using the get_key member function. This function takes a single string as a parameter representing the value to access from the configuration file in the following format:

 filename/section name/value 

Hence, to access a value in test.ini named myvalue in the section mysection, the following value would be passed to the get_key() function:

 test.ini/mysection/myvalue 

Like its counterpart the get() function, particular values may be omitted, in order, from right to left, but the filename section must always remain.

Following are a few more useful functions found in the Config_File class:

get_file_names()

Returns an array of the configuration files loaded by this instance of Config_File.

get_section_names($filename)

Returns an array of section names in the file specified in $filename.

get_var_names($filename [, $section])

Returns an array containing the names of all the values stored without a section in $filename or in the section specified by $section within the file.

clear($filename)

Removes all configuration values from the file specified by $filename from memory.


To show how the Config_File class can be used in a practical manner, let's again return to the configuration file found in Listing 7.21 to load the relevant database information (see Listing 7.23):

Listing 7.23. Using the Config_File Class
 <?php     require("Config_File.class.php");     $config = new Config_File("");     $dbsettings = $config->get("phphaven_config.ini", "DatabaseSettings");     echo <<< OUTPUT Your Database Host is $dbsettings[host]<BR> Your Username is $dbsettings[user]<BR> Your Password is $dbsettings[password]<BR> OUTPUT; ?> 



PHP 5 Unleashed
PHP 5 Unleashed
ISBN: 067232511X
EAN: 2147483647
Year: 2004
Pages: 257

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net