Source of article: Programming Notes
http://blog.csdn.net/nhconch Please support me.
Every developer who has designed a large-scale ASP-Web application probably has the following experience: ASP code and page HTML are confused and difficult to distinguish, and business logic It is tied up with the display mode, making the code difficult to understand and modify; programming must be written after the art, which has become a project bottleneck; when integrating the program code and HTML static pages, it takes a lot of time to get the desired effect, and it doubles as the art. Indeed, it is not easy to separate data processing and data display when developing Web applications using scripting languages. However, in the case of multi-person cooperation, if data and display cannot be separated, it will greatly affect the efficiency of development and the professional division of labor.
Other scripting languages, such as JSP and PHP, have their own solutions. ASP.NET, the later generation product of ASP, also implements codes and pages. It seems that directly transitioning to ASP is a good choice. But there are always reasons of one kind or another that prevent us from giving up ASP or going straight to the .NET camp for the time being. From a company's perspective, switching languages is a huge investment, including hiring experienced .NET programmers, training existing programmers, transformation of development tools, transformation of development style, change of interface style, interface style, software architecture, Documents, development processes, etc.; this also means that the original code must be rewritten in the new language environment to achieve the best effect and stability; at the same time, it will directly affect the progress of the project during this period, and is more likely to lead to individual Programmers leave. It seems that before you decide to switch languages, it is best to find a solution on the original basis.
PHP implements codes and pages through templates. There are FastTemplate, PHPLIB, Smarty, etc. to choose from, among which PHPLIB has the greatest influence and is the most used. In this case, we directly move it to ASP, which has great benefits for companies that use both PHP and ASP: 1. When the artist processes the page, whether PHP or ASP is used, the processing method is the same, and no training is required; 2. When programmers write code, the ideas between the two languages are close or consistent. When the same functions are implemented in the two languages, they only need to copy them and make slight modifications, ensuring work efficiency and project progress.
1. The design of template class implements code encapsulation into template class, which is not only to be compatible with PHPLIB, but also to make the code easy to manage and expand.
The goal of the template class is to read the displayed HTML code from the template file, replace the parts of the display code that require dynamic data with the data calculated by the ASP program, and then output it in a certain order. Among them, the replacement part can be set freely. Therefore it must complete the following tasks:
·Read the HTML code for display from the template file.
·Combine the template file with the actual generated data to generate output results.
·Allows multiple templates to be processed simultaneously.
·Allow template nesting.
·Allows processing of an individual part of the template.
Implementation method:
Use FSO to read template files
Use regular replacement to combine template files and data
Processing multiple templates is implemented using array storage.
The main idea behind the implementation of template nesting is to treat templates and outputs (any intermediate analysis results) equally, and both can be replaced, and that's it.
The processing of individual parts is controlled by setting annotations in the template file, and then combining the annotations in regular replacement to achieve partial replacement.
2. Before giving the specific code for the implementation of the template class, let’s first list the main functions. Friends who have used PHPLIB should be familiar with this:
1) Public Sub set_root(ByVal Value) sets the template default directory 2) Public Sub set_file(ByVal handle,ByVal filename) reads the file 3) Public Sub set_var(ByVal Name, ByVal Value, ByVal Append) sets the mapping data-replacement variable 4) Public Sub unset_var(ByVal Name) Cancel data mapping 5) Public Sub set_block(ByVal Parent, ByVal BlockTag, ByVal Name) Set data block 6) Public Sub set_unknowns(ByVal unknowns) Set the tag processing method for unspecified mapping 7) Public Sub parse(ByVal Name, ByVal BlockTag, ByVal Append) executes the combination of template file and data 8) Public Sub p(ByVal Name) outputs the processing result
implementation code:
<%
'================================================== ======================
' The naming methods such as set_var and set_block are used in this object for compatibility with phplib
'================================================== ======================
'www.downcodes.com
Class kktTemplate
Private m_FileName, m_Root, m_Unknowns, m_LastError, m_HaltOnErr
Private m_ValueList, m_BlockList
Private m_RegExp
'Constructor
Private Sub Class_Initialize
Set m_ValueList = CreateObject("Scripting.Dictionary")
Set m_BlockList = CreateObject("Scripting.Dictionary")
set m_RegExp = New RegExp
m_RegExp.IgnoreCase = True
m_RegExp.Global = True
m_FileName = ""
m_Root = ""
m_Unknowns = "remove"
m_LastError = ""
m_HaltOnErr = true
End Sub
'Destructor
Private Sub Class_Terminate
Set m_RegExp = Nothing
Set m_BlockMatches = Nothing
Set m_ValueMatches = nothing
End Sub
Public Property GetClassName()
ClassName = "kktTemplate"
End Property
Public Property Get Version()
Version = "1.0"
End Property
Public Sub About()
Response.Write("kktTemplate ASP page template class<br>" & vbCrLf &_
"Programming: Peng Guohui2004-07-05<br>" & vbCrLf &_
"Personal website: <a href='http://kacarton.yeah.net'>http://kacarton.yeah.net</a><br>" & vbCrLf &_
"Email: <a href='mailto:[email protected]'>[email protected]</a><br>")
End Sub
'Check if the directory exists
Public Function FolderExist(ByVal path)
Dim fso
Set fso = CreateObject("Scripting.FileSystemObject")
FolderExist = fso.FolderExists(Server.MapPath(path))
Set fso = Nothing
End Function
'Read file content
Private Function LoadFile()
Dim Filename, fso, hndFile
Filename = m_Root
If Right(Filename, 1)<>"/" And Right(Filename, 1)<>"" Then Filename = Filename & "/"
Filename = Server.MapPath(Filename & m_FileName)
Set fso = CreateObject("Scripting.FileSystemObject")
If Not fso.FileExists(Filename) Then ShowError("Template file" & m_FileName & "Does not exist!")
set hndFile = fso.OpenTextFile(Filename)
LoadFile = hndFile.ReadAll
Set hndFile = Nothing
Set fso = Nothing
If LoadFile = "" Then ShowError("Cannot read template file" & m_FileName & "Or the file is empty!")
End Function
'Handle error messages
Private Sub ShowError(ByVal msg)
m_LastError = msg
Response.Write "<font color=red style='font-size;14px'><b>Template error:" & msg & "</b></font><br>"
If m_HaltOnErr Then Response.End
End Sub
'Set the default directory for template files
'Ex: kktTemplate.set_root("/tmplate")
' kktTemplate.Root = "/tmplate"
' root = kktTemplate.get_root()
' root = kktTemplate.Root
'Using a naming method like set_root is for compatibility with phplib, which will not be repeated below.
Public Sub set_root(ByVal Value)
If Not FolderExist(Value) Then ShowError(Value & "Not a valid directory or the directory does not exist!")
m_Root = Value
End Sub
Public Function get_root()
get_root = m_Root
End Function
Public Property Let Root(ByVal Value)
set_root(Value)
End Property
Public Property GetRoot()
Root = m_Root
End Property
'Set template file
'Ex: kktTemplate.set_file("hndTpl", "index.htm")
'This class does not support multiple template files, the handle is reserved for compatibility with phplib
Public Sub set_file(ByVal handle,ByVal filename)
m_FileName = filename
m_BlockList.Add Handle, LoadFile()
End Sub
Public Function get_file()
get_file = m_FileName
End Function
' Public Property Let File(handle, filename)
'set_file handle, filename
'End Property
'Public Property Get File()
'File = m_FileName
'End Property
'Set the processing method for unspecified tags, including keep, remove and comment.
Public Sub set_unknowns(ByVal unknowns)
m_Unknowns = unknowns
End Sub
Public Function get_unknowns()
get_unknowns = m_Unknowns
End Function
Public Property Let Unknowns(ByVal unknown)
m_Unknowns = unknown
End Property
Public Property Get Unknowns()
Unknowns = m_Unknowns
End Property
Public Sub set_block(ByVal Parent, ByVal BlockTag, ByVal Name)
Dim Matches
m_RegExp.Pattern = "<!--s+BEGIN " & BlockTag & "s+-->([sS.]*)<!--s+END " & BlockTag & "s+-- >"
If Not m_BlockList.Exists(Parent) Then ShowError("Unspecified block tag" & Parent)
set Matches = m_RegExp.Execute(m_BlockList.Item(Parent))
For Each Match In Matches
m_BlockList.Add BlockTag, Match.SubMatches(0)
m_BlockList.Item(Parent) = Replace(m_BlockList.Item(Parent), Match.Value, "{" & Name & "}")
Next
set Matches = nothing
End Sub
Public Sub set_var(ByVal Name, ByVal Value, ByVal Append)
Dim Val
If IsNull(Value) Then Val = "" Else Val = Value
If m_ValueList.Exists(Name) Then
If Append Then m_ValueList.Item(Name) = m_ValueList.Item(Name) & Val _
Else m_ValueList.Item(Name) = Val
Else
m_ValueList.Add Name, Value
End If
End Sub
Public Sub unset_var(ByVal Name)
If m_ValueList.Exists(Name) Then m_ValueList.Remove(Name)
End Sub
Private Function InstanceValue(ByVal BlockTag)
Dim keys, i
InstanceValue = m_BlockList.Item(BlockTag)
keys = m_ValueList.Keys
For i=0 To m_ValueList.Count-1
InstanceValue = Replace(InstanceValue, "{" & keys(i) & "}", m_ValueList.Item(keys(i)))
Next
End Function
Public Sub parse(ByVal Name, ByVal BlockTag, ByVal Append)
If Not m_BlockList.Exists(BlockTag) Then ShowError("Unspecified block tag" & Parent)
If m_ValueList.Exists(Name) Then
If Append Then m_ValueList.Item(Name) = m_ValueList.Item(Name) & InstanceValue(BlockTag) _
Else m_ValueList.Item(Name) = InstanceValue(BlockTag)
Else
m_ValueList.Add Name, InstanceValue(BlockTag)
End If
End Sub
Private Function finish(ByVal content)
Select Case m_Unknowns
Case "keep" finish = content
Case "remove"
m_RegExp.Pattern = "{[^ trn}]+}"
finish = m_RegExp.Replace(content, "")
Case "comment"
m_RegExp.Pattern = "{([^ trn}]+)}"
finish = m_RegExp.Replace(content, "<!-- Template Variable $1 undefined -->")
Case Else finish = content
End Select
End Function
Public Sub p(ByVal Name)
If Not m_ValueList.Exists(Name) Then ShowError("Does not exist" & Name)
Response.Write(finish(m_ValueList.Item(Name)))
End Sub
End Class
%>
3. Usage examples Here are three examples for explanation.
1) Simple value replacement template file is myTemple.tpl, content:
<html><title>ASP template simple replacement</title><body>
congratulate! You won a {some_color} Ferrari!
</body>
The following is the ASP code (kktTemplate.inc.asp is the template class given above):
<!--#INCLUDE VIRTUAL="kktTemplate.inc.asp"-->
<%
dim my_color, kkt
my_color = "red"
set kkt = new kktTemplate 'Create template object
kkt.set_file "hndKktTemp", "myTemple.tpl" 'Set and read the template file myTemple.tpl
kkt.set_var "some_color", my_color, false 'Set the value of template variable some_color = my_color
kkt.parse "out", "hndKktTemp", false 'Template variable out = processed file
kkt.p "out" 'Output the content of out
set kkt = nothing 'Destroy the template object
%>
The output after execution is:
<html><title>ASP template simple replacement</title><body>
congratulate! You win a red Ferrari!
</body>
2) Loop block demonstration example template file myTemple2.tpl:
<html><title>ASP Template-Block Demonstration</title><body>
<table cellspacing="2" border="1"><tr><td>Which animal below do you like</td></tr>
<!-- BEGIN AnimalList -->
<tr><td><input type="radio" name="chk">{animal}</td></tr>
<!-- END AnimalList -->
</table>
</body>
ASP code:
<!--#INCLUDE VIRTUAL="kktTemplate.inc.asp"-->
<%
dim animal, kkt, i
animal = Array("Little Pig","Puppy","Xiaoqiang")
set kkt = new kktTemplate
kkt.set_file "hndKktTemp", "myTemple2.tpl"
kkt.set_block "hndKktTemp", "AnimalList", "list"
for i=0 to UBound(animal)
kkt.set_var "animal", animal(i), false
kkt.parse "list", "AnimalList", true
next
kkt.parse "out", "hndKktTemp", false
kkt.p "out"
set kkt = nothing
%>
Execution result:
<html><title>ASP Template-Block Demonstration</title><body>
<table cellspacing="2" border="1"><tr><td>Which animal do you like the following</td></tr>
<tr><td><input type="radio" name="chk">Little Pig</td></tr>
<tr><td><input type="radio" name="chk">Puppy</td></tr>
<tr><td><input type="radio" name="chk">Xiaoqiang</td></tr>
</table>
</body>
3) Nested block demonstration template file myTemple3.tpl:
<html><title>ASP Template - Nested Block Demonstration</title>
<body><table width="400" border="1" bordercolor="#000000">
<tr><td><div align="center">{myname} test</div></td></tr>
<tr><td>My zoological and botanical garden: </td> </tr>
<!-- BEGIN animalList -->
<tr><td>{animal}</td></tr>
<!-- BEGIN plantList -->
<tr><td> {plant}</td></tr>
<!-- END plantList -->
<!-- END animalList -->
</table>
</body>
</html>
ASP code:
<!--#INCLUDE VIRTUAL="kktTemplate.inc.asp"-->
<%
dim my_color, kkt, myname, animal, plant
set kkt = new kktTemplate
myname = "kktTemplate block test..."
animal = array("animal", "plant")
plant = array(array("Little Pig","Xiaobai","Xiaoqiang"), array("Rose","Sunflower"))
kkt.set_file "hndKktTemp", "myTemple3.tpl"
kkt.set_var "myname", myname, false
kkt.set_block "hndKktTemp", "animalList", "a"
kkt.set_block "animalList", "plantList", "p"
for i=0 to UBound(animal)
kkt.set_var "animal", animal(i), False
kkt.unset_var "p"
'kkt.set_var "p", "", false
for j=0 to UBound(plant(i))
kkt.set_var "plant", plant(i)(j), false
kkt.parse "p", "plantList", true
next
kkt.parse "a", "animalList", true
next
kkt.parse "out", "hndKktTemp", false
kkt.p "out"
%>
Execution result:
<html><title>ASP Template - Nested Block Demonstration</title>
<body><table width="400" border="1" bordercolor="#000000">
<tr><td><div align="center">kktTemplate block test...test</div></td></tr>
<tr><td>My zoological and botanical garden: </td> </tr>
<tr><td>Animals</td></tr>
<tr><td> Little Pig</td></tr>
<tr><td> Xiaobai</td></tr>
<tr><td> Xiaoqiang</td></tr>
<tr><td>Plants</td></tr>
<tr><td> Rose</td></tr>
<tr><td> Sunflower</td></tr>
</table>
</body>
</html>
All code mentioned in this article can be downloaded here: