Main
Download
Guide
FAQ
Contact
Other projects
- Spawn SQL
Wishlist/Bugs
Home
|
Note: This website has moved to mikealeonetti.com.
Chip Reference Guide
- Overview
- Installation and set-up
- Template file structure
- Variable usage
- Template aliasing
- Parsing directives
- new - Create a new template
- link - Link an already created template
- include - Include another file containing templates
- if - The conditional flow control directive
- elseif
- else
- set - Set a variable
- foreach - Loop an array
- copy - Duplicate already made templates
- Template control functions
- parse_file - Parse a file
- parse_template - Execute a template's instructions
- output_template - Print a template
- clear_template_cache - Reset a template's cache to NULL
- set_template_properties - Sets the properties of a template.
- set_var - Alternative syntax to referencing variables directly.
- clear_vars
- set_alias - Alias a template.
- 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
| name | The 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
| name | The 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
| src | The 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
| exp | The 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
| exp | The 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
| variable | The 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
| array | The name of the array. |
| value | Variable 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
| tmp | The name of the template to duplicate. |
| name | New 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
| fileshell | Name 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
| name | Name 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
| a | Default. Append the output to the end of the template cache. |
| i | Insert the output in the beginning of the template cache. |
| w | Overwrite 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
| name | Name 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
| name | Name 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
| name | Name of template whose properties you wish to change. |
| property | The property to change. |
| value | The 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
| visible | Either 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
| variable | The name of the variable to set. |
| value | The 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
| alias | Temporary new name of the template. |
| template_name | The 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
| alias | Existing 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.
|