Sitellite Design Templates
Chapter 7: XT Tips & Caveats
XT is a full-blown template language, and as such, learning XT is like learning a new language. With any new language there are quirks and things that seem odd when coming from another language, which might have a different way of doing things. The following is an in-depth overview of the most common quirks people encounter when first working with XT, including examples and solutions to problems that they can create for template designers.
The Basics: HTML Versus XML
For those of you familiar with XHTML (the future of HTML), you will already have some idea what this means, although there are many additional bits of information in this article that will still be relevant to you.
For those of you with no idea what I'm talking about, XHTML is HTML with a few new rules, so that it qualifies as a valid XML document. It's HTML written in XML. But it's pretty easy to get used to. XT doesn't even require that you obey most of the new XHTML rules, just the syntax-oriented ones. However, we encourage you to follow the whole spec, since there are many benefits (that are outside of the scope of this article) for doing so.
Here are the relevant changes from HTML to XHTML:
1. Tags that don't have matching closing tags need to be "self-closing". For example:
<img src="lux.jpg">
becomes:
<img src="lux.jpg" />
The difference is a space and then a forward-slash before the closing angle bracket. The space is optional in XML, but is a little trick that fools older browsers into rendering XHTML as if it was ordinary HTML.
The tags that this applies to in the HTML spec include:
- <area />
- <base />
- <br />
- <button />
- <hr />
- <img />
- <input />
- <link />
- <meta />
- And a few others you probably shouldn't be using anyway (they're deprecated and/or no longer in the XHTML specification, or I may have simply forgotten them).
The tags <option>, <li>, and <p>, that are commonly left open are actually supposed to have closing tags (ie. <li>List Item</li>).
Note for you XHTML/standards gurus: I didn't mention the alt attribute because it's not a syntax change, it's an accessibility change. Since this is not a lesson in XHTML, but a quick "HTML versus XML" comparison, I'm going to avoid those. But I do recognize their importance.
2. Tags must close in reverse order
If you've opened an <em> tag after a <strong> tag, then technically the <em> tag is considered to be inside of the <strong> tag. As a result, the <em> tag should be closed before the <strong> tag is, so that the integrity of the document structure is maintained. This makes it possible for the document parser to be certain of which </em> belongs to which <em> at all times. XML, and consequently XT, requires this unambiguity.
3. Leave a space between empty tags
You might notice that your named anchor tags aren't working out for you, and wonder why. Well, because XT can't tell the difference between:
<a name="top"></a>
And:
<a name="top" />
This is another less pleasant quirk of the xml_parse_into_struct() function. How we solve this is by adding a single space between the empty tags, which is enough to tell XT that our tags are of the former kind, not the latter. For example:
<a name="top"> </a>
4. Tags should, but don't have to be, lowercase
This isn't necessary for XT, but it is a syntactic part of the XHTML specification, and it's good advice to help save your shift-finger. Stop writing <HEAD> and start writing <head> instead. Much nicer. Takes some getting used to at first. Well worth the effort, believe me.
For more info about XHTML, see:
Comments
Comment tags in XT are stripped out, due to the way PHP's xml_parse_into_struct() function works (ie. it doesn't provide the ability to specify handlers for comments, among several other components of the document, including doctypes and xml declarations). Unofficially, we've taken the perspective that this is a feature, not a bug (only in the case of the comments, the others: clear and present bug), because it allows you to have comments in your templates that are hidden from the final user output.
However, this is a pretty moot point, since unless you turn it off via htaccess or your Apache configuration, users can access the source of your templates directly in the browser, and read these comments anyway. So don't put any passwords in there, please (do people still do this?).
Comments that you want remain in the final output of the template can be made using the following syntax:
<xt:comment>This is a comment.</xt:comment>
This will become
<!-- This is a comment. -->
in the resulting web page.
However, there's a problem with this approach: It's in clear violation of the preview capabilities of XT templates, since the comment text would be rendered as if it were web page content in the preview. To solve this, you can either insert a style="display: none" attribute into the comment tag itself, like this:
<xt:comment style="display: none">This is a comment.</xt:comment>
Or if the browser you're using to preview the templates supports the following CSS trickery, you can include this rule in your CSS file:
xt\:comment { display: none;} I should also note that <xt:note> is an alias for <xt:comment>. They're interchangeable, but you'll need to adjust the CSS rule if you're going to use both (or one instead of the other):
xt\:comment, xt\:note { display: none;} A workaround for browsers that don't support the xt\:comment CSS syntax is to rename the tags <xt-comment> and <xt-note>, and to refer to xt-comment and xt-note in your CSS instead. To the XT rendering engine, these are the same thing, and you can do this with all the tags if you like.
For more info about CSS, see:
Entities: Breakin' the law
If you've inserted a or any other HTML entity into your XT templates, you've discovered that it results in a nice "Illegal entity" error. This is because XT templates are XML documents, not HTML documents, and XML parsers know nothing about the special entities defined in the HTML specification.
The XML specification offers an alternative, which is not a very pleasant one, to this problem: Using XML entities to refer to the actual character number of the entity you desire.
XT relies on an alternative specification for its solution, which can be found here:
http://xmlchar.sourceforge.net/
In XT, to insert a non-breaking space into a template, you can say:
<ch:nbsp />
XT will translate this into an ordinary in the final web page output.
There is a limitation to this solution however, which is not present in the solution: <ch:nbsp /> will not render as a space in your template preview, while will. To solve this, we can use some more CSS trickery, either as a style attribute of each tag:
<ch:nbsp style="padding: .5em" />
Or in our global stylesheet:
ch\:nbsp { padding: .5em;} Of course, this only solves it for the <ch:nbsp /> case, but it is the most common case, and it's a good start. Others, if necessary, can most likely be solved with a little extra CSS ingenuity.
For a full list of HTML character entities, see:
Javascript
If you've been doing a lot of Javascript work in an XT template, you've probably run into one of these.
The first is related to the comment tag. Insert the following into your template and view it both directly (preview) and rendered in Sitellite:
<script language="javascript" type="text/javascript">
alert ("Hello World!");
</script>
Works fine. Now add comments like they suggest you should for complex Javascript:
<script language="javascript" type="text/javascript">
<!--
alert ("Hello World!");
// -->
</script>
Works fine in the preview, but it does nothing in Sitellite. View the source in Sitellite and you'll see an empty set of <script> tags. That's because the comment tags are stripped out. The solution, however, is not to simply omit the comment wrapper. The following example illustrates why:
<script language="javascript" type="text/javascript">
<!--
msg = "";
for (i = 0; i < 10; i++) {
msg += i;
}
alert (msg);
// -->
</script>
Again, works fine in the preview. Now take out the comments, which should fix it in Sitellite as well, right?
<script language="javascript" type="text/javascript">
msg = "";
for (i = 0; i < 10; i++) {
msg += i;
}
alert (msg);
</script>
Fortunately, there are several possible solutions to this problem. The first takes some getting used to, but works for all browsers, and doesn't require modifying all of your Javascript code. This is to use character data (or CDATA) tags, which allows < and & characters all you like. For example:
<script language="javascript" type="text/javascript">
//<![CDATA[
msg = "";
for (i = 0; i < 10; i++) {
msg += i;
}
alert (msg);
//]]>
</script>
Notice that I've commented out the CDATA tags with Javascript comments (//), so that to the browser in preview mode, they're ordinary comments, and to the browser after the template is rendered, they're ordinary comments as well (but blank, since the CDATA tags are simply used to preserve their contents through the XT rendering process, and afterwards are removed). As always, to see the output for yourself, View > Source, my friend.
The second solution is the one I prefer (and actually, I'll be mentioning a third, but it only applies to app developers). That is to save your Javascript as an external .js file, either in the js/ folder, in your app's folder, or in your template set itself (under a js/ subfolder), depending on how far-reaching it is (ie. a rendering trick for your template would go in inc/html/yourtemplates/yourscript.js). This makes your Javascript cacheable by the browser, which will increase the loading speed of your web site (bonus!), and will also encourage you to make your Javascript more reusable as well.
However, this brings up another quirk folks run into on occasion in XT, which is described in the 3rd point under "The Basics: HTML Versus XML" above: References to external scripts usually appear like this:
<script src="/js/myscripts.js"></script>
XT turns this into:
<script src="/js/myscripts.js" />
in the final output, which most browsers don't like. There is a simple solution to this (described earlier): Add a space. For example:
<script src="/js/myscripts.js"> </script>
XT will now include your external Javascript file no problem.
For more info:
http://devedge.netscape.com/viewsource/2003/xhtml-style-script/
Doctype
In addition to the comment tags, doctype declarations are stripped away during the XT template rendering. To compensate for this, we've added a special doctype tag, which can be used as follows.
The doctype:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "DTD/xhtml1-transitional.dtd">
Can be represented by:
<xt:doctype root="html" access="public" name="-//W3C//DTD XHTML 1.0 Transitional//EN" uri="DTD/xhtml1-transitional.dtd" />
Make sure however that the <xt:doctype> tag begins on the first line of the document. So an example document might be:
<xt:tpl version="1.0"><xt:doctype root="html" access="public" name="-//W3C//DTD XHTML 1.0 Transitional//EN" uri="DTD/xhtml1-transitional.dtd" /> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Page Title</title> </head> <body> <h1>Page Title</h1> <p>Page Content</p> </body> </html> </xt:tpl>
One problem with this is that the doctype declaration isn't present in the template preview, which can cause rendering issues with certain markup techniques in MSIE, which renders more strictly when a doctype is present. To solve this, we can use the fact that the original doctype is stripped out to place both in the template, and end up with a single doctype declaration in each output method (preview and in Sitellite). So our template header becomes:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "DTD/xhtml1-transitional.dtd"> <xt:tpl version="1.0"><xt:doctype root="html" access="public" name="-//W3C//DTD XHTML 1.0 Transitional//EN" uri="DTD/xhtml1-transitional.dtd" /> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Page Title</title> </head> <body> <h1>Page Title</h1> <p>Page Content</p> </body> </html> </xt:tpl>
XML Declarations
As you might guess from the doctype discussion above, I'm about to introduce a tag to render XML declarations. This tag works as follows:
<xt:xmldecl version="1.0" encoding="utf-8" />
Becomes:
<?xml version="1.0" encoding="utf-8"?>
The attributes of this tag are the same as for the standard XML declaration itself, so there's nothing new to remember. I'll also briefly introduce one more related tag:
<xt:xmlstyle type="text/css" href="mystylesheet.css" />
This creates an XML stylesheet declaration, which renders as:
<?xml-stylesheet type="text/css" href="mystylesheet.css"?>
Outputting PHP
This won't be the most frequently used feature, but in some cases it can be quite handy. I'll start out with an example, then I'll explain my way through it:
<xt:code><![CDATA[ echo 'hello<br />'; ]]></xt:code>
The <xt:code> tag tells XT to wrap the enclosed content in the language identifiers of your choice (the default is PHP). The CDATA tags are in case you have any "illegal entities" in your source code (namely, < and &), as does the above example since it prints a <br /> tag. The output of this code would simply be:
<?php echo 'hello<br />'; ?>
Pretty straight-forward. The previewability of this solution is also intact, since the CDATA block doesn't display in the browser, so your code remains invisible when previewing the template.
The nice thing about this feature is that, coupled with my article on publishing a static web site from Sitellite, you can use this to publish semi-dynamic web sites that are completely devorced from Sitellite itself (leaving the Sitellite-powered site as a staging area), as well. Couple this with some simple rsync-based mirroring and perhaps a little cron, and you've got a full-fledged language-agnostic content publishing solution.
Of course, you'll want to make sure your staging area is blocked off from public access, or people will be able to see your source code by viewing the source of your templates. You could do this either by firewalling it off entirely, or using SSL and HTTP basic authentication to access the staging site.
In the reference chapter of this lesson, you will find the list of supported languages.In conclusion, I hope this helps make you a more empowered XT template designer, or at least helps clear up some of the less apparent aspects of the language.
Troubleshooting
Sometimes you might get stuck on an XTE expression and you'll want to see exactly what a path object contains or some PHP code returns. In this case, the <xt:exec> command is your best friend. To find the value of the cgi/test path, the following would work:
<xt:exec value="php: print_r (cgi.test)" />
This will print the value immediately to the browser, and not append it to the XT output. For silent debugging, you might create a function that logs such values to a file. In this case you could simply replace the print_r() call with the name of your custom logging function. For example:
<xt:box
name="cms/services/log"
transition="cgi/test"
message="${cgi/test}"
/>




Charles Brunet