使用模板实现ASP代码与页面分离
上一篇 / 下一篇 2007-09-03 14:08:59 / 个人分类:ASP
*o;z,{is2Q0 每个进行过较大型的ASP-Web应用程序设计的开发人员大概都有如下的经历:ASP代码与页面HTML混淆难分,业务逻辑与显示方式绞合,使得代码难以理解、难以修改;程序编写必须在美工之后,成为项目瓶颈;整合的程序代码和HTML静态页面时,花费大量的时间才能得到理想的效果,兼作了美工。的确,用脚本语言开发Web应用不容易将数据的处理和数据的显示分开,但在多人合作的情况下,如果无法将数据和显示分开,将大大影响开发的效率,专业分工的发挥。
CH A'QVm"`4C0 其它的脚本语言,如JSP、PHP都有自己的解决方案,ASP的后一代产品ASP.NET也实现了代码与页面,似乎直接过渡到ASP是不错的选择。但是总有这样或那样的原因让我们不能或暂时不能放弃ASP直奔.NET大营。从公司角度来看,转换语言是一笔不少的投资,包括雇佣熟手.NET程序员、培训原有程序员、开发工具的转型、开发风格的转型、界面风格转变、接口风格、软件架构、文档、开发流程等等;这还意味着原有的代码必须在新语言环境里重写以实现最佳的效果和稳定性;同时将直接影响这段时间内项目的进度,更有可能导致个别程序员出走。由此看来在您决定转换语言之前,在原基础上寻求一种解决方案,才是最好的选择。51Testing软件测试网n3uM8~u&r Y;w;rQ
PHP通过模板实现代码与页面,可供选择的有FastTemplate、PHPLIB、Smarty等多种,其中PHPLIB的影响最大、使用最多。既然如此,我们直接把它搬到ASP来,对于同时使用PHP和ASP的公司还有很有好处:一、美工处理页面时,不管将要套用PHP还是ASP,处理方式是一样,无须经过培训;二、程序员编写代码时,两种语言间的思路接近或一致,相同功能在两种语言实现时,只需拷贝过来略作修改即可,保证了工作效率和项目进度。
*E h#QA'\T|9M@+`0
us%L)`*lK01、模板类的设计51Testing软件测试网
bK{,?X
实现代码封装成为模板类,即是为了与PHPLIB兼容,也使得代码方便管理与扩展。
4c%^*o(P9VF7{:Ll0 模板类要实现的目标为:从模板文件中读入显示的HTML代码,将这些显示代码中需要动态数据的地方替换为ASP程序运算所得出的数据,然后按照一定的顺序输出。其中,替换的部分可以自由的设定。因此它必须完成如下任务:
pm ~N{[(Dp0·从模板文件中读取显示用的HTML代码。51Testing软件测试网UG
?h6[I x
·将模板文件和实际生成的数据结合,生成输出的结果。51Testing软件测试网'B\l5L&S
·允许同时处理多个模板。51Testing软件测试网:y k!H\*ZW_| NM
·允许模板的嵌套。51Testing软件测试网!}
s E%\B:Vc5L1t
·允许对模板中的某个单独的部分进行处理。51Testing软件测试网8WNs8TQ,b
}
|y#cS5}~OD~0实现方法:
K&XoND*P0采用FSO读取模板文件
XZwD_ol0采用正则替换实现模板文件和数据的结合
5XT'd&WP7^0处理多个模板用数组存储来实现。51Testing软件测试网O0}z6Gtv
模板的嵌套的实现主要的想法是:将模板和输出(任何中间的分析结果)一视同仁,都可拿来做替换,即可实现。
.M.}N6JD5Az ]0单独部分的处理的通过在模板文件中设定标注,然后在正则替换中结合标注来控制,实现部分替换。51Testing软件测试网+J+dSe3Hs$yO
eI1i9F~8l8nF.@02、模板类的实现51Testing软件测试网~(ZW3SEk;{Gk6Z
给出具体代码之前,先把主要函数列出,用过PHPLIB的朋友应该对此很熟悉了:51Testing软件测试网1qfd&e4}
1)Public Sub set_root(ByVal Value) 设定模板默认目录
R ~q
?Mx*n k3Jg0 2)Public Sub set_file(ByVal handle,ByVal filename) 读取文件51Testing软件测试网z:aA2Y1^a3}
3)Public Sub set_var(ByVal Name, ByVal Value, ByVal Append) 设置映射数据-替换变量
Efx"M4`:aa"_!f*NS0 4)Public Sub unset_var(ByVal Name) 取消数据映射51Testing软件测试网9H1D]+QH
5)Public Sub set_block(ByVal Parent, ByVal BlockTag, ByVal Name) 设置数据块
u!\D$oz}.]{f0 6)Public Sub set_unknowns(ByVal unknowns) 设定未指定映射的标记处理方式51Testing软件测试网PH(?5V&YOE
7)Public Sub parse(ByVal Name, ByVal BlockTag, ByVal Append) 执行模板文件与数据的结合51Testing软件测试网
F8p|,Ef.a
8)Public Sub p(ByVal Name) 输出处理结果
5a)ef-YYD'h0JJ0
r4~.G'I$zf(S$y+gg!x0实现代码:51Testing软件测试网4a@3a
f
ll\
<%
q8t5h mm%Z3x
E M6^0'================================================================
,l#^6OXh zNS0' CLASS NAME: kktTemplateASP页面模板对象
8hF2T$\*}P0' DESIGN BY : 彭国辉
3@)tb'EH$B(Ux1L0' DATE: 2004-07-05
2c6{
A4G6g5b ou0' WEBSITE: http://kacarton.yeah.net/51Testing软件测试网 d%[jC[d{(]'AM
' BLOG: http://blog.csdn.net/nhconch51Testing软件测试网G'h)cO~6V-V
' EMAIL: kacarton@sohu.com51Testing软件测试网!PLkl\"N*X
'
?jE0G5]KZ0' 本对象中使用了set_var、set_block等命名方法是为了兼容phplib
(BnP7px0'文章为作者原创,转载前请先与本人联系,转载请注明文章出处、保留作者信息,谢谢支持!51Testing软件测试网O_D_v;e
'================================================================51Testing软件测试网*n*~1s(~ q{
t
51Testing软件测试网)YdV6[7w3Pf5Ma
Class kktTemplate
M8J4ZFR#M:L*PQ051Testing软件测试网xG}ap6u}G
Private m_FileName, m_Root, m_Unknowns, m_LastError, m_HaltOnErr51Testing软件测试网Pd3~4nZb5G^(M
Private m_ValueList, m_BlockList51Testing软件测试网p I)AV\&itM~ dQ
Private m_RegExp51Testing软件测试网'h+y"y|1G6[
' 构造函数51Testing软件测试网0F-LyX!Mi}MQ I
Private Sub Class_Initialize
;I0t'`0K*O L0Set m_ValueList = CreateObject("scrīpting.Dictionary")
|Y"`0S(pt2Z8u B0Set m_BlockList = CreateObject("scrīpting.Dictionary")
1D6sr9[0yAXTQ0set m_RegExp = New RegExp51Testing软件测试网TU#^|5n
m_RegExp.IgnoreCase = True51Testing软件测试网K$f7Ltxt
m_RegExp.Global = True
tK
Lp2R|0m_FileName = ""51Testing软件测试网.N1}]9yy8xa QXA
m_Root = ""
M \(s~)` t b-C9p:`9~0m_Unknowns = "remove"
qa$ON/?0m_LastError = ""
$z$P;GI0M;r_ dV^0m_HaltOnErr = true51Testing软件测试网 y8n
jf%Y J
End Sub51Testing软件测试网%l4MqJ gr7B}0Y
+yi/Ob
[\r,t2x0' 析构函数
r u?.Y!Q[/u8G0Private Sub Class_Terminate
h#qUTN J'vO_EP0Set m_RegExp = Nothing
Q"t}*~U5c0Set m_BlockMatches = Nothing51Testing软件测试网0mxt%b7d?M,hv
Set m_ValueMatches = nothing51Testing软件测试网Iog3bm:e
End Sub51Testing软件测试网Q CQY7VU
%g/[RzLXJi XS2gS0Public Property Get ClassName()
1Ft9F,~;w5Tsc#G%Q0ClassName = "kktTemplate"
Jx0[cIr,Ec3j0End Property51Testing软件测试网+z]"iJ8f!WS
51Testing软件测试网L,o9Mj Gx)]n
Public Property Get Version()51Testing软件测试网,g(S~!@"cz*hF
y6LY
Version = "1.0"
(D;TZjK)I?
I&Ig0End Property
/J,kleKg051Testing软件测试网'v)UO7zt p*E
m4Q
Public Sub About()51Testing软件测试网lwW`R2y
Response.Write("kktTemplateASP页面模板类<br>" & vbCrLf &_
,^zw:e;W
d b/f0"程序设计:彭国辉 2004-07-05<br>" & vbCrLf &_51Testing软件测试网6?Ii#b3|X:qlT
"个人网站:<a href='http://kacarton.yeah.net'>http://kacarton.yeah.net</a><br>" & vbCrLf &_
+oz1^3f4T}mtS0"电子邮件:<a href='mailto:kacarton@sohu.com'>kacarton@sohu.com</a><br>")
6X.DD,LM3CfGx0End Sub51Testing软件测试网;h,DG/d4a
AH{^lc
\0'检查目录是否存在51Testing软件测试网1S+_-^+N:^h(@#U
Public Function FolderExist(ByVal path)
i,a6Y
_"E6Mw2{0Dim fso
/n+G8Gqe-A@0Set fso = CreateObject("scrīpting.FileSystemObject")
9zc]7B"l#u^
j0FolderExist = fso.FolderExists(Server.MapPath(path))51Testing软件测试网&\:~dZG
Set fso = Nothing
a;h8Pq#Zs$]b0End Function
j%`\V:FO:y^:\4p0'读取文件内容
m-TmV3Tw y{rA0Private Function LoadFile()51Testing软件测试网'oWT-r&FH2k)F
Dim Filename, fso, hndFile
d/msGfjI*kvt$~0Filename = m_Root51Testing软件测试网5ni7T^-a&o*l"}
If Right(Filename, 1)<>"/" And Right(Filename, 1)<>"\" Then Filename = Filename & "/"
"z)J{i'C0Filename = Server.MapPath(Filename & m_FileName)51Testing软件测试网&l!j9UfBZ~
Set fso = CreateObject("scrīpting.FileSystemObject")51Testing软件测试网 Fn-S}"q.u
If Not fso.FileExists(Filename) Then ShowError("模板文件" & m_FileName & "不存在!")51Testing软件测试网0Z(|Vn`:y2Zj
set hndFile = fso.OpenTextFile(Filename)51Testing软件测试网0gE |N6j0w
LoadFile = hndFile.ReadAll
;MG*x9[s7r0Set hndFile = Nothing51Testing软件测试网
HY-pXuK ~
Qj
Set fso = Nothing51Testing软件测试网qG]0jff
If LoadFile = "" Then ShowError("不能读取模板文件" & m_FileName & "或文件为空!")
~/l/d}q8twcrS0End Function
5HN]l:{'DeU0
T4T
l'aTz+D$se&e0'处理错误信息
6q#xWYKF
}uW o0Private Sub ShowError(ByVal msg)
TbW%`Vz0m_LastError = msg
'J~(b4e0m{4J3?0Response.Write "<font color=red style='font-size;14px'><b>模板错误:" & msg & "</b></font><br>"
{u9OP(W0If m_HaltOnErr Then Response.End
lhA0BJ)If)[0End Sub
-k(H#p
F6f/`t4H U;@0
iPrW5V|kyn:Y0'设置模板文件默认目录
|Lk9jB7l/BCn0'Ex: kktTemplate.set_root("/tmplate")
yZT1xs,f.\!P0' kktTemplate.Root = "/tmplate"
7Gg
_uUj0' root = kktTemplate.get_root()51Testing软件测试网bu{1H@+y
' root = kktTemplate.Root
L$z5F
vdJV,zY"VS0'使用类似set_root这样的命名方法是为了兼容phplib,以下将不再重复说明51Testing软件测试网f#D4C$ARK\K
Public Sub set_root(ByVal Value)
!i$G#w!X Ef$p+`0If Not FolderExist(Value) Then ShowError(Value & "不是有效目录或目录不存在!")51Testing软件测试网-P(gZDJBw
m_Root = Value51Testing软件测试网E4w(E
Wz6_ VK
End Sub51Testing软件测试网#l+OU!Ed4FJs6U
Public Function get_root()
mG
t%V
{7I5PQ0get_root = m_Root
pWSA4YY6X,NzU0End Function51Testing软件测试网 z(N~9}/G"K
Public Property Let Root(ByVal Value)
u2[!G?4n2Pa:x0set_root(Value)
V4T,V([#K4TN0End Property51Testing软件测试网+T%`;map3j
Public Property Get Root()51Testing软件测试网fCe}i
f \3w
Root = m_Root
k!WVBf
?%m$R4im0End Property
Sb
@ R&D:{W$I051Testing软件测试网OtZv2rA
'设置模板文件
+E dY
[6J"{7Y&e7K0'Ex: kktTemplate.set_file("hndTpl", "index.htm")51Testing软件测试网 N5Z!Q|nX
'本类不支持多模板文件,handle为兼容phplib而保留51Testing软件测试网2e.|pUR+b#jZ
Public Sub set_file(ByVal handle,ByVal filename)
7D.eF4jOt.P0m_FileName = filename51Testing软件测试网v]+O"@.]/p M
m_BlockList.Add Handle, LoadFile()