Contemplate™ Web Templating System  


Latest release

Contemplate 2.0.2
16 Nov 2011
download now!


A template is simply an HTML file with embed tags added to it in the places where you want content to appear. You can use a few different kinds of embed tags for different purposes:

Standard tags

<!--#embed left_column -->
The most common type of embed tag simply says, "Place the piece of content named xxx here." For example, if Contemplate finds the tag <!--#embed left_column --> in your template and the argument left_column=field,main.html,contact_us in your page definition, it will merge the contact_us field from the main.html file into the template file in place of the left_column embed tag.

Hard-coded tags

<!--#embed args=file,header.html -->
If you have an embed tag in a template that will always receive the same piece of content, you can simplify your page definitions by including a reference to that content directly in the embed tag. For example, rather than using the embed tag <!--#embed header --> and including header=file,header.html in your page definition, you can just use the embed tag <!--#embed args=file,header.html -->. We call this a hard-coded tag because you can't pass values for this tag into the template; but you can still benefit from keeping your content in a separate file from your page layout.

Passthru tags

<!--#embed highlight[0] -->
When Contemplate processes a passthru tag, it doesn't go looking for content to display in its place; instead, it simply displays some portion of the page definition. For example, if Contemplate finds the tag <!--#embed highlight[0] --> in your template and the argument highlight=contact_us in your page definition, it will display the text "contact_us" in place of the highlight[0] embed tag.

Passthru tags always include square brackets after the name; this distinguishes them from standard embed tags, and also allows you to access specific elements of a page definition. For example, the tag <!--#embed left_column[1] --> accesses the string "main.html" from the page definition left_column=field,main.html,contact_us. This can be especially useful when adding logic to your templates using client-side or server-side scripts. For example, you could write a PHP script that contains the line $content_file = "<!--#embed left_column[1] -->" and then make the script behave differently depending on what content file the page is reading from.

In addition to accessing every element of the page definition, you can also access the special variables page[0] (the name of the current page), template[0] (the value of the template argument), and page_definition[0] (the complete page definition of the current page). And if you use the "split page names on" preference, you can access specific portions of the page name by setting an index for the page variable. For example, on a page named company_contact with "split page names on: _" in your preferences file, page[1] will return "contact."

If you don't include an index inside the square brackets, Contemplate will return the entire argument or page name. For example, if your page definition includes the argument home=field,main.html,home, then main[2] would return "home" but main[] would return "field,main.html,home." Similarly, if you're splitting page names and accessing individual portions of the page name, you can still access the entire page name with page[].

Combo tags

<!--#embed args=field,lesson+lesson[0],exercise -->
A combo tag is some combination of a hard-coded and passthru tag. This is useful if most of the arguments are the same across multiple page definitions, but they're not all the same. For example, you might be using the embed tags <!--#embed exercise -->, <!--#embed instructions -->, and <!--#embed tips -->, and the page arguments excersise=field,lesson1,exercise&instructions=field,lesson1,instructions&tips=field,lesson1,tips. You could rewrite this to use the embed tags <!--#embed args=field,lesson+lesson[0],exercise -->, <!--#embed args=field,lesson+lesson[0],instructions -->, and <!--#embed args=field,lesson+lesson[0],tips -->, and the page argument lesson=1.

Specifically, a combo tag looks like a hard-coded tag, but you can insert the same values you would use in a passthru tag anywhere in the list of arguments, concatenating with the + sign as needed. Combo tags don't let you do anything that you can't do with the other kinds of tags, but they do let you write simpler page definitions that are easier to read and maintain.

Navigation tags

<!--#embed nav_previous -->, <!--#embed nav_next -->, etc.
If you want to build Next and Previous buttons to page through your site, you can automate this development using Contemplate's navigation tags. For example, if your page definitions file includes these definitions...

home: template=home.html&main=field,main.html,home

joe: template=people.html&main=field,people.html,joe
bob: template=people.html&main=field,people.html,bob
sally: template=people.html&main=field,people.html,sally
sue: template=people.html&main=field,people.html,sue

site_map: template=other.html&main=field,main.html,map

...and you place navigation tags into your template, they would display as follows on various pages:

  page=joe page=bob page=sally page=sue
<!--#embed nav_current --> 1 2 3 4
<!--#embed nav_total --> 4 4 4 4
<!--#embed nav_next --> bob sally sue joe
<!--#embed nav_previous --> sue joe bob sally
<!--#embed nav_first --> joe joe joe joe
<!--#embed nav_last --> sue sue sue sue

This makes it very easy to build links and counters that automatically update when you add or rearrange pages in your page definitions file. Here's some example HTML that demonstrates this functionality:

<a href=../contemplate/assembler.php?page=<!--#embed nav_previous -->>Previous</a> |
<!--#embed nav_current --> of <!--#embed nav_total --> |
<a href=../contemplate/assembler.php?page=<!--#embed nav_next -->>Next</a>

Note that when processing navigation tags, Contemplate assumes that double line breaks in the page definitions file indicate a group of pages, and only considers the other pages in the same group as the current page.

Navigation tags don't require any arguments in your page definition. They do, however, require the use of a page definitions file rather than passing page definitions through the query string.

Conditional tags

<!--#if (left_column[2] != "home") -->, <!--#else -->, <!--#end if -->
If you want to use one template rather than two in cases where both templates are only slightly different, you could add logic to your template using client-side or server-side scripting to make it display differently in different circumstances. Or, you can use Contemplate's built-in conditional functionality to "show" or "hide" different portions of your template. The advantages of using Contemplate's conditional tags are that they're language-neutral and don't have to be rewritten if you move your site to a different platform, they run faster since Contemplate will completely eliminate the portions of the template you don't need when it assembles your page, and they allow easy access to portions of your page definition for making decisions based on those values.

Conditional tags can contain the same kind of references that you would include in a passthru tag, as in this example:

<!--#if (left_column[2] != "home") -->
<a href=home.html>Home</a>
<!--#else -->
<!--#end if -->

They can also include any code that's compatible with the scripting language of the version of Contemplate you're using. For example, if you're using the PHP version of Contemplate, you could write a conditional tag that uses the strpos() function, as in this example:

<!--#if (strpos(left_column[1], "corporate/") !== false) -->
We're reading a content file from the content/corporate folder.
<!--#end if -->

However, including portions of the host scripting language means that you would have to rewrite those portions if you move your site to a different platform and change the version of Contemplate you're using.

As of version 1.0.3, conditional tags can even contain the names of the nav_* and env_* tags. For example, you could choose to display some content if the current page is the last in a group:

<!--#if (page[0] == nav_last) -->
Sorry, there are no more pages after this one!
<!--#end if -->

Or you could display some content if the page was modified today (this example uses the PHP strpos and date functions):

<!--#if (strpos(env_last_modified, date("Y-m-d") == 0) -->
Hey, this page is brand new!
<!--#end if -->

Environment tags

<!--#embed env_http_user_agent -->, <!--#embed env_remote_addr -->, etc.
Finally, you can display environment variables on your pages by including environment tags in your templates. The value of an environment tag is "env_" plus the name of the environment variable you wish to access, and is not case-sensitive. One additional environment variable is unique to Contemplate: <!--#embed env_last_modified --> will display the modification date of the newest of all the files used to build the page -- effectively, the modification date of the dynamic page.

Tag attributes

With standard, hard-coded, and passthru tags, you can also include a few different attributes to modify the display of the embedded content:


<!--#embed main strip -->
If you include the strip attribute in your embed tag, Contemplate will strip all HTML tags from the embedded content before merging it into the template. This is a good way to clean up content if you need to override its formatting in your template, or embed it into a JavaScript variable.


<!--#embed main replace /[\r\n]// -->
You can take even more control of the formatting of embedded content by running regular expression replacements on it. The example above removes all line breaks, which is also useful when embedding content into a script. You can include both the strip and replace attributes in a single embed tag, and you can list several replace attributes, each with its own regular expression values. Regular expressions are Perl-compatible and use the $n syntax for backreferences.


<!--#embed main variable -->
If you want to embed content into a template but process the content using your own server-side scripts before displaying it, you can include the variable attribute in your embed tag. In this case, Contemplate finds your requested content, but rather than merging it into the template, creates a variable that you can access from scripts written in the same language as the version of Contemplate you're using. For example, if you're using the PHP version of Contemplate and you include the embed tag above, any PHP scripts in your template or content files can automatically access the embedded content through the $main variable. Note that it's then up to you to eventually print the content when you're finished working with it. Also note, if you use the variable attribute in a hard-coded tag, the content will be available in a variable called $hardcoded. If you use the variable attribute in more than one hard-coded tag, the content will be available in a series of variables called $hardcoded_1, $hardcoded_2 and so on.

show_errors, hide_errors

<!--#embed main show_errors -->, <!--#embed main hide_errors -->
These attributes override the SHOW_ERRORS setting in config/constants.php for a single tag. This is useful, for example, if you want to place a tag into some PHP code where the error message formatting would cause problems. With errors hidden, Contemplate will still output a simple message wrapped in HTML comment tags, but with no formatting.


Contemplate is developed by Arlo Leach.