Main
Download
Guide
FAQ
Contact
Other projects
- Spawn SQL

Wishlist/Bugs
Home

Chip Reference Guide

  1. Overview
    1. Installation and set-up
    2. Template file structure
    3. Variable usage
    4. Template aliasing
  2. Parsing directives
    1. new - Create a new template
    2. link - Link an already created template
    3. include - Include another file containing templates
    4. if - The conditional flow control directive
    5. elseif
    6. else
    7. set - Set a variable
    8. foreach - Loop an array
    9. copy - Duplicate already made templates
  3. Template control functions
    1. parse_file - Parse a file
    2. parse_template - Execute a template's instructions
    3. output_template - Print a template
    4. clear_template_cache - Reset a template's cache to NULL
    5. set_template_properties - Sets the properties of a template.
    6. set_var - Alternative syntax to referencing variables directly.
    7. clear_vars
    8. set_alias - Alias a template.
    9. clear_alias - Remove a template's alias.

Overview

Installation and set-up

Installing and setting up the Chip Template Engine is a snap. First, fetch the version of your choice from the download page. Then extract the code into the directory of the file you wish it to be included into. It is not necessary that it be put there but it makes it easier to include. For this example we will assume that either (a) the file has been put into the same directory or (b) the PHP/Perl path has been modified so that we only need to include the filename.

When installed, next we include the file, set up the GUI in directory and the PHP/Perl out directory.

Warning: If the PHP/Perl out directory is not writable by the script, Chip will fail to run properly.

Once the variables are set up properly, and the directories have the correct permissions you are ready to start placing template/GUI files into the GUI directory.

PHP set-up code

common.php
...

require_once( "chip_gui.php" );

$gui = new Chip;

$gui->gui_directory = "gui";
$gui->php_directory = "php";

...

And thanks to the constructor of Chip (function Chip( $gui_directory=null, $php_directory=null )) we can also do this:
common.php
...

require_once( "chip_gui.php" );

$gui = new Chip( "gui", "php" );

...

Perl set-up code

common.pl
...

require "chip_gui.pm";

my $gui = new Chip;

$gui->{'gui_directory'} = "gui";
$gui->{'pl_directory'} = "perl";

...

Constructor parameters are not yet implemented in Perl.

Template file structure

Template file structure is simple. However, it differs from regular HTML files in one major way: all HTML data must be stored in a template. That is, there can be no loose template data that is not placed somewhere within a "<parser:new name="..."> tag. If loose HTML or any other data is found outside of a template the parser will complain.

You are allowed as many template files as you want inside of a single template files. Templates can also be embedded and created inside of other template files and linked in any other place. If a template is linked, but it cannot be found within the current file or any other files that have been included, there will be an error.

incorrect.gui
<parser:new name="scores">
{$a} was greater than {$b} in the race, but {$c} conquered all.
</parser:new>

<p>

<parser:new name="path">
All contestants ran {$path} and encountered {$hill_number} hills.
</parser:new>

This will undoubtedly give errors.
correct.gui
<parser:new name="race">

<parser:new name="scores">
{$a} was greater than {$b} in the race, but {$c} conquered all.
</parser:new>

<p>

<parser:new name="path">
All contestants ran {$path} and encountered {$hill_number} hills.
</parser:new>

</parser:new>

In this case, when "race" is called to be parsed "scores" and "path" will be parsed first. All operations inside will be executed, much like a function. We can also link similarly.
race_details.gui
<parser:new name="race">

<parser:new name="scores">
{$a} was greater than {$b} in the race, but {$c} conquered all.
</parser:new>

<p>

<parser:link name="path">

</parser:new>

<parser:new name="path">
All contestants ran {$path} and encountered {$hill_number} hills.
</parser:new>

Which will most certainly produce the same results. However, let's suppose "path" was in a separate file. Let us suppose "path" was in a file called "path_outputs.gui".
race_details.gui
<parser:new name="race">

<parser:new name="scores">
{$a} was greater than {$b} in the race, but {$c} conquered all.
</parser:new>

<p>

<parser:link name="path" src="path_outputs">

</parser:new>

In the example above, path_outputs.gui is parsed, included and then "path" is linked within "race" after "scores". There are also other ways to get more than one file to cooperate with each other (See link, include).

Variable usage

Variable usage has been made simple, and rather predictable for all those used to PHP. As long as variables begin with a $ and are placed within curly braces they will be parsed as variables and later on replaced. Arrays are of the same nature. There is no special treatment for arrays. They can be included into the code normally.
variable_test.gui
<parser:new name="show_variables">

{$a} is variable "$a"<br>
{$this_variable} is variable "$this_variable"<br>
{$array_data[1]} is variable "$array_data[1]"<br>
{$array_data['apple']} is variable "$array_data['apple']"

</parser:new>

In PHP the only restraints on variables are the restraints PHP puts on them. That is, variables with obvious syntax errors. Not completing quotes in arrays, or even unbalances braces will cause PHP errors in the PHP code generated by Chip. Not placing the variable in curley braces or not prefixing the variable with a $ will result in what was typed to appear in the HTML document, literally.

In Perl the variable restraints may be more specialized to parsing errors. If such an error should arise or the code is behaving strangely when it is not supposed to be please contact me. Even when programming in Perl the variables in the GUI files are still done PHP-esque to increase portability. Please note that when using arrays/hash arrays to always use a reference.


Template aliasing

When coding HTML, it is often important to repeat several lines of HTML code over and over again. This is very likely to be done when the same HTML code needs to appear in several different files. With most template systems, even this one, this can be achieved by using the following:
main.gui
<parser:new name="header">
<html><head><title>Usual title code</title>
<head><body>
</parser:new>

<parser:new name="footer">

</body></html> </parser:new>

And then in every smaller page template you have to link these two in like so:
cart.gui
<parser:new name="cart">
<parser:link name="header">

Cart code <parser:link name="footer">
</parser:new>

However, as an alternative to that, one can do template aliasing.
main.gui
<parser:new name="default">
<html><head><title>Usual title code</title>
<head><body>

<parser:link name="main">

</body></html>
</parser:new>

And then use set_alias to alias the "cart" template to "main."

Parsing directives

new

Creates a new template. The template name must be unique and this tag must be ended since it is a container tag.

Parameters
nameThe unique name of a template.
visible(Optional, Default: "true") Visibility property of the template.

Templates can be embedded in other templates infinitely. However, all data must be placed inside of a template.

Example

template.gui
<parser:new name="main_template">

The following template should be invisible unless otherwise set by "set_template_properties"<br>

<parser:new name="invisible_template" visible="false">
Can you see me?
</parser:new>

</parser:new>


link

Links another template into the current template.

Parameters
nameThe name of the template to link.
src(Optional) When set tells the parser to parse another file before linking. Extensions are also optional.

Linking templates without the "src" parameter implies that the template has already been included or is in the same file currently being parsed. Linking cannot be done outside of a "new" command tag and if the template is not found errors will be raised.

Example

linking.gui
<parser:new name="main_template">

Where is the chair?<br>
<parser:link name="chair_location">
<parser:link name="question" src="external">

</parser:new>

<parser:new name="chair_location">
The chair is on the table.<br>
</parser:new>

external.gui
<parser:new name="question">

What's it doing there?
</parser:new>


include

Tells the parser to parse another template file.

Parameters
srcThe file name of the GUI file to link. File extensions are optional.

This command tells the parser to stop parsing and parse another file before finishing. It is a rather simple command, however there is one thing to pay attention to: it cannot be embedded in any other tag. It can be placed anywhere in the file except for inside of a template.

Let's re-write the above example to give alternatives.

Example

linking.gui
<parser:include src="external">

<parser:new name="main_template">

Where is the chair?<br>
<parser:link name="chair_location">
<parser:link name="question">

</parser:new>

<parser:new name="chair_location">
The chair is on the table.<br>
</parser:new>

external.gui
<parser:new name="question">

What's it doing there?
</parser:new>


if

Only use the HTML code inside this tag if the condition provided is true. Is a container tag and must be closed.

Parameters
expThe expression to evaluate.

This is the generic if/conditional command. All data within these tags are only displayed/executed upon "exp" being true. Since PHP evaluates literally what is passed in "exp" the constraints of PHP apply, and also so does all PHP functions. By that matter, logical expressions work as well (and, or, etc). When using Perl be careful to make sure that string comparisons are correct. Although the variables in the templates follows PHP's variable format, the expression handler is different. In other words, make sure to use Perl compliant expressions.

These tags can also be embedded in each other infinitely.

Example
With PHP

main.gui
<parser:new name="array_display">

<parser:if exp="is_array($data) and count($data)>1">
The $data is an array and has more than one item. </parser:if>

</parser:new>

<parser:new name="animal_query">

<parser:if exp="$animal=='cat'">
The animal he is keeping is a cat!
</parser:if>

</parser:new>

With Perl
main.gui
<parser:new name="array_display">

<parser:if exp="ref($data) eq 'ARRAY' and @{$data})>1">
The $data is an array and has more than one item. </parser:if>

