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 = "ns*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