Skip to page content or Skip to Accesskey List.

Work

Main Page Content

Separating Asp Code From Html In Templates

Rated 3.81 (Ratings: 3)

Want more?

 
Picture of Junglee

Ashok Hariharan

Member info

User since: 28 Jan 2002

Articles written: 5

Not so long ago, I got introduced to server side scripting for websites. I

really began to enjoy myself. I could create my HTML and go around embedding

my neat little <%%> asp tags. Man... it was fun. Then came a time when

the client wanted me to change some of the visual design. "Just move

this image from over here to there..." That's when my nightmares began.

It turned out to be an experience just about as pleasant as piercing needles

through your eyes. Somewhere down the line my embedded ASP got jumbled. Something

had to be wrong with what I was doing.

I needed a framework that would allow:

  • Single point of modification for templates on a site
  • Some kind of templating. I didn't want to use templating features of a specific

    HTML editor, since a lot of the time I end up editing html manually
  • Separate ASP from HTML
  • Allow reusability.

Some Nuclear Physics

The first part of our technique is basically about breaking up an HTML page

into usable bits, when we need to display it on the website (some HTML Fission).

The second part is about rejoining the various bits, when we need to see the

HTML as a whole (some HTML Fusion).

Fission

Why do I breakup a decent HTML page into pieces? There are quite a few advantages

to this. For one, most websites have a common look and feel throughout, but

when the look does need to change I would like to make it in 1 place. Sometimes

only small things need to be changed like a navigation menu moving from the

left hand side of the page to the right hand side. And many times the only thing different

between look and feel of pages is something technically minor like the banner

table being a 3-column table instead of a single column table, I didn't want

to maintain a duplicate of the page template just to accommodate stuff like

this.

There are additional advantages to this scheme. It's very easy to provide

additional features like "print version" and also hidden/alternate

navigation on specific pages.

Fissile Material

A typical page layout for my example would look like:

image sample page layout

As you can see I have divided the page into manageable tables.

I break up the page further to my convenience by demarcating specific parts

of the page. For example, I mark the starting of the page header into 3 parts in

the following way:

<!--[_part_start_:000.01.head_beg]-->

<html>

<head>

<title><!--_VAR_TITLE_--></title>

<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">

<!--[_part_start_:000.02.head_scr]-->

<script>

function dummy()

{

return 0;

}

</script>

<!--[_part_start_:000.99.head_end]-->

</head>

As you can see I divided the HTML by using comment tags named in a particular

way:

<!--[_part_start_:xxx.xx.section_name]-->.

I used a naming convention as it allows me to later extract specific sections

of this file using regular expressions. There are certain advantages to

using a naming schema based on comment tags. For one, most HTML editors find

them palatable and generally don't screw around with them (though personally I

use the editor to make the initial layout, after that I hand-edit it...).

There is also a comment called <!--_VAR_TITLE_--> within

the <title> tag. I use many of these _VAR_..._ type of comments

in the page and I use them as "display" variables. These are searched

and replaced at runtime. For example my ASP page replaces the <!--_VAR_TITLE_-->

tag with the page title and the <!--_VAR_CONTENT_1_--> with

the meat of the content at the time of script execution.

Blowin' it up

I have been using windows scripting to automate a lot of stuff on my PC, which

means I use it again to make a script that would break up the HTML. I make

use of the powerful JavaScript regexp object to do this. I execute the script

on the layout HTML file in which I have also inserted my special comments. The cscript.exe

interpreter that comes installed with windows takes care of interpreting and executing the

JavaScript.

I find windows scripting quite useful when I install ActivePython/Perl. I can even use

Python or Perl scripts in it.

I execute my script on the HTML file using a command line syntax similar to

this:

d:\files>cscript tools.wsf //job:SplitHtml file.html input_folder

Incidentally the .wsf script file is called a package file and can contain

scripts for multiple tasks (or <job> as Microsoft documentation calls it),

so the SplitHtml is a job in the wsf file. The SplitHtml job executes on the

html file and creates multiple text files. The text files are named using the

tag we defined the section to be e.g.:

For a section that was marked as:

<!--[_part_start_:000.01.head_beg]-->
the HTML code in

the section denoted by this comment tag gets extracted to a file called 000.01.head_beg.txt.

The SplitHtml script uses regular expression matching to extract the specific

_part_start_ sections of the HTML page. The regular expression was defined in

Javascript as:


re=new RegExp("\<\!--\\[_part_start_:([0-9]{3}.[0-9]{2}.[A-Za-z_]+)\\]--\>","g");

The script creates files for every such designated section.

image of explorer File Listing

I used a naming scheme for the comment tags, which ensures that the generated

text files maintain the same sequence as the section dividing comments. Additionally

the naming scheme allows me to add a new section comment without changing or

disrupting the existing sequence. For instance if I needed to add some new HTML

code between 000.02.head_scr and 000.99.head_end

(head_end marks the </head> tag..) sections, I can insert up to

95 individual

parts in between by naming them as 000.03.tag1, 000.04.tag2.....When I sort

the files in Windows Explorer by name, they are in exactly the same sequence

as the _part_start_ comments were in the originating HTML file.

Maybe a better method of maintaining the sequence, would be to store the individual

splits in a database table. Well, this works for me so I use it.

My ASP page scripts read the split parts sequentially (discussed later below)

and renders the page.

When I want to see the page as a single HTML file, I again use a windows script

called BuildHtml that rebuilds the HTML file from the parts text files. This

job uses a very similar syntax to the SplitHtml method. I can also now use any HTML editor to edit the page layout.

All the source code for SplitHtml & BuildHtml with a couple of other script

functions to query display tags & variable tags in a HTML file can be downloaded

from:
source.zip

Fusion

We use some ASP fusion to create our dynamically generated page out of all

the pieces we divided our HTML page into. Let's start with the basics. If my

ASP page is called display.asp, I have a corresponding

definition file
for it called def.display.asp .

Defining The Ingredients

The definition file defines the sequence in which the individual HTML section

files (the text files we just created) should be looked up & allows defining

of a condition for looking up the section. This file is included at the beginning

of every ASP file it defines the structure. For instance when display.asp

is executed, the def.display.asp is first executed and a String variable is

built which contains the HTML code for the page.

The def.display.asp file would look something like this:

<%

/**************************

Section 1 -- HTML Lookups

***************************/

/*now we being lookup the html sections */

/*this should always be shown..*/

/*Settings for this page*/

/*

Header section

*/

HtmlLookup("000.01.head_beg",true);

HtmlLookup("000.02.head_scr",true);

HtmlLookup("000.99.head_end",true);

/*

Banner section

*/

HtmlLookup("001.00.body",true);

HtmlLookup("001.01.banner",printable());

HtmlLookup("001.02.horiz_nav",printable());

/*

Page Vertical Navigation

*/

HtmlLookup("002.01.main_tbl_begin",true);

HtmlLookup("002.02.vertical_nav_beg",true);

HtmlLookup("002.03.vertical_nav",printable());

HtmlLookup("002.04.vertical_nav_end",true);

HtmlLookup("002.05.content_begin",true);

HtmlLookup("002.08.content_end",true);

HtmlLookup("002.09.main_tbl_end",true);

HtmlLookup("003.01.footer",true);

HtmlLookup("009.99.end_page",true);

%>

The HtmlLookup function takes the section name as the 1st parameter (this happens

to be the primary name for the text file) and a 2nd parameter which can be used

to conditionally display the section. For instance, in the sample with this

article I hide a part of the navigation when the page is being viewed in printable

mode (I set a page to printable mode by passing a query string parameter).

The multiple calls to HTMLLookup builds a string variable with the HTML code

for the page. Based on the section name that has been passed the lookup function

opens the corresponding .txt file and builds up the HTML.

Concocting the page for the final output

Now to the structure of our main ASP file display.asp . This page has a few

SSI includes, and importantly this is where our main code to pick up the content

from a database would reside. The specific content is then updated into the

specific comment _VAR_iables I described earlier. I have a helper function called

HtmlTransform which takes the _VAR_ variable name as the 1st parameter

and the actual content to be displayed in place of that variable as a string

parameter.

In the HtmlTransform function I search and replace every instance of the comment

variable with the content string. Which means that I could have _VAR_TITLE_

or any other display tage appearing more than once. My search & replace

function would appear as:

replace(strHtml, "\<\!--"+strVariable+"--\>",

strReplace) ;

where strVariable is anything like (_VAR_TITLE_, _VAR_CONTENT_1_ etc.), (the

replace function is some code taken from one of the gazillion javascript sites...)

There is an additional advantage to using a _VAR_ style of variable. For instance

if my vertical navigation menu bar (typically on the left or hand side of a

page) is not to appear on the print version or a hidden navigation version of

the page, I can save the overhead of a lookup to the database for that information

(This would be relevant if the menu navigation or any of the display element

which is to be hidden in a print version is picked up from a database), by simply

checking if the _VAR_ variable for the menu exists in my HTML string. Something

like:

if (getHtml().indexOf("<!--_VAR_LEFTMENU_-->") != -1)

//only if the HTML string contains a leftmenu display

//variable pickup the content for it

{

strVertMenuOut = LookupFromDatabase();

}

So my display.asp script would look something like this:

<%@ LANGUAGE=JScript%>

<!--common ssis-->

<!--#include file="inc/globvars.asp"-->

<!--#include file="inc/funcs.asp"-->

<!--#include file="inc/setprintable.asp"-->

<!--end common includes-->

<!--page defintion ssi-->

<!--#include file="def.display.asp"-->

<%

/*

Section 2 -- HTML Transforms

*/

//Code to fetch content from database

//Code to fetch stuff like page title etc.

var strContent1;

var strContent2;

//here we just fill with dummy info

strContent1 = "<h2>My Content1</h2>";

strContent2 = "<h2>My Content2</h2>";

//Code to fetch Navigation menus etc.

//.....

//again I fill up some dummy links for my vertical menu

strVertNav = "<br><a href=\"http://dir.evolt.org\">

Evolt directory</a><br><a href=\"http://browsers.evolt.org\">Evolt

Browsers</a>";

//....

//.....

//begin transforms

HtmlTransform("_VAR_TITLE_", "HTML Templating sample code");

HtmlTransform("_VAR_CONTENT_1_", strContent1);

HtmlTransform("_VAR_CONTENT_2_", strContent2);

HtmlTransform("_VAR_VERT_NAV_", strVertNav);

%>

<!--output page html here-->

<%=getHtml()%>

<!--page end-->

Main advantages of this method

  • Separation of HTML from ASP code
  • Splitting of page HTML increases flexibility & makes changes easier
  • Makes creation of print versions, alternate navigations easier
  • Easy to adapt to other non-asp languages (hopefully!) 

Some drawbacks of this method

  • The method is very much dependent on a proper sequential naming scheme for

    named _part_ comments (I maintain a sequential documented list of _part_ and _VAR_ comments

    in an excel sheet just for my reference)
  • Additional Scripts like SplitHtml & BuildHtml need to be used to view

    the HTML file as a whole when required (and this is dependent on a proper

    naming scheme)
  • There might be a higher performance overhead since all the HTML is looked up and filled in a string and then the named comments replaced

Sample code

All the sample ASP & WSF script code with sample files can downloaded

from:

source.zip

Related links

I found some similar methods & ideas discussed at:

4guysfromrolla


These are a couple of sites on Windows Scripting that I have found useful:

WinScripter.com

Ian Morrish's site on Windows scripting

Just as I was posting this article, I saw this nice article on regex by sprocket:

Regular Expression basics

Ashok is based in Nairobi, Kenya. When not busy dodging vagrant matatus in Nairobi traffic, he keeps himself upto date by evolt-ing.

The access keys for this page are: ALT (Control on a Mac) plus:

evolt.org Evolt.org is an all-volunteer resource for web developers made up of a discussion list, a browser archive, and member-submitted articles. This article is the property of its author, please do not redistribute or use elsewhere without checking with the author.