回 帖 发 新 帖 刷新版面

主题:[原创]快速单层循环区块模板类

Fast ASP Template Class
[quote]
<%
'转发或修改时,请务必保留注释说明.
'            ____       __
'    ___     \   \     / /
'   |   |     \   \   / /   领
'   |   |      \   \ / /
'   |   |       \  // /     星
'   |   | _     / //  \
'   |   || |   / / \   \    动
'   |   || |  / /   \   \
'   |   || | /_/     \___\  网
'   |   || |___
'   |___||_____| www.lxasp.com
'
'版权所有.使用时请联系告知原作者.

'############################################################
'* 名称: 快速单层循环区块模板类 ( Ver 2.0 )
'* 说明: Fast/High Performance Single-level Blocks ASP Template Class
'* 日期: 2007-4-23  状态: 就绪
'############################################################
Class clsLxxTPL

  Private vrM1,vrM2
  Private bkM1,bkM2,bkM3,bkN1,bkN2
  Private bkM_1,bkM_2,bkM_3,bkN_1,bkN_2

  Private gloTplBK,gloTplBK1,unTplBK,reTplBK,tplSubs
  Private tplStore,tplStore1,curTpl,IngTpl,curBk,curBkL,bkNames,BlockCode,NoBlocked

  Private Sub Class_Initialize()

    tplStore=""
    tplStore1=""
    curTpl=""
    IngTpl=""
    curBk=""
    curBkL=0

    NoBlocked=True

    Set reTplBK=New clsLxxTPLStrCat
    Set unTplBK=New clsLxxTPLStrCat
    Set bkNames=New clsLxxTPLStrCat
    Set BlockCode=New clsLxxTPLStrCat

    gloTplBK="tmp_"&amp;amp;RndGenerator(3)&amp;amp;"_"
    gloTplBK1="res_"&amp;amp;RndGenerator(3)&amp;amp;"_"

    '设置普通标签符号
    vrM1="{="
    vrM2="}"

    '设置区块标签符号
    bkM1="{%[ "
    bkM2=" %}"
    bkM3="{%] "
    bkN1="{%["
    bkN2="{%]"

    bkM_1=Len(bkM1)
    bkM_2=Len(bkM2)
    bkM_3=Len(bkM3)
    bkN_1=Len(bkN1)
    bkN_2=Len(bkN2)

  End Sub

  Private Sub Class_Terminate()
    On Error Resume Next
    tplStore=""
    tplStore1=""
    curTpl=""
    IngTpl=""
    curBk=""
    Execute unTplBK
    Set reTplBK=Nothing
    Set unTplBK=Nothing
    Set bkNames=Nothing
    Set BlockCode=Nothing
  End Sub

  'VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
  '模板文件加载、获取、处理过程
  'VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
  Private Function RndGenerator(Length)
    Dim i, tempS
    tempS = "abcdefghijklmnopqrstuvwxyz"
    RndGenerator = ""
    For i = 1 To Length
      Randomize
      RndGenerator = RndGenerator &amp;amp; Mid(tempS, Int((Len(tempS) * Rnd) + 1), 1)
    Next
  End Function

  Private Function MLine(src)
    Dim s
    s = src
    s = Replace(s, """", """""")
    s = Replace(s, vbCrLf, """ &amp;amp; vbCrLf &amp;amp; """)
    s = Replace(s, vbCr, """ &amp;amp; vbCr &amp;amp; """)
    s = Replace(s, vbLf, """ &amp;amp; vbLf &amp;amp; """)
    s = Replace(s, vbTab, """ &amp;amp; vbTab &amp;amp; """)
    MLine = """" &amp;amp; s &amp;amp; """"
  End Function

  Private Function FindBlock()
    On Error Resume Next

    Dim i1, i2, i3
    Dim s1, s2, l1, l2, b1, b2
    Dim p,o,s
    p=1
    o=curTpl
    s=curTpl
    Do
      i1 = InStr(p, s, bkM1)
      If i1 > 0 Then
        i1 = i1 + bkM_1
        p = i1
        i2 = InStr(i1, s, bkM2)
        If i2 > 0 Then
          l1 = i2 - i1

          If l1 >= 1 And l1 <= 20 Then

            s1 = Mid(s, i1, l1)

            b1 = i2 + bkM_2
            p = b1
            s2=bkM3 &amp;amp; s1 &amp;amp; bkM2
            l2=Len(s2)
            i3 = InStr(b1, s, s2)
            If i3 > 0 Then
              b2 = i3
              i3 = i3 + l2
              p = i3

              BlockCode()="Dim " &amp;amp; gloTplBK &amp;amp; s1 &amp;amp; vbCrLf &amp;amp; gloTplBK &amp;amp; s1 &amp;amp; "=" &amp;amp; MLine(Mid(s, b1, b2 - b1)) &amp;amp; vbCrLf &amp;amp; "Dim " &amp;amp; gloTplBK1 &amp;amp; s1 &amp;amp; " : Set " &amp;amp; gloTplBK1 &amp;amp; s1 &amp;amp; "=New clsLxxTPLStrCat" &amp;amp; vbCrLf

              unTplBK()=gloTplBK &amp;amp; s1 &amp;amp; "=Empty: Set " &amp;amp; gloTplBK1 &amp;amp; s1 &amp;amp; "=Nothing"&amp;amp;vbCrLf
              reTplBK()=gloTplBK1 &amp;amp; s1 &amp;amp; ".Reset"&amp;amp;vbCrLf

              bkNames()="curTpl=Replace(curTpl,""" &amp;amp; bkN1 &amp;amp; s1 &amp;amp; bkN2 &amp;amp; """," &amp;amp; gloTplBK1 &amp;amp; s1 &amp;amp; "() )" &amp;amp; vbCrLf

              o=Replace(o,Mid(s,(i1-bkM_1),(i3)-(i1-bkM_1)),bkN1 &amp;amp; s1 &amp;amp; bkN2 )

            End If

          End If

        Else
          l1 = 0
        End If

      End If

    Loop While i1 > 0

    ExecuteGlobal BlockCode()

    curTpl=o
    tplStore1=curTpl
    IngTpl=curTpl

    NoBlocked=False

  End Function

  Private Function GetFile(fn)
    Dim FSO,ts
    On Error Resume Next
    Set FSO = Server.CreateObject("Scripting.FileSystemObject")
    If Len(Trim(fn))>0 Then
      If FSO.FileExists(Server.MapPath(fn)) Then
        Set ts = FSO.OpenTextFile(Server.MapPath(fn))
        GetFile=ts.ReadAll
        ts.Close
        Set ts = Nothing
      Else
        GetFile=Null
      End If
    Else
      GetFile=Null
    End If
    Set FSO = Nothing
  End Function

  Private Function Init()
    On Error Resume Next

    Init=True

    tplStore=tplSubs(0)
    If Len(tplStore)=0 Then Init=False:Exit Function
    curTpl=tplStore
    tplStore1=curTpl
    IngTpl=curTpl
    curBk=""
    curBkL=0
    NoBlocked=True

  End Function

  Public Function LoadFile(FilePath)
    LoadFile=True

    tplSubs=Split(GetFile(filepath),"<!--/*ExtraSubLevel*/-->")

    LoadFile=Init()
  End Function

  Public Function LoadStr(tplContent)
    LoadStr=True
    If Len(tplContent)>0 Then

      tplSubs=Split(tplContent,"<!--/*ExtraSubLevel*/-->")

      LoadStr=Init()

    Else
      LoadStr=False
    End If
  End Function

  Public Function Reset()
    On Error Resume Next

    Reset=True
    If Len(tplStore1)=0 Then Reset=False:Exit Function
    curTpl=tplStore1
    IngTpl=curTpl
    curBk=""
    curBkL=0
    NoBlocked=False
    Execute reTplBK()

  End Function

  Public Function GetTemplate()
    GetTemplate=tplStore
  End Function

  Public Function GetSub(idx)
    On Error Resume Next
    GetSub=""
    GetSub=tplSubs(idx)
  End Function
  'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

  '用于判断区块是否存在
  Public Function Exists(Key)
    If NoBlocked Then FindBlock
    Exists=(InStr(1,tplStore1,bkN1 &amp;amp; Key &amp;amp; bkN2) > 0)
  End Function

  Public Function GetParam(pname,def)

    Dim qs,p1,p2,pn,sf1,sf2,lf1,lf2

    qs=tplStore

    pn=""
    GetParam=""

    sf1="<!--" &amp;amp; pname &amp;amp; "="
    lf1=Len(sf1)

    sf2="-->"
    lf2=Len(sf2)

    p1=InStr(1,qs,sf1,1)
    If p1>0 Then
      p2=InStr(p1+lf1,qs,sf2)
      If p2>0 Then
        pn=Mid(qs,p1+lf1,p2-(p1+lf1))
      End If
    End If

    GetParam=pn
    If Len(GetParam)=0 Then GetParam=def
    If IsNumeric(pn) Then  GetParam=CInt(pn)

  End Function

  'VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
  '设置要替换的模板中的特殊标签·主要调用过程
  'VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
  Public Sub Go(k)

    On Error Resume Next

    If NoBlocked Then FindBlock

    Execute "IngTpl="&amp;amp;gloTplBK&amp;amp;k

    If Err Then
      IngTpl=curTpl
      curBk=""
      curBkL=0
      Err.Clear
    Else
      curBk=k
      curBkL=Len(k)
    End If

  End Sub

  Public Property Let Tag(k, val)
    If curBkL>0 Then
      IngTpl = Replace(IngTpl, vrM1 &amp;amp; k &amp;amp; vrM2, val)
    Else
      curTpl = Replace(curTpl, vrM1 &amp;amp; k &amp;amp; vrM2, val)
    End If
  End Property

  '用于判断标签是否存在
  Public Default Property Get Tag(k)
    Tag = InStr(1,tplStore,vrM1 &amp;amp; k &amp;amp; vrM2)
  End Property

  Public Sub Add()
    On Error Resume Next
    If curBkL > 0 Then Execute gloTplBK1&amp;amp;curBk&amp;amp;"()=IngTpl"
    IngTpl=""
    curBk=""
    curBkL=0
  End Sub

  '这个纯粹是上面属性的过程调用版
  Public Sub Rep(b,ks,vs)

    Dim i,u

    On Error Resume Next

    If NoBlocked Then FindBlock

    Execute "IngTpl="&amp;amp;gloTplBK&amp;amp;b

    If Err Then
      IngTpl=curTpl
      curBk=""
      curBkL=0
      Err.Clear
    Else
      curBk=b
      curBkL=Len(b)
    End If

    u=UBound(ks)
    If curBkL>0 Then
      For i=0 To u
        IngTpl = Replace(IngTpl, vrM1 &amp;amp; ks(i) &amp;amp; vrM2, vs(i))
      Next
    Else
      For i=0 To u
        curTpl = Replace(curTpl, vrM1 &amp;amp; ks(i) &amp;amp; vrM2, vs(i))
      Next
    End If

    Execute gloTplBK1&amp;amp;curBk&amp;amp;"()=IngTpl"
    IngTpl=""
    curBk=""
    curBkL=0

  End Sub
  'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

  'VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
  '生成输出处理完成后的结果
  'VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
  Public Function GetOutput()
    On Error Resume Next
    If NoBlocked Then FindBlock
    Execute bkNames()
    GetOutput=curTpl
  End Function

  Public Function Text()
    On Error Resume Next
    If NoBlocked Then FindBlock
    Execute bkNames()
    Text=curTpl
  End Function

  Public Function HTML()
    On Error Resume Next
    If NoBlocked Then FindBlock
    Execute bkNames()
    HTML=curTpl
  End Function

  Public Sub Pump()
    On Error Resume Next
    If NoBlocked Then FindBlock
    Execute bkNames()
    Response.Write curTpl
  End Sub

End Class

Class clsLxxTPLStrCat
  Private aFStrings()
  Private iFSPos,iFSLen,iFSIncr
  Private Sub Class_Initialize()
    Reset
  End Sub
  Private Sub Class_Terminate()
    Erase aFStrings
  End Sub
  Public Property Let Item(ByRef sData)
    If iFSPos > iFSLen Then
      iFSLen = iFSPos + iFSIncr
      ReDim Preserve aFStrings(iFSLen)
    End If
    aFStrings(iFSPos) = sData
    iFSPos = iFSPos + 1
  End Property
  Public Default Property Get Item()
    Item = Join(aFStrings, "")
  End Property
  Public Sub Reset()
    iFSPos = 0
    iFSIncr = 100
    iFSLen = iFSIncr
    ReDim aFStrings(iFSLen)
  End Sub
End Class

%>
[/quote]

回复列表 (共1个回复)

沙发

测试代码:
[quote]
<!--#INCLUDE FILE="clsLxxTPL.asp"-->
<%
Dim a,b,c,i,o,startime
startime=Timer

Set a=New clsLxxTPL
Set b=New clsLxxTPL
Set c=New clsLxxTPL
a.LoadFile "tpl_src2.htm"
b.LoadStr a.GetSub(1)
c.LoadStr a.GetSub(2)

c.Go ""

For i=500 To 1 Step -1
  c.Go "blockD"
  c("var1")="a"&i
  c.Add
Next
b.Go "blockC"
b("blockD")=c.Text
b.Add

c.Reset
For i=500 To 1 Step -1
  c.Go "blockD"
  c("var1")="b"&i
  c.Add
Next
b.Go "blockC"
b("blockD")=c.Text
b.Add


'公共标签要先替换
a("pub")="color:blue"

a.Go "" '仅处理外部

'不在区块中的标签可以先替换
a("title")="高性能单层循环模板类(新)"

a("var2")="版权所有 领星动网 www.lxasp.com (200704)"

a.Go "blockA"
a("blockC")=b.Text
a.Add

'另外一种使用方法:
'For i=1000 To 1 Step -1
'  a.Rep "blockB",Array("var1","var2"),Array(i,i)
'Next

For i=1000 To 1 Step -1
  a.Go "blockB"
  a("var1")=i
  a("var2")=i
  a.Add
Next

a("var1")=FormatNumber((Timer-startime)*1000,3)

o=a.Text
Response.Write o

Set a=Nothing
%> 
[/quote]

模板文件:
[quote]
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<title>{=title}</title>
</head>

<body>

{=var1}

<table width="100%" border="1">
{%[ blockA %}  <tr>
    {=blockC}
  </tr>
{%] blockA %}
{%[ blockB %}  <tr style="{=pub}">
    <td>{=var1}</td>
    <td>{=var2}</td>
  </tr>
{%] blockB %}
</table>

{=var2}

</body>
</html>
<!--/*ExtraSubLevel*/-->
{%[ blockC %}<th>{=blockD}</th>
{%] blockC %}
<!--/*ExtraSubLevel*/-->
{%[ blockD %}<div style="color:red">{=var1}</div>{%] blockD %}
[/quote]

我来回复

您尚未登录,请登录后再回复。点此登录或注册