ASP支持嵌套模板和循环标签的模板类

王朝学院·作者佚名  2009-05-08
窄屏简体版  字體: 小  |  中  |  大  |  超大  

ASP Template 类说明

作者:shaoyun Form www.devjs.com

时间:17:05 2008-12-10

++功能简介

--支持单层循环标签,并可在一个页面类多次使用.

--支持引入模板文件,在装载的时候,将进行模板的合并

--可指定模板文件路径,路径为相对路径,默认为当前文件路径

--对于空白行最终输出的时候,进行删除

++标签定义

{$tag$} 普通标签

{$include:filename$} 模板文件标签

<loop name="tagname">...</loop> 循环标签,name属性为标签名称

{$tag/subtag$} 循环标签中的子标签

++标签说明:

采用正则表达式进行标签的匹配和过滤,loop标签中的name属性之前可以有多个空格,之前之后可以存在其他属性,name属性可以带引号也可以不带,识别单引号和双引号,设定只匹配第一个

++函数说明

LoadTPL函数 读取模板文件,读取的时候,检查模板文件里的嵌套模板文件标签,首先替换嵌套的模板文件标签的内容,合并模板文件,存入变量

Assign函数 分析模板标签,对于普通标签将其加入数据对象,如果为循环标签,则存入循环数据对象,如果循环标签对象更换,则将循环累加的数据加入数据对象

Flush函数 模板类很重要的一个函数,用于处理循环标签,对于单次的循环,执行循环块内部替换,对循环数据进行累加保存,每个单次循环完后必须调用

Bulid函数 将没有来的及保存的循环数据加入到数据对象,然后按照模板定义输出数据对象中的所有数据,普通标签的替换在这一步完成

特别说明一下,assign函数有一个便捷的赋值方法,就是调用默认属性来赋值,效果是一致的,例如:

程序代码

tp.assign("title","新闻")

可以采取这样更简洁的赋值方式

程序代码

tp("title")="新闻"

tp是实例化的模板对象

整个模板了代码如下(template.asp):

程序代码

<%

Class Template

Private m_content,m_looptmp,tagData,loopdata,m_loop_content,m_Looptag,m_TplPath,m_SetTplPath

Private m_ClassName,m_Version,m_Copyright

Private Sub Class_Initialize()

m_content="" : m_looptmp="" : m_loop_content="" : m_looptag=""

m_ClassName="Shaoyun ASP Template类" : m_Version="1.0" : m_Copyright="DevJS.com"

m_TplPath="./" : m_SetTplPath=false

Set tagData = Server.CreateObject("Scripting.Dictionary")

Set loopData = Server.CreateObject("Scripting.Dictionary")

End Sub

Private Sub Class_Terminate()

m_content="" : m_looptmp="" : m_loop_content="" : m_looptag=""

m_TplPath="./" : m_SetTplPath=false

Set tagData = Nothing : Set loopData = Nothing

End Sub

Public Property Get ClassName

ClassName = m_ClassName

End Property

Public Property Get Version

Version = m_Version

End Property

Public Property Get Copyright

Copyright = m_Copyright

End Property

Rem 模板类的默认属性,判断模板中是否含有这个标签

Public Default Property Get Tag(tagname)

Tag = InStr(m_content,"{$" & tagname & "$")>0

End Property

Rem 调用定义好的赋值函数,这个属性用来简化赋值操作

Public Property Let Tag(tagname,replaceString)

Call Assign(tagname,replaceString)

End Property

Public Property Get TplPath

TplPath = m_TplPath

End Property

Rem 设定模板文件的路径

Public Property Let TplPath(sTplPath)

If sTplPath<>"" Then m_TplPath = sTplPath

If Right(m_TplPath,1)<>"/" Then m_TplPath = m_TplPath & "/"

End Property

Private Function LoadFromFile(sFilePath,sCharset)

LoadFromFile=false

Dim oStream

Set oStream=Server.CreateObject("ADODB.Stream")

oStream.Type=2

oStream.Mode=3

oStream.Open

oStream.Charset=sCharset

oStream.Position=oStream.Size

oStream.LoadFromFile sFilePath

LoadFromFile=oStream.ReadText

oStream.Close

Set oStream=Nothing

End Function

Private Function FileExist(filespec)

On Error Resume Next

FileExist=False

Dim oFSO : Set oFSO = Server.CreateObject("Scripting.FileSystemObject")

FileExist=oFSO.FileExists(filespec)

Set oFSO=Nothing

End Function

Rem 获取循环块

Private Function GetTmpStr(tplstr,tagname,attname)

Dim regEx,Matches,Match

Set regEx = New RegExp

regEx.Pattern = "<" & tagname & ".*?\s+name=[\""|\']?" & attname & "[\""|\']?.*?>([\s\S.]*?)<\/" & tagname & ">"

regEx.Global = False

regEx.IgnoreCase = True

Set Matches = regEx.Execute(tplstr)

For Each Match in Matches

GetTmpStr=Match.Value

Next

Set regEx = Nothing

End Function

Rem 移除HTML标记

Private Function RemoveTag(tagString,tagname)

Dim regex

Set regex=New RegExp

regEx.Pattern = "<[\/]?" & tagname & ".*?>"

regEx.Global = True

regEx.IgnoreCase = True

RemoveTag = regEx.Replace(tagString,"")

Set regex=nothing

End Function

Rem 移除空白行

Private Function RemoveSpace(tagString)

Dim regex

Set regex=New RegExp

regEx.Pattern = "\n\s*\r"

regEx.Global = True

regEx.IgnoreCase = True

RemoveSpace = regEx.Replace(tagString,"")

Set regex=nothing

End Function

Rem 读取模板文件,同时处理嵌套模板,进行模板的合并

Public Function LoadTpl(tplfile)

tplfile=Server.MapPath(tplfile)

If Not FileExist(tplfile) Then

Response.Write "Load template file faild!"

Response.End

Exit Function

End If

m_content=LoadFromFile(tplfile,"GB2312")

Dim regEx,Matches,Match,fname,sContent

Set regEx = New RegExp

regEx.Pattern = "\{\$include\:(.*?)\$\}"

regEx.Global = True

regEx.IgnoreCase = True

Set Matches = regEx.Execute(m_content)

For Each Match in Matches

fname=Match.SubMatches(0)

fname=Server.MapPath(m_TplPath & fname)

If FileExist(fname) Then

sContent=LoadFromFile(fname,"GB2312")

m_content=replace(m_content,Match.value,sContent)

End If

Next

Set regEx = Nothing

End Function

Rem 赋值替换函数

Public Function Assign(tagname,replaceString)

If tagname="" Then Exit Function

Rem 如果是循环标签

If InStr(tagname,"/")>0 and InStr(tagname,"/")<Len(tagname) Then

Rem 获取循环标签名称

m_curLooptag=Left(tagname,InStrRev(tagname,"/")-1)

If m_Looptag="" Then

Rem 如果是第一次检测到循环标签,设置循环所需变量初始值

m_looptag=m_curLooptag : m_loop_content=""

m_looptmp=GetTmpStr(m_content,"loop",m_Looptag)

Else

If m_LoopTag<>m_curLooptag Then

Rem 如果循环标签改变,初始循环变量

m_content=replace(m_content,m_looptmp,m_loop_content)

m_looptag=m_curLooptag : m_loop_content=""

m_looptmp=GetTmpStr(m_content,"loop",m_Looptag)

End If

End If

If Not(loopData.Exists(tagname)) Then loopData.Add tagname,replaceString

Else

Rem 普通标签

tagData.Add tagname,replaceString

End If

End Function

Rem 执行块内替换

Public Function Flush()

If loopdata.count>0 then

Dim i

chgtmp=RemoveTag(m_looptmp,"loop")

arrtag=loopData.keys

arrval=loopData.items

For i=0 To loopData.count-1

chgtmp=replace(chgtmp,"{$" & arrtag(i) & "$}",arrval(i))

Next

Rem 将块内数据保存到变量中

m_loop_content=m_loop_content & chgtmp

loopdata.RemoveAll

End if

End Function

Rem 构建,完成模板的最后替换

Public Function Bulid()

m_content=replace(m_content,m_looptmp,m_loop_content)

arrtag=tagData.keys

arrval=tagData.items

For i=0 To tagData.count-1

m_content=replace(m_content,"{$" & arrtag(i) & "$}",arrval(i))

Next

m_Content=RemoveSpace(m_Content)

Response.Write m_Content

End Function

End Class

%>

父模板模板代码(default.tpl):

程序代码

{$include:head.tpl$}

<h1 align=center>{$doc_title$}</h1>

<h3>{$news_title$}</h3>

<ul>

<loop name="news">

<Li style="color:#F00">新闻标题:{$news/title$}--作者:{$news/author$}</Li>

</loop>

</ul>

<h3>{$lastest_news$}</h3>

<ul>

<!-- 这里loop中的bing和count只用作测试,不是必须的,实际使用的时候请删除 -->

<loop bind="id" name=arts count="15">

<Li>文章标题:{$arts/title$}--作者:{$arts/author$}</Li>

</loop>

</ul>

{$include:foot.tpl$}

嵌套的子模板(head.tpl):

程序代码

<title>{$doc_title$}</title>

嵌套的子模板(foot.tpl):

程序代码

<p align=center>Copyright By DevJS.Com</p>

调用代码(default.asp):

程序代码

<!--#include file="function/template.asp"-->

<%

Rem 模板类的使用方法事例

Set tp = new Template

tp.tplpath="tpl"

tp.LoadTpl(tp.tplpath & "default.tpl")

tp.assign "doc_title","模板机制的例子"

tp.assign "news_title","国内新闻"

for i=0 to 2

call tp.assign("arts/title","金融危机导致大批失业人员")

call tp.assign("arts/author","网易")

tp.flush

next

tp.assign "lastest_news","最新文章"

Rem 这里改用另一种赋值方式

for i=0 to 2

tp("news/title")="政府利好消息将有助拉高股市"

tp("news/author")="SOHU"

tp.flush

next

tp.bulid

Set tp = nothing

%>

本文来源于shaoyun的blog http://www.devjs.com/ , 原文地址:http://www.devjs.com/post/asp-template-class.html

 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
© 2005- 王朝網路 版權所有 導航