# Template Class

## Contents

Installation Main Usage Other functions <INCLUDE> tag Loop Code Bugs History License

## Installation

Simply bung the class file somewhere where your script can include() it, and then include() it.

## Main Usage

There are three main methods (functions) to the template engine, (engine hmmmm? sounds good). There are of course other methods that can and indeed have to be accessed, but these 3 are the real meat of the class.

`void parse(string file identifier)`:

This inserts the values of all the variables that have been register()ed (see further down) into the template. Obviously the variable must be in the template. To parse multiple files in one call, the argument can be a comma seperated string of file ids.
05/08/2000 This function also processes any <INCLUDE> tags in the specified file (see section on includes).

`void parse_loop(string file identifer, string array name)`:

Note that the second argument is the array NAME! Not the array itself. The function takes an array (which has to be in the format described below) and substitutes the "loop code" (see later) for the data in the array. Difficult to describe, (at least, when half drunk) the format of the array is like so:

                       +---------- This is the row number, starting at zero.
                       |
                       |      +--- This is the column name.
                       |      |
                       |      |
                $array[0]['column_1']  Contains data for row 1, column 1.
                $array[0]['column_2']  Contains data for row 1, column 2.
                $array[0]['column_3']  Contains data for row 1, column 3.

                $array[1]['column_1']  Contains data for row 2, column 1.
                $array[1]['column_2']  Contains data for row 2, column 2.
                $array[1]['column_3']  Contains data for row 2, column 3.

See. Makes perfect sense. The column names should correspond to entries in the template file. Check the example scripts if you're still unsure.

`void parse_sql(string file identifier, string result set name)`:

Very similar to the above, but instead of using an array for the data, it uses a mysql result set. Again, pass the function the name of the result set, and not the result set itself, and as before it replaces the "loop code" (see later) with the data from the result set. The field names must correspond with what is in the template.

`void parse_pgsql(string file identifier, string result set name)`:

Basically the above function but parses Postgres result sets instead of MySQL. This function was contributed by Ovidiu Eftimie.

NB: For the above three functions the array/result set variables should be lowercase.

## Other functions

`void load_file(string file identifier, string file name)`:

This, (as you may well have guessed), simply loads a template file into the object so that we may use it. The file identifier is just that, and is what is used to refer to the file from now on, much like in FastTemplate. The file identifier is necessary so that multiple templates are possible.

                    $tpl = new template;

                    $tpl->load_file('header', 'header.html');
                    $tpl->load_file('main', 'your.template.html');
                    $tpl->load_file('footer', 'footer.html');

                    $tpl->register('header', 'title');
                    $tpl->register('main', 'var1, var2, var3');
                    $tpl->register('footer', 'credits');

                    $tpl->parse('header, main, footer')
                    $tpl->print_file('main');

`void set_identifiers(string beginning, string end)`:

Enables you to determine what identifies a "variable" in the template file. Defaults to "{" and "}", so in a template file {example} would be replaced with the contents of the variable $example. An example:

            $tpl = new template;
            $tpl->load_file('main', 'your.template.html');
            $tpl->register('main', 'var1, var2, var3');
            $tpl->set_identifiers('{{', '}}');
            $tpl->parse('main')
            $tpl->print_file('main');

`void register(string file identifier, mixed variable names))`:

Registers a variable so that later, the parse() function will insert it into the template file. The second arugment can be either a comma seperated string containing the variable names (not the variables themselves), or it can be an array containing variable names. If it is an array the variable names must be the values, and not the keys. The arrays can be associative, but it is still the values that are registered. Nested arrays will be traversed. For example, all the below register $var1, $var2 and $var3:

- $obj->register('id', 'var1, var2, var3');
- $obj->register('id', array('var1', 'var2', 'var3'));
- $obj->register('id', array('var1', array('var2', 'var3')));

An example:

            $tpl = new template;
            $tpl->load_file('main', 'your.template.html');
            $tpl->register('main', 'var1');
            $tpl->register('main', array('var2', 'var3'));
            $tpl->parse('main')
            $tpl->print_file('main');

`void print_file(string file identifer)`:

After all processing is done, use this script to print the template. Multiple templates can be printed at once by comma seperating the identifiers. An example:

            $tpl = new template;
            $tpl->load_file('main', 'your.template.html');
            $tpl->register('main', 'var1, var2, var3');
            $tpl->parse('main')
            $tpl->print_file('main');

`string return_file(string file identifier)`:

After all processing is done, use this script to return the html code that has been generated. Can be useful for post-processing or (for example) inserting the template into an email. Multiple templates can be returned at once by comma seperating the identifiers. An example:

            $tpl = new template;
            $tpl->load_file('main', 'your.template.html');
            $tpl->register('main', 'var1, var2, var3');
            $tpl->parse('main')
            $output = $tpl->return_file('main');

`void pprint(string file identifer [, mixed variable names])`:

This function acts as an alternative to calling register(), parse() and then print_file() and will call all those functions for you. The second argument can be a string or an array, as with the register() function and is passed directly to that function. This function was contributed by Bruce Christensen. An example:

            $tpl = new template;
            $tpl->load_file('main', 'your.template.html');
            $tpl->pprint('main', 'var1, var2, var3');

`void pget(string file identifier [, mixed variable names])`:

This function acts as an alternative to calling register(), parse() and then return_file() and will call all those functions for you. The second argument can be a string or an array, as with the register() function and is passed directly to that function. This function was contributed by Bruce Christensen. An example:

            $tpl = new template;
            $tpl->load_file('main', 'your.template.html');
            $output = $tpl->pget('main', 'var1, var2, var3');

`void pprint_file(string filename [, mixed variable names])`:

This function acts as an alternative to calling load_file(), register(), parse() and then print_file() and will call all those functions for you. When loading the file it will find a spare file_id, use it, and unset() it when finished. The second argument can be a string or an array, as with the register() function and is passed directly to that function. If you have loops to process, you should not use this function. This function was contributed by Bruce Christensen. An example:

            $tpl = new template;
            $tpl->pprint_file('your.template.html', 'var1, var2, var3');

`void pprint_file(string filename [, mixed variable names])`:

This function acts as an alternative to calling load_file(), register(), parse() and then return_file() and will call all those functions for you. When loading the file it will find a spare file_id, use it, but will NOT unset() it when finished. The second argument can be a string or an array, as with the register() function and is passed directly to that function. If you have loops to process, you should not use this function. This function was contributed by Bruce Christensen. An example:

            $tpl = new template;
            $output = $tpl->pget_file('your.template.html', 'var1, var2, var3');

## <INCLUDE> tag

The <INCLUDE> tag can make your life much easier by enabling you to include things like header/footer files in your templates. An example is below:

<INCLUDE FILENAME="templates/header.html">

The case of the tag and attribute name doesn't matter, but the spacing does. There must be precisely one space between "include" and "filename" and no spaces either side of the equals sign or between the last double quote and greater than sign. Basically stick to the above and you'll be fine. Obviously the string inside the quotes is the filename, and must point to a valid file. If the file is not found an error will be printed in its' place.

IMPORTANT: The path of the file to be included should be relative to the php script that runs the template script stuff, and not the template with the tag in. Multiple include ttags can be in a template, and even multiple include tags pointing to the same file.

## Loop Code

What is loop code then? Loop code is the piece of code that gets repeated when parse_loop(), parse_sql() or parse_pgsql() are run. It could be for example a table row in HTML, which gets repeated x number of times depending on how many rows there are in the array or sql result set, (for the structure of the array, see the diagram further up). Loop code has to be defined in a particular way:

            <LOOP NAME="your_name">
                    <Code to be repeated>
            </LOOP NAME="your_name">

The beginning tag defines the start of the loop code, and the name is the name of the array or result set it is assigned to. The ending tag simply signifies the end of the loop code. Here is an example of loop code in a table:

            <TABLE BORDER="0" BGCOLOR="#000000">
                    <TR>
                            <TH BGCOLOR="#DDDDDD">Column 1</TH>
                            <TH BGCOLOR="#DDDDDD">Column 2</TH>
                            <TH BGCOLOR="#DDDDDD">Column 3</TH>
                    </TR>

                    <LOOP NAME="table_rows">
                    <TR>
                            <TD BGCOLOR="#DDDDDD">{column_1}</TD>
                            <TD BGCOLOR="#DDDDDD">{column_2}</TD>
                            <TD BGCOLOR="#DDDDDD">{column_3}</TD>
                    </TR>
                    </LOOP NAME="table_rows">

            </TABLE>

Here, the table has the usual structure. First the header row is static. Then, the data row is loop code. What will happen once this is parsed is that the loop code gets repeated once for every row in the array or result set. The {column_1} etc will also be replaced with the appropriate data for that column. Also, the loop tags will be removed. A good example of this is the complete-script.php script (which goes with the complete-template.html template file). Compare the before and after and you should easily understand it.

## Performance

*** See History for updated performance info ***

Still with me? Good, as that's all the hard work done.
The performance of the engine (still sounds good...) is very good, primarily due to the fact that regular expression functions (ereg, preg_match etc) are not used.

Compared against FastTemplate, my own (admittedly quite basic) benchmarks came out consistently around 30% faster. This was done by taking timestamps using microtime() just before instantiating the template object and just after printing the results, doing a bit of jiggery-pokeryŽ with the results and inserted into a db. The average of twenty times was taken and then compared.

It also came out as 60% faster than another template routine, which is not an object or function, simply an include file, but it's not publicly accessible so it doesn't mean that much.

## Bugs

Not bloody likely.

## History

13/08/2000 - Version 1.3
Added five new functions:

- parse_pgsql()
- pprint()
- pget()
- pprint_file()
- pget_file()

These new functions make the class very much more useful, accessible and easy to use. Also made some minor alterations to existing functions, Eg. parse() can now accept a comma seperated string of file_ids to parse multiple templates in one call.

05/08/2000 - Version 1.23
Added <INCLUDE> tag. So you can include other files in your template, eg. header/footer files.

11/07/2000 - Version 1.13
You can now have two loops with exactly the same loop code in one template file.

25/06/2000 - Version 1.12
Altered load_file() so it reads the file using fread() instead of file(). Marginally faster.

04/06/2000 - Version 1.1
Altered parse_loop and parse_sql so that they don't have to go through every line of the file they're parsing. The complete example (single template) is now more than twice as fast, (0.008 vs 0.017 on RHL 6.1, Apache 1.3.12, Php 4.0.0, P166, 32Mb).

23/05/2000 - Version 1.0
Initial release.

## License

Postcard-ware. If you use this utility then I'd appreciate a postcard from ya. :)
Otherwise, it's free, be grateful, don't whinge, and don't sue me if it screws your system.