====== 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 [[pattern: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 [[http://www.macromedia.com/software/dreamweaver/|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 [[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 [[class: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 [[class:Component]]), which you have access to via the [[class: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 [[Tag Developers Guide]]);
==== 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 [[class: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 [[class:Template]]::getChild() method).
They are the least common type of tag in WACT although examples include the [[tag:core:set|Core Set Tag]] (used to set the value of a variable reference so the value gets written into the compiled template);
and the [[tag:core:import|Core Import Tag]] (used to import a set of values to be written into the compiled template):
==== 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 [[tag:core:include|Core Include Tag]] (used to include one template in another, much like the PHP [[phpfn>include]] function):
[[tag:core:optional|Core Optional Tag]] and [[tag:core:default|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 [[class:DataSpace]]);
==== Server Component Tags ====
Server component tags **do** have a corresponding runtime component which you can interact with from your PHP script, via the [[class:Template]] API **and** they write into the compiled template.
They are the most common type of tag in WACT, examples include the [[tag:core:block|Core Block Tag]] (marks a section of the template which can be hidden or displayed dynamically at runtime):
and the [[tag:calendar:month|Calendar Month Tag]] (used to build a navigable calendar for a month)
Server tag component tags are a powerful feature in WACTs template engine, for example:
* ''
{$Title}
At runtime WACT will look for the a variable called 'Title' inside the template [[class: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 Reference]]s is the [[tag:core:dataspace|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// [[class:Data Space]] (the template [[class:Data Space]]) by replacing the $ context definiation in the variable reference with a # character. You access the //parent// [[class: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 [[Template Authors Guide]]
**Note**: you can also populate a variable reference at [[Compile Time]], using the [[tag:core:set|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;
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:
Select a Logo
The ''
// Load the template
$Page =& new Template('/logo.html');
// Is the logo variable set?
if (isset ($_GET['logo'])) {
// Get the
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 ''
But this will become a [[class:Generic Container Tag]];
In other words, although the normal rules of XML parsing regard '''' and '''' 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:
In other words all those '''' and '''' 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.
One thing to note here is the '''' 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 '''' tag e.g.:
The other approach is to explicitly disable specific tags by giving them the attribute //''runat="client"''// or nest it inside of [[tag:core:literal|Core Literal Tag]], for example:
===== 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:
Some text
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 [[class: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 Reference]]s 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 Tag]]s) 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 [[class:FormController]] and [[class:FormView]] classes. To support this, forms provide a further mechanism for "naming" tags, using the "name" attribute (typically used to identify an '''' 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 [[class: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:
===== Template Error Reporting =====
The template engine is "self aware" in that it knows how to spot violations of (most of) the [[template_synxtax|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 [[http://sourceforge.net/tracker/?func=browse&group_id=85372&atid=575984|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 ([[http://pear.php.net/XML_HTMLSax|XML_HTMLSax in fact]]), no error message being generated while wierd output is produced.
* Self defence - run your templates through an [[http://validator.w3.org/|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 =====
* [[Template Authors Guide]]