</parser:new>

<parser:new name="animal_query">

<parser:if exp="$animal eq 'cat'">
The animal he is keeping is a cat!
</parser:if>

</parser:new>

Known problems/issues
Due to the preg expression that reads and interprets the tags, using double quotes within the expresion will cause parsing errors and/or unexpected results. To avoid this problem, stick to using single quotes when using string comparisons.


elseif

The conditional tag that executes when the first condition fails and the expression is true. Can only be embedded in an "if" tag. This tag does not have to be close speicifically, unlike if.

Parameters
expThe expression to evaluate.

Follows the same constraints and examples as "if" except this tag comes after an "if" statement. It is only executed when the "if" statement that it is included in fails and exp is true.

Example

main.gui
<parser:new name="animal_query">

<parser:if exp="$animal=='cat'">
The animal he is keeping is a cat!
<parser:elseif exp="$animal=='dog'">
Why does he even like dogs!
<parser:elseif exp="$animal=='cow'">
A cow! Now that's a real pet.
</parser:if>

</parser:new>

Known problems/issues
See if.


else

The operation that executes when all conditional statements fail.

Parameters None

Must be placed within the "if" tag. It does not need to be ended specifically unlike the "if" tag.

Example

main.gui
<parser:new name="star_rating">

<parser:if exp="$stars>5">
That's a lot of stars.
<parser:elseif exp="$stars>3">
Not so bad
<parser:else>
Better luck next time
</parser:if>

</parser:new>


set

Sets a variable. Requires a closing tag.

Parameters
variableThe name of the variable to set.

The variable set command tag allows any variable to be set to the data inside of the tag. It can be embedded in any conditional tag and "new" tags. Variable setting will function as expected when embedded.

Since setting variables works across templates, it is useful for inserting code into the main template from a sub template or other various tricks.

Example

girls.gui
<parser:new name="girl_i_like">

<parser:if exp="$day=='sunday'">
<parser:set variable="$girl">Jessica</parser:set>
<parser:else>
<parser:set variable="$girl">Erica</parser:set>
</parser:if>

Today I like {$girl}

</parser:new>

default.gui
<parser:new name="main">
<html><head><title>{$title}</title></head>
<body>

<parser:link name="body">

</body></html>
</parser:new>

<parser:new name="body">

<parser:set variable="$title">Hello world</parser:set>
Hello world title setting! The title should be "Hello world".
</parser:new>


foreach

Loops through an array. Requires a closing tag.

Parameters
arrayThe name of the array.
valueVariable to contain the current array data.
key(Optional) Variable to contain the current array index.

This command tag, most closely resembling PHP's "foreach" construct, will loop through an array until it's end has been reached. Upon each loop pass it will append all of the data in the tag, replacing any variables necessary. Conditional tags may be embedded within, and this tag may be embedded within contional tags. The variables passed in "value" and "key" will be written to upon each pass.

The behaviour changes slightly when in Perl. In Perl, when both value and key are set array is treated as a hash ref. When only value is set and key is null array is treated as an array ref. If this behaviour is undesirable, please let me know. However, after some thinking I decided this was the better method.

Example

loop.gui
<parser:new name="display_array">

$single_dimension_array elements:<br>
<parser:foreach array="$single_dimension_array" key="$key" value="$value">
Element {$key} is {$value}<br>
</parser:foreach>

$multi_dimensional_array elements:<br>
<parser:foreach array="$multi_dimensional_array" value="$value">
Element a:{$value['a']}, element b:{$value['b']}<br>
</parser:foreach>

</parser:new>


copy

(version >0.3) Duplicates a pre-existing template.

Parameters
tmpThe name of the template to duplicate.
nameNew name of the template.
src(Optional) Fetches the template from another GUI file.
visible(Optional) Sets the new template visible property.

The "copy" command tag allows for template copying without having to use copy and paste, or reusing the same template but embedded in different parent templates. The copied template has its own properties, cache, and is an entity completely separate from the template it is a copy of (although it currently makes call to the template it is a copy of code-wise).

Copy can be used inside of a template as well as outside. When used inside of a template a dependency is created.

Example

form.gui
<parser:new name="listbox">
<select size="5" name="{$name}">

<parser:foreach array="$items" key="$key" value="$value">
<option id="{$key}">{$value}<option>
</parser:foreach>

</select>
</parser:new>

<parser:new name="form">

Birthdate: <parser:copy tmp="listbox" name="month">
<parser:copy tmp="listbox" name="day">
<parser:copy tmp="listbox" name="year">

</parser:new>


Template control functions

parse_file

function parse_file( $fileshell )

Parameters
fileshellName of the GUI file to parse. Extensions are optional.

This function takes a single parameter which becomes the name of the file to be parsed. Since the function it uses to ensure that the file name is correct (format_filename) will add an extension if one is missing, extensions are completely optional. Passing the string "main" and "main.gui" will produce the exact same results.

parse_file looks for the filename passed to it, runs a syntax check on the file and then parses it into PHP/Perl, placing it in the writable PHP/Perl output directory. That file is then included into the PHP/Perl source. Incorrect filenames will result in file opening errors.

However, if the force_rebuild option is not set this function checks to see if there is already a PHP/Perl file generated of the same name as the GUI file being passed. If there is, the function then checks to see if the PHP/Perl file's modify time is older or newer than its GUI counterpart. Only when the GUI file's modify time is newer will it make a new PHP/Perl file. This allows for a system of caching and faster page output. Of course, if no PHP/Perl file exists then it shall also create one.

Example

main.php
...

// Make sure to include our "main" page templates
$gui->parse_file( "main" );

$gui->variables[ 'first_name' ] = $customer['first_name'];
$gui->variables[ 'last_name' ] = $customer['last_name'];
$gui->variables[ 'last_logon' ] = $customer['last_login_time'];

// Give the customer the welcome back message and the front page
$gui->output_template( "main_page" );

...

main.pl
...

# Make sure to include our "main" page templates
$gui->parse_file( "main" );

$gui->{'variables'}->{'first_name'} = $customer->{'first_name'};
$gui->{'variables'}->{'last_name'} = $customer->{'last_name'};
$gui->{'variables'}->{'last_logon'} = $customer->{'last_login_time'};

# Give the customer the welcome back message and the front page
$gui->output_template( "main_page" );

...


parse_template

function parse_template( $name, $action="a" )

Parameters
nameName of the template to parse.
action(Optional, default: "a") How to handle the cache data.

parse_template brings all of the HTML code written in the template, preforms all conditions, replaces all variables, and then caches the end result. The cache result is controlled by the action parameter. All sub templates if not already parsed will be parsed upon this function being called. If a sub template has already been parsed, it will not be re-parsed.

action options
aDefault. Append the output to the end of the template cache.
iInsert the output in the beginning of the template cache.
wOverwrite the template cache.
t(version >0.3) Override caching, and return only the parsed template data. No changes will be made to the cache.

Even if a template has already been parsed calling "parse_template" again on the template will force a re-parse. Thus making "parse_template" useful for situations where data needs to appear repeated in the output. It is also useful when multiple variables of the same name appear in many template files and one wishes to parse this file explicitly before others.

Note: Despite the misleading name, no parsing is actually done when this function is called.

Example

customers.php
...

$gui->parse_file( "customers" );

$query_result = mysql_query( "SELECT first_name, last_name, zip_code FROM customers WHERE customer_id={$customer_id}" );

while( $gui->variables['customer'] = mysql_fetch_assoc($query_result) )
  $gui->parse_template( "customer_list" );

mysql_free_result( $query_result );

// Output the customer list, finally $gui->output_template( "customer_list" );

...


output_template

function output_template( $name )

Parameters
nameName of the template to output.

output_template gets the cache of the template name and then uses print to ouptut it. If the template name has already been parsed it will use the template's cache. If the template has not been parsed yet (and perhaps its sub templates) output_template will parse them. In straightforward circumstances where no fancy coding or long loops are to be executed, this function may be all that is necessary.

Example

register.php
...

$gui->parse_file( "register" );

// Get the reigster URL from the URL list
$gui->variables['register_url'] = getURL( "register" );

// Output the register form
$gui->output_template( "register_form" );

...

register.pl
...

$gui->parse_file( "register" );

# Get the reigster URL from the URL list ("getURL" is obviously a defined function)
$gui->{'variables'}->{'register_url'} = getURL( "register" );

// Output the register form
$gui->output_template( "register_form" );

...


clear_template_cache

function clear_template_cache( $name )

Parameters
nameName of the template to have its cache set to NULL.

Clearing the template's cache will make it as if the template has never been parsed at all. All of the sub templates belonging to the template's cache will remain, but this template's cache will be set to NULL. Useful for templates embedded in templates that are meant to be repeated.

Example

menu.pl
...

# Keeping the menu items in the DB keeps it dynamic
my $query_result = $mysql_dbi->prepare( "SELECT * FROM menu_items WHERE parent_id IS NULL ORDER BY sort_order;" );
$query_result->execute();

// File that handles the main page
$gui->parse_file( "default" );

while( my $item = $query_result->fetchrow_hashref() )
{
  # buildURL has been made to get the proper URL from keywords
  $item->{'url'} = buildURL( $item->{'url_script'}, $item->{'url_action'} );

  $sub_query_result = $mysql_dbi->prepare( "SELECT * FROM menu_items WHERE parent_id=$item->{'menu_item_id'};" );
  $sub_query_result->execute();

  if( $sub_query_result->rows() )
  {
    # Make sure the old template cache was cleared
    # And since we need to display the sub items show the template
    $gui->set_template_properties( "_main_menu_sub_items", "visible", 1 );
    $gui->clear_template_cache( "_main_menu_sub_items" );
    while( my $sub_item = $sub_query_result->fetchrow_hashref() )
    {
      $sub_item->{'url'} = buildURL( $sub_item->{'url_script'}, $sub_item->{'url_action'} );
      $gui->{'variables'}->{'sub_menu_items'} = $sub_item;
      $gui->parse_template( "_main_menu_sub_items" );
    }
  }
  else
  {
    # Since there are no sub menu items hide the template for sub menu items and parse the menu item template
    $gui->set_template_properties( "_main_menu_sub_items", "visible", 1 );
  }
  $gui->{'variables'}->{'menu_items'} = $item;
  $gui->parse_template( "_main_menu_items" );
}

...

menu.php
...

// Keeping the menu items in the DB keeps it dynamic
$main_query_result = mysql_query( "SELECT * FROM menu_items WHERE parent_id IS NULL ORDER BY sort_order;" );

// File that handles the main page
$gui->parse_file( "default" );

while( $item = mysql_fetch_assoc( $main_query_result ) )
{
  // buildURL has been made to get the proper URL from keywords
  $item['url'] = buildURL( $item['url_script'], $item['url_action'] );

  $sub_query_result = mysql_query( "SELECT * FROM menu_items WHERE parent_id={$item['menu_item_id']};" );

  if( mysql_num_rows($sub_query_result) )
  {
    // Make sure the old template cache was cleared
    // And since we need to display the sub items show the template
    $gui->set_template_properties( "_main_menu_sub_items", "visible", true );
    $gui->clear_template_cache( "_main_menu_sub_items" );
    while( $sub_item = mysql_fetch_assoc( $sub_query_result ) )
    {
      $sub_item['url'] = buildURL( $sub_item['url_script'], $sub_item['url_action'] );
      $gui->variables['sub_menu_items'] = $sub_item;
      $gui->parse_template( "_main_menu_sub_items" );
    }
  }
  else
    // Since there are no sub menu items hide the template for sub menu items and parse the menu item template
    $gui->set_template_properties( "_main_menu_sub_items", "visible", false );
  $gui->variables['menu_items'] = $item;
  $gui->parse_template( "_main_menu_items" );
}

...


set_template_properties

function set_template_properties( $name, $property, $value )

Parameters
nameName of template whose properties you wish to change.
propertyThe property to change.
valueThe new property value.

(version >0.2) Setting a template's properties affects its behaviour and how it is displayed (and whether or not it is even displayed at all). All template properties can also be set in the new command tag.
Available properties
visibleEither true or false. When false a template's cache is ignored and forced to NULL, effectively making it invisible. It will also not be parsed.

Example
See clear_template_cache


set_var

function set_var( $variable, $value )

Parameters
variableThe name of the variable to set.
valueThe new value of that variable.

(version >0.2) This is exactly like setting the variables manually using the class-wide variable "variables".


clear_vars

function clear_vars()

Parameters None

(version >0.2) Sets the "variables" class-wide variable to a blank array, effectively clearing all variables.


set_alias

function set_alias( $alias, $template_name )

Parameters
aliasTemporary new name of the template.
template_nameThe template to alias.

(version >0.2) Aliasing gives a template a new name. It can still be referred to by its old name, but at the same time it has a new name that it can be referred to as. Calling output_template and parse_template with the alias will also give the same results. All dependencies will also call the aliased template. Aliasing a template so it has the name of another template that already exists is allowed. The template that does exist will not be referred to as long as an alias exists with its name.

You can theoretically have an infinite number of template aliases.

Example See aliasing


clear_alias

function clear_alias( $alias )

Parameters
aliasExisting template alias.

(version >0.2) Rids a template of its alias. The template will no longer exist.

Warning: If a template expects a dependency to exist and it does not there will be a PHP error in the compiled template. Please be on the lookout for such problems.