Recent changes RSS feed
 

WACT Template Syntax

The WACT template syntax uses XML markup to “extend” HTML (or whatever XML vocabulary you are using) with tags and attributes to allow declarative logic to be used in the template. Compared to more common styles of template engines implemented in PHP (see Template View), it can be a little confusing to begin with. However, once grasped, it provides a powerful mechanism for rendering content as well as clean separation between application and presentation logic.

Note: as far as is possible, the syntax has been designed to allow WACT templates to be edited in a WYSIWYG editor, such as Macromedia's DreamWeaver.

There are a number of key points which need to be understood when working with the WACT’s templates:

CompileTime vs. RunTime

WACT handles templates in two stages; a compiling stage (Compile Time) and an execution stage (Run Time) (see also WACT Template Component Architecture).

During the compiling stage, your template is parsed and a Compile Time Component Tree is constructed to represent it. In Compile Time Component Tree are objects (subclasses from Compiler Component) which write output into the compiled template. The compiled template is your WACT template compiled into a native PHP script, ready for execution.

During the execution stage, the compiled template is invoked and a lightweight (fast) runtime component tree is built (each component in the tree being a subclass of Component), which you have access to via the Template API, allowing you to control the runtime components.

Because the compiling stage is expensive, in terms of performance, you can disable it with the config.ini setting FORCECOMPILE = FALSE. Normally you will only use the compile stage when you are developing an application and the template is being modified. Once the application is “live”, the compiling stage should be disabled (the template is not changing), meaning only the fast, Run Time stage takes place.

Tag Types

There are four flavours of tag in WACT (see also Supported Tags and Define Tag Information);

Silent Compiler Directive Tags

Silent compiler directive tags provide instructions to the template engine, influencing template compile-time behaviour but without writing anything to the compiled template.

They also do not have a runtime component. That means when you load the template from your PHP script, via the Template class, there is no opportunity to interact with them - they do not exist at runtime and have no entry in the runtime component tree (you cannot find them with the Template::getChild() method).

They are the least common type of tag in WACT although examples include the Core Set Tag (used to set the value of a variable reference so the value gets written into the compiled template);

<core:set varname="value"/>

and the Core Import Tag (used to import a set of values to be written into the compiled template):

<core:import file="menu.vars"/>

Compiler Directive Tags

Like silent compiler directive tags, compiler directive tags do not have runtime components, but they do write into the compiled template.

Examples include the Core Include Tag (used to include one template in another, much like the PHP include function):

<core:include file="header.html">

Core Optional Tag and Core Default tags (used for an if/else type condition in the template, depending whether the variable names in the for attribute has been set in the DataSpace);

<core:optional for="authenticated">You are logged in</core:optional>
<core:default for="authenticated">You are not logged in</core:default>

Server Component Tags

Server component tags do have a corresponding runtime component which you can interact with from your PHP script, via the Template API and they write into the compiled template.

They are the most common type of tag in WACT, examples include the Core Block Tag (marks a section of the template which can be hidden or displayed dynamically at runtime):

<core:block hidden="true">This is invisible</core:block>

and the Calendar Month Tag (used to build a navigable calendar for a month)

<calendar:month/>

Server tag component tags are a powerful feature in WACTs template engine, for example:

  • <page:navigator /> tag generates navigation for paged result sets and can easily be attached to a <list:list /> tag.
  • <calendar:month /> tag builds a navigable HTML table to represent a calendar month, without you needing to worry about the HTML or the math working behind the scenes that calculates the calendar.

Server Data Component Tags

The Server Data Component Tag is an extension of the Server Component Tag and deals with connecting a WACT Data Source to a tag. Otherwise the same rules apply as with the Server Component Tag - there is corresponding runtime component and it writes into the compiled template.

Some examples of Server Data Component Tags are:

  • <list:list /> tag makes it very easy to loop through a Record Set and embed it in HTML.
  • <data:table /> tag allows you to generate instant HTML tables for a Record Set (without typing a single <td> tag)

