《拓文asp.net网站内容管理系统》官方演示站。
 设为首页  
 收藏本站
 作者:黄振安
 QQ:53854651
首 页 开源拓文.NET编程网站编程网页设计图形图像数据库软件工程留言本
    站内搜索:  
您现在的位置: 拓文网络 → 网站编程 → ASP → 使用模板实现ASP代码与页面分离[正文]

热 门 文 章

相 关 文 章
  • ASP.NET性能优化
  • ASP脚本循环语句
  • 在.NET框架应用程序中发送电子邮件
  • .net打包自动安装数据库
  • asp.net开发wap必备:更好的匹配手机设备
  • 用ashx动态生成文件
  • windows 2003下asp.Net站点无法使用用户名+密码的方
  • ASP.NET中17种正则表达式
  • 提高ASP.Net应用程序性能的十大方法
  • 一个通过web.Mail发送邮件的类
  • 使用模板实现ASP代码与页面分离
     
    [作者:不详    转贴自:不详    点击数:    更新时间:2006-3-14 9:11:56]

    每个进行过较大型的ASP-Web应用程序设计的开发人员大概都有如下的经历:ASP代码与页面HTML混淆难分,业务逻辑与显示方式绞合,使得代码难以理解、难以修改;程序编写必须在美工之后,成为项目瓶颈;整合的程序代码和HTML静态页面时,花费大量的时间才能得到理想的效果,兼作了美工。的确,用脚本语言开发Web应用不容易将数据的处理和数据的显示分开,但在多人合作的情况下,如果无法将数据和显示分开,将大大影响开发的效率,专业分工的发挥。
      其它的脚本语言,如JSP、PHP都有自己的解决方案,ASP的后一代产品ASP.NET也实现了代码与页面,似乎直接过渡到ASP是不错的选择。但是总有这样或那样的原因让我们不能或暂时不能放弃ASP直奔.NET大营。从公司角度来看,转换语言是一笔不少的投资,包括雇佣熟手.NET程序员、培训原有程序员、开发工具的转型、开发风格的转型、界面风格转变、接口风格、软件架构、文档、开发流程等等;这还意味着原有的代码必须在新语言环境里重写以实现最佳的效果和稳定性;同时将直接影响这段时间内项目的进度,更有可能导致个别程序员出走。由此看来在您决定转换语言之前,在原基础上寻求一种解决方案,才是最好的选择。
      PHP通过模板实现代码与页面,可供选择的有FastTemplate、PHPLIB、Smarty等多种,其中PHPLIB的影响最大、使用最多。既然如此,我们直接把它搬到ASP来,对于同时使用PHP和ASP的公司还有很有好处:一、美工处理页面时,不管将要套用PHP还是ASP,处理方式是一样,无须经过培训;二、程序员编写代码时,两种语言间的思路接近或一致,相同功能在两种语言实现时,只需拷贝过来略作修改即可,保证了工作效率和项目进度。

    1、模板类的设计
      实现代码封装成为模板类,即是为了与PHPLIB兼容,也使得代码方便管理与扩展。
      模板类要实现的目标为:从模板文件中读入显示的HTML代码,将这些显示代码中需要动态数据的地方替换为ASP程序运算所得出的数据,然后按照一定的顺序输出。其中,替换的部分可以自由的设定。因此它必须完成如下任务:
        ·从模板文件中读取显示用的HTML代码。
        ·将模板文件和实际生成的数据结合,生成输出的结果。
        ·允许同时处理多个模板。
        ·允许模板的嵌套。
        ·允许对模板中的某个单独的部分进行处理。

    实现方法:
        采用FSO读取模板文件
        采用正则替换实现模板文件和数据的结合
        处理多个模板用数组存储来实现。
        模板的嵌套的实现主要的想法是:将模板和输出(任何中间的分析结果)一视同仁,都可拿来做替换,即可实现。
        单独部分的处理的通过在模板文件中设定标注,然后在正则替换中结合标注来控制,实现部分替换。

    2、模板类的实现
      给出具体代码之前,先把主要函数列出,用过PHPLIB的朋友应该对此很熟悉了:
      1)Public Sub set_root(ByVal Value) 设定模板默认目录
      2)Public Sub set_file(ByVal handle,ByVal  filename) 读取文件
      3)Public Sub set_var(ByVal Name, ByVal Value, ByVal Append) 设置映射数据-替换变量
      4)Public Sub unset_var(ByVal Name) 取消数据映射
      5)Public Sub set_block(ByVal Parent, ByVal BlockTag, ByVal Name) 设置数据块
      6)Public Sub set_unknowns(ByVal unknowns) 设定未指定映射的标记处理方式
      7)Public Sub parse(ByVal Name, ByVal BlockTag, ByVal Append) 执行模板文件与数据的结合
      8)Public Sub p(ByVal Name) 输出处理结果

    实现代码:
    <%
    '=======================================================================
    ' CLASS NAME:  kktTemplate ASP页面模板对象
    ' DESIGN BY :  彭国辉
    ' DATE:        2004-07-05
    ' WEBSITE:     http://kacarton.yeah.net/
    ' EMAIL:       kacarton@sohu.com
    '
    ' 本对象中使用了set_var、set_block等命名方法是为了兼容phplib
    '=======================================================================

    Class kktTemplate
       
        Private m_FileName, m_Root, m_Unknowns, m_LastError, m_HaltOnErr
        Private m_ValueList, m_BlockList
        Private m_RegExp   
        ' 构造函数
        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
       
        ' 析构函数
        Private Sub Class_Terminate
            Set m_RegExp       = Nothing
            Set m_BlockMatches = Nothing
            Set m_ValueMatches = nothing
        End Sub
       
        Public Property Get ClassName()
            ClassName = kktTemplate
        End Property
       
        Public Property Get Version()
            Version = 1.0
        End Property
       
        Public Sub About()
            Response.Write(kktTemplate ASP页面模板类<br> & vbCrLf &_
                           程序设计:彭国辉 2004-07-05<br> & vbCrLf &_
                           个人网站:<a href='http://kacarton.yeah.net'>http://kacarton.yeah.net</a><br> & vbCrLf &_
                           电子邮件:<a href='mailto:kacarton@sohu.com'>kacarton@sohu.com</a><br>)
        End Sub
       
        '检查目录是否存在
        Public Function FolderExist(ByVal path)
            Dim fso
            Set fso = CreateObject(Scripting.FileSystemObject)
            FolderExist = fso.FolderExists(Server.MapPath(path))
            Set fso = Nothing
        End Function
        '读取文件内容
        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(模板文件 & m_FileName & 不存在!)
            set hndFile = fso.OpenTextFile(Filename)
            LoadFile = hndFile.ReadAll
            Set hndFile = Nothing
            Set fso = Nothing
            If LoadFile = Then ShowError(不能读取模板文件 & m_FileName & 或文件为空!)
        End Function
       
        '处理错误信息
        Private Sub ShowError(ByVal msg)
            m_LastError = msg
            Response.Write <font color=red style='font-size;14px'><b>模板错误: & msg & </b></font><br>
            If m_HaltOnErr Then Response.End
        End Sub
       
        '设置模板文件默认目录
        'Ex: kktTemplate.set_root(/tmplate)
        '    kktTemplate.Root = /tmplate
        '    root = kktTemplate.get_root()
        '    root = kktTemplate.Root
        '使用类似set_root这样的命名方法是为了兼容phplib,以下将不再重复说明
        Public Sub set_root(ByVal Value)
            If Not FolderExist(Value) Then ShowError(Value & 不是有效目录或目录不存在!)
            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 Get Root()
            Root = m_Root
        End Property
       
        '设置模板文件
        'Ex: kktTemplate.set_file(hndTpl, index.htm)
        '本类不支持多模板文件,handle为兼容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
       
        '设置对未指定的标记的处理方式,有keep、remove、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+-->([\s\S.]*)<!--\s+END & BlockTag & \s+-->
            If Not m_BlockList.Exists(Parent) Then ShowError(未指定的块标记 & 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(未指定的 块标记 & 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 = \{[^ \t\r\n}]+\}
                    finish = m_RegExp.Replace(content, )
                Case comment
                    m_RegExp.Pattern = \{([^ \t\r\n}]+)\}
                    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(不存在的标记 & Name)
            Response.Write(finish(m_ValueList.Item(Name)))
        End Sub
    End Class
    %>

    3、使用例子
      下面举三个例子进行说明。
    1)简单的值替换
    模板文件为myTemple.tpl,内容:
    <html><title>ASP模板简单替换</title><body>
    祝贺!你赢了一辆{some_color}法拉利!
    </body>

    下面是ASP代码(kktTemplate.inc.asp就是上面给出的模板类):
    <!--#INCLUDE VIRTUAL=kktTemplate.inc.asp-->
    <%
    dim my_color, kkt
    my_color = 红色的
    set kkt = new kktTemplate                 '创建模板对象
    kkt.set_file hndKktTemp, myTemple.tpl '设置并读取模板文件myTemple.tpl
    kkt.set_var some_color, my_color, false '设置模板变量 some_color = my_color的值
    kkt.parse out, hndKktTemp, false      '模板变量 out = 处理后的文件
    kkt.p out                               '输出out的内容
    set kkt = nothing                         '销毁模板对象
    %>

    执行后输出为:
    <html><title>ASP模板简单替换</title><body>
    祝贺!你赢了一辆红色的法拉利!
    </body>


    2)循环块演示例子
    模板文件myTemple2.tpl:
    <html><title>ASP模板-块的演示</title><body>
    <table cellspacing=2 border=1><tr><td>下面的动物您喜欢哪一种</td></tr>
    <!-- BEGIN AnimalList -->
    <tr><td><input type=radio name=chk>{animal}</td></tr>
    <!-- END AnimalList -->
    </table>
    </body>

    ASP代码:
    <!--#INCLUDE VIRTUAL=kktTemplate.inc.asp-->
    <%
    dim animal, kkt, i
    animal = Array(小猪,小狗,小强)
    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
    %>
     
    执行结果:
    <html><title>ASP模板-块的演示</title><body>
    <table cellspacing=2 border=1><tr><td>下面的动物您喜欢哪一种</td></tr>
    <tr><td><input type=radio name=chk>小猪</td></tr>
    <tr><td><input type=radio name=chk>小狗</td></tr>
    <tr><td><input type=radio name=chk>小强</td></tr>
    </table>
    </body>
                                           

    3)嵌套块演示
    模板文件myTemple3.tpl:
    <html><title>ASP模板-嵌套块演示</title>
    <body><table width=400 border=1 bordercolor=#000000>
      <tr><td><div align=center>{myname}测试</div></td></tr>
      <tr><td>我的动植物园:</td> </tr>
    <!-- BEGIN animalList -->
      <tr><td>{animal}</td></tr>
      <!-- BEGIN plantList -->
        <tr><td>&nbsp;&nbsp;{plant}</td></tr>
      <!-- END plantList -->
    <!-- END animalList -->
    </table>
    </body>
    </html>

    ASP代码:
    <!--#INCLUDE VIRTUAL=kktTemplate.inc.asp-->
    <%
    dim my_color, kkt, myname, animal, plant
    set kkt = new kktTemplate
    myname = kktTemplate block test...
    animal = array(动物, 植物)
    plant  = array(array(小猪,小白,小强), array(玫瑰,向日葵))

    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
    %>

    执行结果:
    <html><title>ASP模板-嵌套块演示</title>
    <body><table width=400 border=1 bordercolor=#000000>
      <tr><td><div align=center>kktTemplate block test...测试</div></td></tr>
      <tr><td>我的动植物园:</td> </tr>
      <tr><td>动物</td></tr>
        <tr><td>&nbsp;&nbsp;小猪</td></tr>
        <tr><td>&nbsp;&nbsp;小白</td></tr>
        <tr><td>&nbsp;&nbsp;小强</td></tr>
      <tr><td>植物</td></tr>
        <tr><td>&nbsp;&nbsp;玫瑰</td></tr>
        <tr><td>&nbsp;&nbsp;向日葵</td></tr>
    </table>
    </body>
    </html>


    首页 | 1 | 尾页  共 1 页
     
    hch004 打印本页 关闭窗口

         文 章 评 论
    评论人 查看该文章的评论 发表时间
       笔 名* : 0 50分 60分 70分 80分 90分 100分
    评论内容 *: (最多1000字。当前字数:0)


    没有相关评论,欢迎您参与!

    - 关于本站 - 网站帮助 - 下载声明 - 友情连接 - 网站地图 -
    Copyright © 2005-2006 myTopWin.Com. All Rights Reserved . [桂ICP备06004496号]