Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Separate Code and Style with ASPTemplate

0.00/5 (No votes)
26 Mar 2002 1  
How to separate code and style using ASP templates

Background

Recently I've been forced to write a lot of fairly complex ASP code to interact with a database and present stuff on a nicely formatted web page. As you all know it is no fun working with HTML and ASP code jumbled together in a single file. Once you have to either change the code logic or redo the layout it is even less fun. So I went searching for some solution to this problem.

I found a bunch of different systems, both free and commercial, but none that did precisely what I wanted, so I decided to roll my own template processor. And with the help of the RegEx object available in IIS 5.0 or better, this is what I came up with:

Details

The guy that runs the show is a VBScript class called ASPTemplate. From now on you'll use two files for each web page: One that contains only code, and one that is pure HTML.

The ASPTemplate class exposes two mechanisms you'll use to enter dynamic data in the HTML template: Slots and Blocks.

A Slot is a property and works just like a variable that renders the value you assign to it in the ASP file. You put a slot name between double braces (like this {{Name}}) when you use them in the HTML template.

A Block is a piece of HTML that can be shown or hidden from the ASP code using the ShowBlock method. What makes Blocks truly useful is that they can be repeted using the RepeatBlock method. Whenever you call this method the block contents is repeated using the slot values that are current at that moment. In this way you can fill a table with database information easily and conveniently.

But wait, there is more! Blocks can also be nested to an arbitrary depth (though the processing time tends to increase a lot when you nest deeply), allowing you to create very complex structures with a minimum of code.

How to use ASPTemplate

A little example will probably make this clear. As stated above, you'll use two files for each page. Here is the first one:

File Test.asp

This is the code file, or the driver file if you like. As you can see, the first thing to do is to include the ASPTemplate.asp file and create an instance of the ASPTemplate object. We then tell the object what HTML template to use. In this case it is loaded from the default directory Templates/. You can change this with the TemplateDir property if you like.

The rest is just to fill the nested structures with some varying data so you can see it actually does something. Note that you can control the Blocks One and Two with QueryString parameters like so: test.asp?Block=One.

All Blocks are hidden by default and shown with ShowBlock or RepeatBlock. The call to ClearBlock before the loop that fills a nested block is needed to remove the contents from the previous loop.

<!--#include file="ASPTemplate.asp" -->
<script language="VBScript" runat="Server">
  dim t : set t = new ASPTemplate
  
  t.Debug = false ' Set to true if you want to keep uninstantiated slots as text

  t.Template = "test.html"

  t.Slot("Title") = "This is a test"
  t.Slot("Now") = Now()
  t.Slot("Title") = t.Slot("Title") + " - and some more"
  t.Slot("Test") = "Test text"

  ' Some random calculations to make up our test data

  for i = 1 to 8
    t.Slot("Cell1") = i
    if t.Slot("Cell1") > 5 then t.Slot("Test") = t.Slot("Test") + " ..."
    t.ClearBlock "Block1"
    for j = 1 to i
      t.Slot("Cell2") = i*j
      t.ClearBlock "Block2"
      for k = 1 to i-j+1
        t.ClearBlock "Block3"
        for l = 1 to 3
          t.Slot("Cell3") = k+j*l+t.Slot("Cell2")
          t.RepeatBlock "Block3"
        next
        t.RepeatBlock "Block2"
      next
      t.RepeatBlock "Block1"
    next
    t.RepeatBlock "TBody"
  next

  ' Show Blocks named by query parameters. One and Two are available.

  for each block in Request.QueryString("Block")
    t.ShowBlock block, true
  next

  ' Create and display the document

  t.Generate
  set t = nothing
</script>

File test.html

And this is what a template file looks like. The important thing with the code/template dichotomy is that the template file can be formatted using a wysiwyg-editor without the need to switch to code view.

Well, that might not be entirely accurate, since the block markers needs to be expressed as HTML comments since they tend to appear in places where it is not valid to put text or normal HTML tags. But most wysiwyg editors can show the comments as a symbol or something, so the layout person can still see where they are.

Another nice thing with ASPTemplate, not shown in the demo, is that you could switch to an entirely different template from the .asp file, depending on some condition or parameter, and, as long as the other template uses the same slots and block structure, no changes to the ASP code are needed. Isn't that neat?

<html>
  <head>
    <title>{{Title}}</title>
  </head>
  
  <body>
    <p>This is a test. Here is the title <b>{{Title}}</b></p>
    <p>This is now: {{Now}}</p>
    <p>This is unused {{Nada}} more text.</p>
    <!--#BeginBlock One--><p>This is block <b>One</b></p><!--#EndBlock One-->
    <!--#BeginBlock Two--><p>This is block <b>Two</b></p><!--#EndBlock Two-->
    <table border="1">
      
      <tr>
        <th width="70">Col 1</th>
        <th>Col 2</th>
      </tr>
      
      <!--#BeginBlock TBody-->
      
      <tr>
        <td align="center">{{Cell1}}</td>
        <td>
          <table border="1">
          <!--#BeginBlock Block1-->
            <tr>
              <td valign="top">{{Cell2}}</td>
              <td><font size="2">
                <!--#BeginBlock Block2-->
                  <i>{{Test}}</i>
                  <!--#BeginBlock Block3-->
                    {{Cell3}}!
                  <!--#EndBlock Block3-->
                <!--#EndBlock Block2-->
                </font>
              </td>
            </tr>
          <!--#EndBlock Block1-->
          </table>
        </td>
      </tr>
    <!--#EndBlock TBody-->
    </table>
  </body>
</html>

The nitty gritty stuff

The code for the ASPTemplate relies heavily on the regular expression object introduced in IIS 5.0. One slight problem with the RegEx object is that the catch-all .* doesn't match newlines. I first used (\n|.)* to solve this, which worked fine, but very slowly. So I instead switched to replacing all newlines with a single space as soon as I read in the template file. This made subsequent processing much faster.

I used a compact coding style and not many comments in the ASPTemplate.asp file to keep the file size small, but it should still not be too hard to figure out how it works.

Caveat

I have been asked about the performance of this class. As all template processors it will slow things down - by how much depends on how you use it. I have not done any real benchmarking on the code compared to a pure ASP approach. It has performed well enough for my needs so far, although I will probably not recommend it's use in any high traffic web sites. Still, if you'd like to try, be my guest.

History

6/3 2002 First version released to the world.
27/3 2002 Changed the Slot to use properties instead of methods. This saves variables in the code since you can use a Slot just like a normal variable. Also changed ShowBlock to do both showing and hiding depending on a boolean parameter.

Direct all questions and comments to Sven Axelsson (svenax@bredband.net).

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here