分享
 
 
 

模板用xml的思路

王朝other·作者佚名  2006-11-24
窄屏简体版  字體: |||超大  

前段时间,一直比较关心php的模板技术的我,接到了客户的要求:全站利用模板技术,可以控制多模板,这个项目要求有强大的后台,主要是多模板,难点就在模板的导入和识别并且生成上,我仔细考察了php的模板核心技术,无外乎查找字符串开始,然后定义替换变量,替换成数据,然后并成输出页输出,牵扯到的缓存我就不再说了.

我们来看看这种方式的生成方式的缺点:如果要"多样式"的显示数据,当然我先不说CSS,不能真正的把数据和表示分离,无外乎利用css样式表方式显示而已,我们现在接到的这个项目不但要求css样式表的可选化,而且要求数据显示的"多方式",打个比方,看下图:

我们下面为了容易描述期间,我这样表示各个部分:A,B,C,D,E,F,G这6个区可以表示数据显示区域,从设计者角度考虑,有全局(div控制A-G),TOP(A),LEFT(B),RIGHT(C,D,E,F)和FOOTER(G),当然,您可以分的更细一些,这么显示,可以用div控制的,但这不是模板技术,请明白,多样式表不叫模板,这和模板无关,所谓的模板,就是只与"数据布局"相关,在A数据我们另外可以表示成一个导航,如果您喜欢的话.这在传统的模板技术中会这样写:

...

<div id="top">

{$SITE_TOP$}//cjjer制作

</div>

...

替换的时候replace()的是{$ 和$}符号中的变量,这在数据简单的时候,比方只是一个导航,而我们如果要的是一个很复杂的数据显示的时候,那就很难控制了,因为把一个很大量输出数据放在一个变量中很难保证不出错.

另外,传统的模板(在php中)是这样的,获取模板的文件,加载,显示,这没什么问题,问题就在当web项目(不完全是网站)非常复杂的时候,很容易替换错误和模板单调,虽然可以用css控制一些显示,但很难控制数据的布局,比方,E区我今天不想要了,你改模板,重新加载文件... ?

有没有更加容易的解决方案?有.

我提出了这样一种观点:

模板页为 XML文档 ,模板节点加载已有模块 ,加载"仿xml数据"生成文件 (原谅我,这么说我觉得已经非常容易了)下面我就这种模板技术详谈.

先看看我说的模块是什么东西,大家都知道,html中的<div>呀,<table>都是显示数据布局的一些布局标签,为什么我们不能自己制作这种标签呢?例如:我现在"创"一个这样的标签<format>这里,当然,这个标签对项目是有意义的,表示控制全局的模块节点,如果在模板页中出现节点<format>加载的就是对应名称为 format 的模块数据:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3c.org/TR/1999/REC-html401-19991224/loose.dtd">

<HTML xmlns="http://www.w3.org/1999/xhtml">

<head>

<title>[%TITLE%]</title>

<meta http-equiv="content-type" content="text/html; charset=gb2312" />

<meta http-equiv="Content-Language" content="zh-CN" />

<meta name="author" content="[%AUTHOR%]" />

<meta name="copyright" content="[%COPYRIGHT%]" />

<meta name="description" content="[%DESCRIPTION%]" />

<meta name="keywords" content="[%KEYWORDS%]" />

<link href="styles/[%STYLES%]/import.css" rel="stylesheet" type="text/css" />

</head>

<body>

<div id="format">

&%format%&

</div>

</body>

</html>

这里我把这个模板节点定义成 加载控制全局的html源了,再看这个标签topdata:

<div id="topdata">{%TOP_MESS%}<%=show_top_meun()%></div>

如果这个节点被加载,生成的文件里面会将topdata节点替换成如上的html文档模板,这就是模块

这里的模块也可以是xml文档,重复加载模块,也可以是终数据.

当这些还有模块节点的xml模板被加载以后,就被程序识别,对应的加载成html二级模块,然后提出我们的"仿xml 数据"标记中的数据,正则替换对应的节点,生成文件,这里的"仿xml数据"是这种方式的数据:

{%TITLE%}<%=cjjer_hometitle%>{%/TITLE%}

{%STYLE%}default{%/STYLE%}

{%site_top%}<%=get_cache(0)%>{%/site_top%}

{%format_two%}<div id="footer_ul"><%Call light()%></div>

{%/format_two%}

{%site_footer%}<%Call cc_footer()%>{%/site_footer%}

这里,您可能马上理解了我说的"仿xml数据"了,这种加载数据的方式也是xml分析节点,然后直接正则替换,当然可以include文件的(asp,php).

好了,现在您想必概念已经很清楚了,(不清楚的话重新看上面的话,或看如下的例子)

我就举个举个简单的例子说明一下(format_index.xml):

<format>

<site_top>{%site_top%}</site_top>

<format_two>

<home_bigflash>{%home_bigflash%}</home_bigflash>

{%format_two%}

</format_two>

<site_footer>{%site_footer%}</site_footer>

</format>

模块:

//format,就是最上面的那个,不列举了

//home_bigflash

<div id="main_img">

<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/

swflash.cab#version=6,0,29,0" width="100%">

<param name="movie" value="images/main.swf">

<param name="wmode" value="transparent">

<param name="quality" value="high">

<embed src="images/main.swf" quality="high" pluginspage="http://www.macromedia.com/go/getflashplayer" type="application/x-shockwave-flash" width="100%"></embed>

</object>

</div>

//format_two

<div id="format_two">(&format_two&)<script language="javascript" type="text/javascript" src="js/same_h2.js"></script> </div>

//site_footer

<div id="site_footer">(&site_footer&)</div>

差不多应该加载的模板和模块就这点吧(都是可以重用的.)

现在是程序处理:

<%

'根据输入判断输出是名称还是数据

Function geturlxml(outfile,mode)

geturlxml=False

If outfile="" Then Exit Function

Dim tab

Select Case killint(mode,0,0,2)

Case 0:tab="szd_tpl"

Case 1:tab="szd_content"

End Select

Set rs=conn.execute("select ["&tab&"] FROM szd_asp where [szd_link]='"&outfile&"'")

If rs.eof And rs.bof Then

Exit Function

else

geturlxml=rs(tab)

End If

End Function

'提取include文件到原始的数据项中

Function getincludefile(x)

Dim regxml,html

html=""

Set regxml=new regexp

regxml.ignorecase=True

regxml.global=True

regxml.pattern="(<!--#include)(\s)(file|virtual)(=)(\u0022)([a-zA-Z][A-Za-z0-9_/]{0,30})(.)(asp|inc|dll)(\u0022)(-->)"

Dim Matches,Match

Set Matches = regxml.Execute(x)

For Each Match in Matches

html=html&match.value

Next

getincludefile=html

End Function

'获取模板项,先判断输出,返回值是 html 形式的模板,参数是模板的名称

Function gettpl(url)

Dim mudule_file,xml_file,asp_file

xml_file=url

asp_file=gettpldata(xml_file,0)'由模板名称获取模板的内容

Dim loadxml,parsexml,nodes,node

Set loadxml = Server.CreateObject("MSxml2.DOMDocument")

loadxml.async=false

parsexml=server.mappath("../"&gettpldata(xml_file,10)&xml_file)'装载本地的xml文档,先到数据库取到路径

loadxml.load parsexml

Set nodes = loadxml.selectNodes("//*")

for each node in nodes

asp_file=insertaspinhtml(asp_file,gettpldata(node.nodename,1),node.nodename)'加载模块到模板,输出html模板

Next

gettpl=asp_file

End function

'匹配模板中的数据项

'把data中的数据传入html文件当中去

Function tpltodata(html,data)

Dim regxml

Set regxml=new regexp

regxml.ignorecase=True

regxml.global=True

regxml.pattern="({%)([a-zA-Z][A-Za-z0-9_]{2,60})(%})(.[^\[]*)({%/)\2(%})"

Dim Matches,Match

Set Matches = regxml.Execute(data)

For Each Match in Matches

html=Replace(html,"{%"&regxml.Replace(match.value,"$2")&"%}",regxml.Replace(match.value,"$4"))

Next

tpltodata=html

End Function

'geturlxml 传入参数模板名称,返回模板的内容,失败的时候返回 null

Function geturlxml(outfile)

geturlxml=Null

If outfile="" Then Exit Function

Set rs=conn.execute("select [szd_tpl] FROM szd_asp where [szd_link]='"&outfile&"'")

If rs.eof And rs.bof Then

Exit Function

else

geturlxml=rs("szd_tpl")

End If

End Function

public Function gettpldata(url,mode)

'Set rs=server.CreateObject("server.adodbrecordset")

If Len(url)<1 Then Exit Function

Dim szd_keytpl

Select Case mode

Case 0:Set rs=conn.execute("select [szd_content] from szd_tpl where [szd_link]='"&url&"'")

Case 10:Set rs=conn.execute("select [szd_url] from szd_tpl where [szd_link]='"&url&"'")

Case 1:Set rs=conn.execute("select [szd_content] from szd_keytpl where [szd_key]='"&url&"'")

End Select

If Not(rs.eof And rs.bof) Then

szd_keytpl=rs(0)

Else

szd_keytpl="<div>{%nodefined%}</div>"

End If

gettpldata=szd_keytpl

End Function

'加载标记的模块到 xml 格式的模板中,输出html格式的模板,asp:xml格式模板,html:导入的模块,xmls:当前标记

Function insertaspinhtml(asp,html,xmls)

Dim regxml,temp,temps,tempasp,tempasp_e

[1] [2] 下一页

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有