Server Tag Component Tags

Server tag component tags are an extension of server component tags (they have a runtime component and they write into the compiled template) but the important difference is they also correspond to native tag names in the XML vocabulary you are using. For example the Select Tag corresponds to the HTML <select /> tag.

In other words server tag component tags allow behaviour to be added directly to an HTML tag in the template, on the server side, before the tags are sent to the browser. There are some special rules that need to be considered when dealing with Server Tag Component Tags, such as how to identify them to the template engine, which are explained below.

Widgets

Widgets are components that exist purely at Run Time and allow the output to be manipulated dynamically outside of the template engine. The template engine is unaware of their existence.

They are recommended only for special cases where additional ability to manipulate the output is required. Because they are generated at Run Time they have a greater overhead than Compile Time components.

Examples include Text Widget (used to insert plain text into the body of a Generic Container Tag), Tag Widget (used to add tag into the body of a Generic Container Tag, but the tag cannot have further widgets added to it (e.g. a <br />)) and Tag Container Widget (used to add tag with can have further widgets added to, into the body of a Generic Container Tag (e.g. a <div></div>)).

Tag Type Summary

Tag type Writes to Compiled Template? Runtime Component? Matches Real HTML Tags?
Silent Compiler Directive Tag No No No
Compiler Directive Tag Yes No No
Server Component Tag Yes Yes No
Server Data Component Tag Yes Yes No
Server Tag Component Tag Yes Yes Yes
Widgets No Yes Yes (your choice)

Expessions and Variable References

A Variable Reference is a placeholder to be filled by the value PHP variable at Run Time. It is a form of template expression in WACT. For a more detailed description of expressions, see the Output Expressions.

The basic syntax is:

<h1>{$Title}</h1>

At runtime WACT will look for the a variable called ‘Title’ inside the template Data Space where the Variable Reference was declared. To populate the above variable from your PHP script you might have:

$Page = & new Template('/index.html');
 
// Set the variable reference value
$Page->set('Title', 'This is the title of the page');

Variable references can be used for attributes as well, even for the value of an attibute in a WACT tag (but not in the ID attribute of a WACT tag - see below).

A special case for Variable References is the Core Data Space tag, which defines an internal scope for data inside the template. If you are using the CoreDataSpace tag, you can access the root Data Space (the template Data Space) by replacing the $ context definiation in the variable reference with a # character. You access the parent Data Space using a ^ character to the $ context definition e.g {$#variableName} or {$^variableName}.

Note: There is further syntax available which extends Variable References, described in the Output Expressions

Note: you can also populate a variable reference at Compile Time, using the Core Set Tag.

How does WACT identify Server Tag Component Tags?

To tell the WACT template engine that a native HTML tag should be made into Server Tag Component Tag, the attribute runat must be added to the tag in the template and given the value “server” for example;

<!-- This form is just plain HTML -->
<form id="MyFormA">
    <!-- ... -->
</form>
 
<!-- This form is a Server Tag Component Tag because it has the runat="server" attribute -->
<form id="MyFormB" runat="server">
    <!-- ... -->
</form>

Only the second form above will become a Server Tag Component Tag, the first being treated as plain HTML.

Generic Tags

Any HTML (or XML) tag in the template can be assigned a runat=”server” attribute and value allowing you to modify it’s attributes at Run Time and (depending on the tag) insert Widgets into the tag.

This provides you a mechanism to modify HTML without needing to embed imperative logic (if/else etc.) into the template. For example, in a template, you might have:

<img id="TheLogo" src="http://ch.php.net/images/php.gif" runat="server">
 
<h2>Select a Logo</h2>
<p><a href="?logo=php">PHP Logo</a> | <a href="?logo=mysql">MySQL Logo</a></p>

The <img> tag has been marked with a runat=”server” attribute, so the template engine makes it into a component.

Your PHP script, controlling this template, listens for the GET variable “logo” then modifies the src attribute of the above <img/> element like this:

// Load the template
$Page =& new Template('/logo.html');
 
// Is the logo variable set?
if (isset ($_GET['logo'])) {
 
    // Get the <img /> component
    $Img =& $Page->getChild('TheLogo');
 
    // Modify the src attribte, depending on the value of $_GET['logo']
    switch (strtolower($_GET['logo'])) {
        case 'php':
            $Img->setAttribute('src','http://ch.php.net/images/php.gif');
        break;
        case 'mysql':
            $Img->setAttribute('src','http://www.mysql.com/images/poweredbymysql-125.png');
        break;
    }
}

So the <img /> tag can be dynamically modified at runtime.

Types of Generic Tag

There are two types of generic tag, defined by the classes Generic Tag and Generic Container Tag. The second, Generic Container Tag, can have Widgets added to it, as well as having it’s attributes modified at Run Time. Instances of Generic Tag can only have their attributes modified.

The template engine decides which type of generic tag to use depending on how you declare the tag in the template. For example these three will all be turned into a Generic Tag;

<div runat="server" />
 
<br runat="server">
 
<br runat="server" />

But this will become a Generic Container Tag;

<div runat="server"></div>

In other words, although the normal rules of XML parsing regard <div runat=”server” /> and <div runat=”server”></div> to be the same thing, the WACT template engine regards the second as a tag you want to insert Widgets into.

Inheritance of runat="server"

For Server Tag Component Tag‘s which have a well defined set of children which may also need to become components, WACT supports automatically registering the children. This is currently used only for the form tags.

For example, imagine a form and it’s children components:

<form id="MyForm" runat="server">
 
<label for="name" runat="server">Name:</label> <input type="text" value="name" runat="server">
<br>
 
<label for="email" runat="server">Email:</label> <input type="text" value="email" runat="server">
<br>
 
<input type="submit">
 
</form>

In other words all those <label /> and <input type=”text” /> tags have to be explicitly declared as components using runat=”server”. This can be a headache to type, and is especially problematic when working with a WYSIWYG HTML editor.

To prevent you needing to do this the template engine will normally automatically register all the known children of the form tag, which are commonly used in forms, as runtime components. In other words, by default, the tags which typically appear inside a form tag inherit the parent runat=”server” attribute.

<form id="MyForm" runat="server">
 
<label for="name">Name:</label> <input type="text" value="name">
<br />
 
<label for="email">Email:</label> <input type="text" value="email">
<br />
 
<input type="submit">
 
</form>

One thing to note here is the <input type=”submit”> will now also be registered as a runtime component so be warned - you may get more than you were expecting.

There are two ways to prevent inheritance of the runat=”server” attribute. It can be switched off completely by placing a useknown=”false” attribute in the <form /> tag e.g.:

<form id="MyForm" runat="server" useknown="false">
 
<!-- None of the following tags will be registered as components -->
 
<label for="name">Name:</label> <input type="text" value="name">
<br>
 
<label for=\"email\">Email:</label> <input type=\"text\" value=\"email\">
<br>
 
<input type="submit">
 
</form>

The other approach is to explicitly disable specific tags by giving them the attribute runat=”client” or nest it inside of Core Literal Tag, for example:

<form id="MyForm" runat="server">
 
<!-- Labels and Text Inputs will automatically be components -->
<label for="name">Name:</label> <input type="text" value="name">
<br>
<label for="email">Email:</label> <input type="text" value="email">
<br>
 
<!-- This will not become a component -->
<input type="submit" runat="client">
 
<!-- This will not become a component -->
<core:literal>
<input type="reset">
</core:literal>
 
</form>

Identifying Components at Run Time

If you place WACT tags into your template, how to you find them at runtime, from your PHP script?

WACT tags are identified (uniquely) by the ID attribute. The template engine checks for duplicate IDs and will raise an error if it finds one. For example:

<div id="MyBlock" runat="server">
Some text
</div>

PHP Script:

$Page =& new Template('/index.html');
 
// Get the DIV tag
$Div =& $Page->getChild('MyBlock');
 
// Do something to it
$Div->setAttribute('style', 'background-color: red');

The ID attribute above will also appear in the output HTML, so you can use it with CSS.

You are not required to give a WACT tag an ID attibute (perhaps you don’t need to access it directly at runtime) and if not defined, WACT will generate an ID for it (beginning “id000...”) - note that generated ID’s will not be displayed in the output HTML.

The Template API also allows you to find components by their Run Time PHP class name and will return the first component it finds of that class.

Note: Do not put Variable References in the ID attribute of a WACT tag. Right now this is not supported and does wierd things to the template. You can put a Variable Reference into an ID attribute of a plain HTML tag though.

Note: A further additional attribute called “wact:id” is planned to allow the optional ability to clearly distinguish between the HTML id attibute used for CSS and the unique name WACT needs to identify components.

HTML Form Tags

HTML Form tags, (which are Server Tag Component Tags) are a special case which needs some consideration.

Because forms in HTML play an important part in PHP applications, WACT implements them as components that are ready to be used with WACT’s FormController and FormView classes. To support this, forms provide a further mechanism for “naming” tags, using the “name” attribute (typically used to identify an <input/> tag for example).

The following rules are applied by WACT to determine what value identifies the tag, which is what you will need to use if you want to find the component with Template::getChild():

  • If the ID attribute exists, this will identify the tag (the “name” attribute is ignored)
  • If the ID attribute does not exist but the \”name\” attribute does, “name” will identify the tag
  • If neither exist, WACT will generate an ID

For example:

<form id="MyForm" runat="server">
 
   <!-- the unique identifier is "Input1" -->
   <input type="text" id="Input1" name="foo">
 
   <!-- the unique identifier is "bar" -->
   <input type="text" name="bar">
 
   <!-- the unique identifier is generated -->
   <input type="text">
</form>

Template Error Reporting

The template engine is “self aware” in that it knows how to spot violations of (most of) the syntax rules of WACTs markup. For example if you assign the same ID to more than one WACT tag (plain HTML tags ignored), you will get a duplicate ID error as well as the file and line number where the duplicate tag was found. Different rules apply to different tags but another common error will be failing to close a tag which must be closed.

Some syntax errors will be harder to track down - WACT can only report the error at the point where it found it but you should at least know in which template file the error occured and what type of error you are looking for.

Template Debugging

There are three tags currently available to help with debugging templates;

  • DevSourceTag - allows you to view a section of the compiled template file (this is mainly for tag development)
  • DevTreeTag - allows you to view the compile time component tree so you can see which tags have been registered (again mainly for tag development)
  • DevDataSpaceTag - allows you to see the variables residing in the dataspace where this tag was placed. Useful for examining the contents of a form component, for example.

More such functionality is planned, such as tracing and profiling.

One further tag, along this lines, is the DataDumpTag, which allows you to dump a RecordSet (e.g. database query result or ArrayDataSet) into the template output.

Known Template Quirks

Generally the template engine is fairly robust and stable although there are some outstanding issues. For the most up to date information, see the Template Component bug list as well as the “Template Group” unit tests.

  • Badly formed HTML - some instances of badly formed HTML will trip the parser (XML_HTMLSax in fact), no error message being generated while wierd output is produced.
    • Self defence - run your templates through an HTML validator. See the Template Group unit tests for details.
  • Variable references in the id attribute of WACT components. Varying wierd behaviour depending on the tag. ←- I think variable references in “compile-time attributes” are not (yet?) supported.

Additional Information

 
wact/template_syntax.txt · Last modified: 2006/12/09 17:16
 
Hosting for this site donated by Procata PHP Development