Recently, I've been faced with the task of building a template engine for Active Server Pages. The purpose of this is to add the ability to customize the
ASP Nuke content manager. In this article, I will discuss the components of a template engine and how we can develop them in Active Server Pages.
Components of a Template System
Before I got started on this task, I first had to identify the major components of a content management system. These will largely dictate how the template engine would be designed and built. Although every template manager is built differently, they usually share these common components:
- Cascading Style Sheets
- HTML templates
- Object-Oriented
1. Cascading Style Sheets
Cascading Style Sheets or CSS were originally invented to separate the appearance of a web page from it's layout. Using CSS, we can define font styles, element margins and alignments and the colors and images used throughout the site. They provide a powerful mechanism for changing the entire look of your site.
By simply swapping out one stylesheet for another, you can completely change the look and feel of your site. If you need more evidence of this, just check out CSS Zen Garden. You could even go so far as to dictate the layout of your site using CSS (as all of the examples on the aforementioned site do), but that's a bit of overkill.
Ideally, the best solution is to use HTML for layout and structure and combining that with a stylesheet to dictate appearance. By layout here, we are talking about positioning block elements on the page. If you are familiar with HTML, the best equivalent would be the TABLE element. By creating tables which are nested inside other tables, we can create very complex page layouts.
2. HTML Templates
As you know, our goal here is to create a template engine that incorporates both ASP code and HTML markup. To merge the two, either the HTML markup has to reference the ASP code or the ASP code has to reference the HTML markup.
The solution is to embed macros within the HTML markup that the ASP template engine can parse and substitute dynamic content. By dynamic content, we mean content that is generated from ASP program code and may or may not include database content.
Ideally, the macros should follow the same syntax that HTML markup does to make it as easy as possible for the designer of the templates. This makes good sense because most good web page editors will ignore unrecognized tags in the markup. We could use these extensions to the HTML language to insert program code:
<template name="article">
<p><template name="articletitle" /><br />
<template name="articleauthor" />
<template name="articlebody" />
</template>
But what if we wanted to use standard HTML elements to place inside the template? The one tag that we may use anywhere within an HTML page is the comment tag. Utilizing this, we could reference dynamic ASP content like this:
<!--articlelist-->
<p><!--articletitle--><br />
<!--articleauthor-->
<!--articlebody-->
<!--/article-->
The one problem with this design is that when you preview the page using a design tool, there will be no sample content available to test with. This really becomes a problem with the repeating elements (such as the articlelist) where you need to see the same block of content shown repeatedly.
Another problem we need to tackle, is not just including ASP code using a macro, but including another HTML markup file using a macro. The HTML markup file can be another template or just a static HTML file. This can easily be solved by creating ASP program code to process the template.
3. Object-Oriented
In a complex website application such as a content management system, there are many different applications which plug into the system. Each of these applications may have the need to create their own styles for elements which are unique to the application. For instance, a message forum may have special styles for comment, post and reply links. The same can be said for the HTML templates which are used to build module-specific elements.
What we would like to have is a hierarchical list of elements. Each one inheriting its appearance from a parent element. For instance, a "forum listing table" could inherit from a "theme report table". Using this scheme, even if a module-specific element doesn't have a custom theme, the element will still inherit from the parent.
Summary
You can see from the components described above how we can neatly separate the three major components of a template engine. It's very similar to how you would create a three-tiered architecture for a website project. Although creating a templated system such as this involves a lot of work, the benefits outweight the negatives.
Using this sytstem we can easily seperate the presentation layer from the business logic. Unfortunately, there are not many (if any at all) IDEs that will support efficient development of an Active Server Pages template system such as this. Many people will point out that ASP.Net has already solved this problem and efficiently separates these two layers for us. This is true, and if you are so inclined, you may choose to develop using ASP.Net.