Click here to Skip to main content
Click here to Skip to main content

Separate Code and Style with ASPTemplate

, 26 Mar 2002
Rate this:
Please Sign up or sign in to vote.
How to separate code and style using ASP templates
<!-- Download Links --> <!-- Add the rest of your HTML here -->

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.

<!--<span class="code-comment">#include file="ASPTemplate.asp" --></span>
<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>
    <!--<span class="code-comment">#BeginBlock One--></span><p>This is block <b>One</b></p><!--<span class="code-comment">#EndBlock One--></span>
    <!--<span class="code-comment">#BeginBlock Two--></span><p>This is block <b>Two</b></p><!--<span class="code-comment">#EndBlock Two--></span>
    <table border="1">
      
      <tr>
        <th width="70">Col 1</th>
        <th>Col 2</th>
      </tr>
      
      <!--<span class="code-comment">#BeginBlock TBody--></span>
      
      <tr>
        <td align="center">{{Cell1}}</td>
        <td>
          <table border="1">
          <!--<span class="code-comment">#BeginBlock Block1--></span>
            <tr>
              <td valign="top">{{Cell2}}</td>
              <td><font size="2">
                <!--<span class="code-comment">#BeginBlock Block2--></span>
                  <i>{{Test}}</i>
                  <!--<span class="code-comment">#BeginBlock Block3--></span>
                    {{Cell3}}!
                  <!--<span class="code-comment">#EndBlock Block3--></span>
                <!--<span class="code-comment">#EndBlock Block2--></span>
                </font>
              </td>
            </tr>
          <!--<span class="code-comment">#EndBlock Block1--></span>
          </table>
        </td>
      </tr>
    <!--<span class="code-comment">#EndBlock TBody--></span>
    </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, along with any associated source code and files, is licensed under A Public Domain dedication

About the Author

Sven Axelsson
Web Developer
Sweden Sweden
No Biography provided

Comments and Discussions

 
Generalproblem.. PinmemberJennifer Miles1-Aug-03 18:20 
GeneralRe: problem.. Pinsussallia13-Sep-03 11:06 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web01 | 2.8.140721.1 | Last Updated 27 Mar 2002
Article Copyright 2002 by Sven Axelsson
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid