做过两个ROC的皮肤了,说实话,对于普通的页面制作者来说,XSLT太过陌生,或许说陌生到有些神秘的程度,其实,在焦头烂额的制作过两个以后,发现其实在制作页面的时候完全不必考虑XSLT的具体语法,至于一些属性等,甚至都可以说参考原有皮肤或者参考语参即可。有几个朋友希望能有个教程,但多少有些为难我,第一组织这类技术性语言不是很擅长,第二其实我也不是很懂这个技术,只是有些小花招能够应付元素的一些移动换位,改变页面结构的事情。再多,就不行了,所以勉强按照当初我一点点的摸索理解的东西写了一片文章,希望能有点作用吧。
先来初步了解一下汤尼尔ROC4.0的皮肤结构吧。

从上图可以看到,洛克龙阁4.0的这款博客皮肤由以上几个部分组成。
- 文件夹 include 里存放有一个共享页面 UI.XSL ,这个页面在整套模版中至关重要。他包含了侧边栏,头部栏,底部版权栏,还有评论列表,留言列表。
- 文件夹script中是存放皮肤所有的脚本语言的,例如AJAX,jQuery.js还有所有的提示信息,包括我们留言时候判别等。
- 文件夹style中存放了两个.CSS文件和IMAGES文件夹,这基本不用说了,分别是站点的样式,弹出图片的样式和整个皮肤的SKIN图片。
- XML文件夹,说实话,这个文件夹里的东西没有深究过,也不是很理解,自己感觉应当是每个版面的设计到判别返回结果的一个过程,应该和SCRIPT中Common.JS有着紧密的联系,当然这个我不确认。也不太会影响到皮肤的制作。
下来就是皮肤下的几个页面了,仔细看过的自不用多说,对于刚上手试着做小汤的博客皮肤者,稍懂英文或者看看页面代码也可以知道页面的具体作用。介绍之前先说一句话,以下的每个页面,只针对该页面的主内容,也就是头部边栏等均是调用UI.XSL的内容根本不用考虑,所以,在构思好页面整体结构后,UI.XSL也写好后,制作这些页面只需要考虑我们所说的中段(也就是正文区。对于留言板和评论更特殊,只需要考虑发表留言的表单即可)。
- Article_List,这个就是日志列表页,也就是博客的首页了,需要我们定义日志列表的样式以及日志的一些参数等。
- Article_View,日志展示页,也就是具体的一篇文章的显示,里边包含了评论列表(这个在UI.XSL中)和发表评论等。
- Board_List,论版,就是留言板了,包含了留言列表(这个在UI.XSL中)和发表留言的表单。
- Fellow_List,友情链接,包含了友情链接列表。
- Page_View,新增页面,就是我们在后台增加一个页面后,这个就会被激活。
- Photo_Album,相册列表。
- Photo_List,相片列表。
- Tag_List,标签云集列表。
上边介绍了ROCLOG皮肤的一些构成部分,那么我们现在来了解一下页面中运用到得XSLT模版引擎技术,还是那句话,我对于XSLT的知识并未从知识角度去了解,充其量是遇到问题解决问题而已,在我的讲述中,希望大家能够明白“块”这个概念。整个皮肤其实就是由不同的块组成的,比如头部块,边栏块,正文块,正文块又包含了评论等块。那么来看看XSLT是怎样形成块的,看下图(图片来源于皮肤中的UI.XSL):

看到图片中我用红色方框选中的部分了吗?很明显,一个由XSLT标记构成的“块”形成了,它是以<xsl:template name="">开头以</xsl:template>结尾,这样的方式和XML的写法是一样的,或者说和HTML的标记一样,有起始代码,有闭合代码。为了方便说明,我把以上代码再用代码模式展现一下。
- <!--头部-->
- <xsl:template name="Top">
- <xsl:param name="Config"/>
- <xsl:param name="Setting"/>
- <xsl:param name="Pages"/>
- <div class="headBox">
- <div class="headTop" xml:space="preserve"> </div>
- <div class="headContent" xml:space="preserve">
- <xsl:value-of select="$Setting/Caption"/>
- </div>
- <div class="headFoot">
- <xsl:value-of select="$Setting/Intro"/>
- </div>
- </div>
- <div class="menuBox">
- <div class="menuTop" xml:space="preserve"> </div>
- <div class="menuContent">
- <ul>
- <li><a href="{$Config/AppPath}">首页</a></li>
- <li><a href="{$Config/AppPath}Board.aspx">讨论区</a></li>
- <li><a href="{$Config/AppPath}Photo.aspx">相册</a></li>
- <li><a href="{$Config/AppPath}Fellow.aspx">友情链接</a></li>
- <xsl:for-each select="$Pages">
- <li><a href="{$Config/AppPath}Page/{Page.Label}.aspx"><xsl:value-of select="Page.Title"/></a></li>
- </xsl:for-each>
- <li><a href="{$Config/AppPath}Tag.aspx">标签</a></li>
- <li><a href="{$Config/AppPath}Manage/Default.aspx">管理</a></li>
- </ul>
- </div>
- <div class="menuFoot" xml:space="preserve"> </div>
- </div>
- </xsl:template>
没有被红框包裹的就是头部的页面了,你可以单独的把头部的页面做成一个区域,比如我举例的代码是小汤发布的LAB_V4,他的都不包含了头部的图片和导航条等内容,那么你就可以把你做好的头部的整个包裹层放到这个块里,当然这其中涉及到一些调用数据的问题,看看小汤的代码,很多没有内容的空层你可以不用去管,完全按照你的设计习惯把该调用的数据的位置设计进去就行,像以上代码中的<div class="menufoot"></div>,我感觉是小汤为了方便别人修改样式,增加边角而预留的,自己做皮肤完全没有必要写入这些没有意义的层。好了,还是返回来看下代码吧,具体说下XSLT块的含义。
看下代码的第2行,<xsl:template name="Top">,这个就是块的开始,name就像ID或者CLASS,精确的说应该像ID,因为它具有唯一性,这个名字你可以在保证不和其他已有命名冲突的前提下自己命名,但是记得,在你需要调用的页面,如果你要调用这块内容,那么你的name就要和这个保持一致了,就好像我们使用INCLUDE一样,我们要给定调用的具体链接。再看代码的第3行到第5行,<xsl:param name="Config"/><xsl:param name="Setting"/><xsl:param name="Pages"/>,这里的name有着非常重要的作用,name里写的不是我们可以随意修改的,按照我的理解,这个应该是开发者定义个一个命名集,至于什么原理我也不懂,就好像JS中的函数,你需要调用什么数据,就要把你定义好的函数名写在这里,以告诉客户端,我要调用的是这个集合里的数据,拿name="config"来作比喻,我并不知道这个是用来干什么的,但是通过观察以上代码第20行到28行,我可以知道,如果我要调用导航的数据,那么我就需要在块的开始写上<xsl:param name="Setting"/>,因为导航调用时{$Config/AppPath}用到的是config这个集合里的数据,如果你不事先声明,那么程序并不知道你导航里的那些调用代码来源于何处。还记得我开始说的“块”的概念吗?你可以完全理解成块就是一个独立体。在这个块里,他不会影响到其他块,也不受其他块的影响,如果你想调用,那必须要把数据来源给明。OK,如果你能理解我上边说的一段话,那你就可以明白,头部调用的这部分,我们根本不需要必须把导航和网站标题等放到一起,我可以把他随便的放到我页面的任何部分。我们甚至可以把导航放到底部版权的下边,或者侧边栏中,我举例写一下。
- <xsl:template name="nav_my">
- <xsl:param name="Config"/>
- <xsl:param name="Pages"/>
- <div class="menuContent">
- <ul>
- <li><a href="{$Config/AppPath}">首页</a></li>
- <li><a href="{$Config/AppPath}Board.aspx">讨论区</a></li>
- <li><a href="{$Config/AppPath}Photo.aspx">相册</a></li>
- <li><a href="{$Config/AppPath}Fellow.aspx">友情链接</a></li>
- <xsl:for-each select="$Pages">
- <li><a href="{$Config/AppPath}Page/{Page.Label}.aspx"><xsl:value-of select="Page.Title"/></a></li>
- </xsl:for-each>
- <li><a href="{$Config/AppPath}Tag.aspx">标签</a></li>
- <li><a href="{$Config/AppPath}Manage/Default.aspx">管理</a></li>
- </ul>
- </div>
- </xsl:template>
OK了,我把导航单独定义成一个块了,为什么把PAGES也放到里面了呢,自己看下代码第10行就可以明白了,因为导航中涉及到了一个pages,我们就必须把它写进来,如果你不想写也可以,那么你就必须把第10行到第12行的代码扔掉,否则一准报错。第10行道第12行蛮有意思,你在纯手写的时候要注意,我不明白为什么这个功能需要单独的用一个<xsl:for-each select="$Pages"></xsl:for-each>包裹起来,反正肯定有用就对了。
好了,这下是否可以理解ui.xsl定义的这些块的方法了?如果你要完全脱离原来的模版结构制作新的模版结构,那么我的建议就是,像做一个普通的网页一样,规规矩矩的把你的页面单纯的用DIV+CSS写出来,然后观察你的代码,有哪些是可以放到一起的,哪些是要分开放的,哪些是所有版面或者多于一个页面会调用到得,观察好后,再开始规划你的UI.XSL和具体的页面,能放到一起的就写成一个块,不能放到一起的就单独的写一个块。然后把你的代码扔进去。这时候你要有一个清晰的思路,那就是,具体页面在调用的时候,是完全的把你这个块中的层和样式调用进来的,所以你只要把你做好的页面中的相应的层放到相应的块中即可。
好了,说完了UI.XSL了,那么我们来说一下每个页面的调用方式吧。还是以小汤的lab_v4这个模版为例,把article_list这个页面提出来做解说吧。还是以头部块来说明吧。
- <!--头部块-->
- <xsl:call-template name="Top">
- <xsl:with-param name="Config" select="Global.Config"/>
- <xsl:with-param name="Setting" select="Global.Setting"/>
- <xsl:with-param name="Pages" select="Append.Pages/Item"/>
- </xsl:call-template>
看到上边的代码了吧,是不是和我贴出的第一个代码段很类似,其实光有ui.xsl中定义的块还不够,只有在调用页面写上相应的部分,才可以形成一个完整的字符集,你需要调用块的时候,你就把块写进你的具体页面中即可,但是一定要记得写上相应的with-param,还是很郁闷,我没有了解过XSLT的技术知识,我只能按照汤原有的方式调用,当调用导航时,我就需要在调用页面写上<xsl:with-param name="Setting" select="Global.Setting"/> <xsl:with-param name="Pages" select="Append.Pages/Item"/>这两块。拿我刚才自己定义的导航块为例,如果我要在某个部分调用导航,那么我在具体页我想放置导航的位置写上。说到这,我插一句,如果你是在原有的模版上修改结构,那么一定记得一点,就是你在UI.XSL的某个块中加了什么,那么记得在调用页面的调用代码中增加对应的内容。
- <xsl:call-template name="nav_my">
- <xsl:with-param name="Setting" select="Global.Setting"/>
- <xsl:with-param name="Pages" select="Append.Pages/Item"/>
- </xsl:call-template>
这样,导航就乖乖的显示出来了。这些块中包含的层最终调用完后,应当组成一个完整的HTML页面。不知道能理解吗?还有一点我需要说明的,我在制作模版的时候,所有页面的body以前和body以后的内容,我都是完整复制的小汤模版的,而对于UI.XSL,下部分代码我也是完整复制的,谁让咱不知道具体含义呢,还有,复制这些代码的时候最好不要去改变它的段落结构,我曾经弄过一次,我觉得很乱,认为有些可以加个空白空格放到一行即可,就这一个自作聪明,害得我两个小时找不到报错原因。
- <?xml version="1.0" encoding="utf-8" ?>
- <xsl:stylesheet
- version="2.0"
- xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
- xmlns="http://www.w3.org/1999/xhtml"
- xmlns:string="http://www.foxcup.com/string"
- xmlns:url="http://www.foxcup.com/url"
- xmlns:common="http://www.foxcup.com/common"
- >
- <!--声明-->
- <xsl:template name="Head">
- <xsl:param name="Title"/>
- <xsl:param name="Config"/>
- <xsl:param name="Setting"/>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
- <script type="text/javascript" src="{$Config/AppPath}Theme/{$Setting/Theme}/Script/jQuery.js" xml:space="preserve"> </script>
- <script type="text/javascript" src="{$Config/AppPath}Theme/{$Setting/Theme}/Script/thickbox-compressed.js" xml:space="preserve"> </script>
- <script type="text/javascript" src="{$Config/AppPath}Theme/{$Setting/Theme}/Script/AJAX.js" xml:space="preserve"> </script>
- <script type="text/javascript" src="{$Config/AppPath}Theme/{$Setting/Theme}/Script/Common.js" xml:space="preserve"> </script>
- <link rel="stylesheet" type="text/css" href="{$Config/AppPath}Theme/{$Setting/Theme}/Style/Layout.css"/>
- <link rel="stylesheet" type="text/css" href="{$Config/AppPath}Theme/{$Setting/Theme}/Style/thickbox.css"/>
- <title xml:space="preserve"><xsl:if test="$Title!=''"><xsl:value-of select="$Title"/> - </xsl:if><xsl:value-of select="$Setting/Caption"/><xsl:if test="$Title=''"> - <xsl:value-of select="$Setting/Intro"/></xsl:if></title>
- </head>
- </xsl:template>
- ……
- </xsl:template>
- </xsl:stylesheet>
好了,调用以及块说的不知道看明白没,没看明白也没辙了,表达能力实在有限。下边还是来看看涉及到正文的具体部分。还是先插一句,公告比较独立,如果你完全复制了body前后和后的东西,那么公告的这段代码,你可以直接放到你想放的地方即可
- <div class="affiche" xml:space="preserve">
- <xsl:value-of select="Global.Setting/Affiche" disable-output-escaping="yes"/>
- </div>
好了,言归正传,看article_list的正文部分,你在lab_v4的该页面中,你可以看到小汤注释的<!--middle-->,里边大层小层套了一堆,其实都是为了页面的表现,而如果是自己做模版,很针对性,那么我们需要考虑的就是这个标记包裹的区域
- <xsl:for-each select="This.Articles/Item">
- <!--这里就是放置你的文章列表样式和调用具体数据的部分,注意每个具体页面XSL标记不同,我只是举例,请自行观察原有模版即可-->
- </xsl:for-each>
- <!--正文结束后就是翻页-->
其实这个和UI.XSL中块是一个道理,只不过,这里输入的只是调用,而定义放在BODY前了,所以我建议不想了解太多的朋友,直接复制BODY前的内容咯,呵呵。你只需要把你定义好的包括标题啊,日期啊,评论啊的表现层放在其中,然后对应的把调用代码放进去即可。看下我某个模版的正文布局,这个是摘除掉没有用的层以后的样子,代码少容易看懂些
- <!--正文列表-->
- <xsl:for-each select="This.Articles/Item">
- <div class="article_box">
- <div class="article_name">
- <a title="{Article.Title}" href="{$Config/AppPath}Article/{Article.Label}.aspx" xml:space="preserve"><xsl:value-of select="Article.Title"/></a>
- </div>
- <div class="article_content" xml:space="preserve">
- <xsl:if test="Article.Password!=''">
- <p style="color:red;">加密内容</p>
- </xsl:if>
- <xsl:if test="Article.Password=''">
- <xsl:value-of select="Article.Explain" disable-output-escaping="yes"/>
- </xsl:if>
- </div>
- <xsl:if test="string:Length(Article.Explain)!=string:Length(Article.Content)"><a href="{$Config/AppPath}Article/{Article.Label}.aspx" class="article_more">点击查看全文...</a></xsl:if>
- <div class="article_tags">标签Tags: <xsl:value-of select="string:TagsSplit(Article.Tags, ',', ' ')" disable-output-escaping="yes"/></div>
- <div class="article_other">所属分类: [ <a href="{$Config/AppPath}Category/{Category.Label}.aspx" title="{Category.Name}"><xsl:value-of select="Category.Name"/></a> ] | 评论: [ <a title="{Article.Title}" href="{$Config/AppPath}Article/{Article.Label}.aspx#comment_box" xml:space="preserve"><xsl:value-of select="Article.CommentCount"/></a> ] | 浏览: [ <xsl:value-of select="Article.Reader"/> ] | 作者: <xsl:value-of select="Article.Author"/></div>
- </div>
- </xsl:for-each>
至于哪个标记是调用哪个数据的,还是看客们自己去发掘吧。一条一条的列很费力,小汤在命名的时候还是比较标准的英文的,可以对照翻译去了解每个调用时具体涉及哪个数据。正文里还用了不少判别,因为有什么加密文章,或者点击查看更多之类的,不想多说了,直接复制吧兄弟们。特别说明一下的,上边代码中的
- <xsl:if test="Article.Password=''">
- <xsl:value-of select="Article.Explain" disable-output-escaping="yes"/>
- </xsl:if>
这段代码就是正文,当然,每个具体页面少许不同,自己观察,懂一个就全懂了,正文一般在编辑器都默认是P标记来区分段落的,定义样式的时候请注意,还要注意到英文的换行问题,不做的话,一些英文是不会自己换行的哦。
好了,大体的制作方法就说完了。下边说下我制作当中的一些错误和使用XSLT的一些注意事项,当然肯定不全,只是我遇到的。我用代码方式罗列,这样比较清晰。
- <!--在写代码的时候,如果一个层因为这样那样的原因,层中没有实质内容,那么最好在DIV中加一个标记xml:space="preserve",并且在封闭区内加一个空格,还有,如果层中只有一个xsl的调用标记,那么也视作是一个空层,最好加上xml:space="preserve",例如-->
- <div id="space" xml:space="preserve"> </div>
- <!--在写代码的时候,如果需要调用FLASH,请尽量不要使用OBJECT,总是出错,简单的办法是只写embed标记,例如-->
- <embed menu="true" wmode="transparent" pluginspage="http://www.macromedia.com/go/getflashplayer" src="/Theme/zbzv_angle/Style/Images/flashtime.swf" width="151" height="31" type="application/x-shockwave-flash" play="true" loop="true"> </embed>
- <!--在写代码的时候,如果需要加入脚本,一定注意脚本中俄&标志,你需要把它写成标准的&并且在标记中加入一个符号,例如;-->
- <script src="http://s107.cnzz.com/stat.php?id=815284&web_id=815284" language="JavaScript" charset="gb2312">;</script>
- <!--在article_list和article_view中注意其中的加密内容,或许你永远用不到,但记得皮肤的完整性是要考虑的,还有注意view页面代码中的id="contentDom",这个必须保留,否则,你的加密内容将永远的验证下去-->
- <div class="article_content" id="contentDom" xml:space="preserve">
- <xsl:if test="Article.Password!=''">
- <span style="color:red;">加密内容</span><br/>
- 密码:<input type="text" id="ArticlePasswordInput_{Article.ID}"/> <input type="button" value="验证" onclick="javascript:System.Article.PWDCheck({Article.ID}, document.getElementById('ArticlePasswordInput_{Article.ID}').value, this);"/>
- </xsl:if>
- <xsl:if test="Article.Password=''">
- <xsl:value-of select="Article.Content" disable-output-escaping="yes"/>
- </xsl:if>
- </div>
- <!--因为日志列表和日志显示页太相似,很多时候我就喜欢直接把日志列表页直接复制过来小小的修改一下即可,但是记得更改的xsl调用的函数。同样的问题也容易出现在评论和留言中-->
- <!--别忘了定义你的PAGE_VIEW页-->
恩,就这些了,我发现的,给我带来很多痛苦的东西就这些了,肯定你做的时候还会发现新的,仅作参考吧。
下边说下我的小经验吧,设计好模版,不要考虑XSLT,认真的把页面布局做完,再去做XSLT的模版,这样思路清晰。把UI做好后,再做具体页面的时候,把你需要调用的部分调用进来,正文区只预留一个表现层即可,先不要往进写代码,这样你在清空缓存刷新页面测试的时候,可以及时的定位错误是发生在正文还是UI,如果页面刷新出来了,并且边栏头部等正确调用了,说明你的UI没有问题,如果报错了,那么说明的你UI有问题,这个时候去检查UI。检查也是有技巧的,删除一个块,清空缓存,刷新,如果没出来,继续删除一个块,就这样一个一个的删除下去,直到你删除完某个块以后页面刷新正常了,那么说明你刚删的那块你出问题了。去修改,把UI的问题解决清楚后,再去写正文数据,这样,一旦出错,肯定是正文错了。
好了,就这么多了,自己也从头到尾的看了几遍,不是很通顺,逻辑也不够强,松松垮垮,但是如果朋友够认真,仔细看过之后,我相信还是会有帮助的,做这个,如果你像我一样,完全不懂XSLT,那么,没别的,耐心加认真,就会成功,XSLT在我们做皮肤这个应用级别,其实就是面熟,突破性的做出一个,那么以后再做,顺风顺水,好了,这么个教程零零散散的写了两天,睡觉去了,希望大家都能做出满意的皮肤。有没明白的,留言吧,我能解答的会尽力解答的。
本站所有文章均为原创或整理原创,欢迎转载,但请注明出处给予链接,并且不得删除文章中标识的引用出处,谢谢,让我们创建良好的互联网氛围。
- 小金刚菩提的选择、清理与盘玩,如何清理小金刚,如何盘玩小金刚
- 2009-12-20 14:04:02
- 制作了新的皮肤,又是一个黑版的
- 2009-08-05 02:24:47
- 持续的忙,这就是生活
- 2009-07-15 14:26:28
- 关于洛克龙阁使用XSLT模版引擎的一些使用心得和皮肤制作方法
- 2009-06-22 02:28:27
- 发布ROCLOG4.0皮肤——黑色游戏风格
- 2009-06-16 01:21:58
- DIV+CSS让图片自适应层宽度
- 2009-06-03 23:27:07
- 发布一个ROCLOG4.0的皮肤
- 2009-06-03 22:35:21
- 博客随想
- 2009-03-14 23:29:18
改不改不知道,不过我想小汤应该在近期不会对模版引擎做太大的改动了,这哥们最近捂着做新东西呢。嘿嘿
我也希望文章能够对大家有所帮助,不过能力有限,有什么问题随时问,我能解决的会及时答复的。期待你更精彩的皮肤
嘿嘿,汤汤来补充下就更完美了,大家可以点击“引用通告”查看汤汤写的一些深层补充和关键点,挺重要的部分
- 来了就不要吝啬了,欢迎在下边发表评论哦!
- 称呼: * (您的姓名)
- 电邮: * (邮箱地址)
- 网址:
- 内容:
-
验证码:
还行,这个服务商还可以。哈哈