做一个WEB程序能够在尽量修改极少程序代码的情况下轻松制定皮肤以及切换皮肤应该都是需要的谁也不想在网站界面想要改版的时候要改一大片逻辑代码
一个合格的皮肤机制体系的实现应该要做到以下几点
>页面模板上要极少拥有逻辑代码(如果模板上拥有大量逻辑代码那估计这个也不叫作模板了)
>能够轻松改变页面布局同时不影响程序代码(cs)
>新模板的定制基本上能由皮肤制作者参照旧模板自行完成不需要开发人员太多介入
>保持性能
然后来看看都有哪些方法大家用来实现所谓的皮肤机制同时进行各个方法的一些个人说明
改变页面调用的CSS文件来换肤
这一个严格上来讲不应该算作皮肤机制虽然CSS非常强大也能够通过它来任意改变页面元素布局但它的HTML始终是不变的所以局限性是非常大的
优点完全不影响性能甚至可以完全不由服务端代码来管理它的变换可以使用JS来切换皮肤(由此在我们有一套完美皮肤机制的情况下这种方法可以完全不与此机制沖突让用户在客户端作更多的个性化)
缺点如果作为核心皮肤机制的话非常有局限性
示例如QQCOM LACOM上面的一些可点击的小色块就是改变调用的CSS文件来实现换肤
读取模板文件替换标识符为要显示的内容与数据输出
这一个方法的灵活性比较高每套皮肤可以有自己的布局有自己的个性
实现比如模板中有一个标识$Subject程序代码会把它替换成文章标题然后有一个标识块<!—Loop[ArticleList]><h>$Subject</h><div>$Content</div><!/Loop>程序代码会把它替换成一个文章列表最后输出处理完所有标识符的内容
通常我们会缓存读取到的模板内容但字符串的替换始终不可避免或者也会把替换过的内容也缓存起来但这样子就等于要缓存模板内容以及替换过的内容占用了两份似乎挺重复内容的内存(为什么?不然总不该每次数据有改变的时候就去作IO操作读取操作读模板文件吧这似乎比字符串替换性能更差)
优点模板灵活程度很高可以随便改动页面布局
缺点影响性能开发人员维护难必须有特定的标识符来表示页面变量后期维护可能会带来非常多的问题
使用ASPNET的App_Themes
这一个方法应该是极差的一个方法根本只是ASPNET的一个小纂头鸡肋基本上不实用
实现比如定制一个BUTTON的样式是这样子的<asp:buttonrunat=server BackColor=lightblueForeColor=black />类似这样的代码存在于skin文件中然后它的换肤机制如下<%@ Page Language=C# Theme=default %>在App_Themes目录下是各套皮肤的独立文件夹各个文件夹包含皮肤的样式以及图片文件等等也可以包含skin文件
优点只有ASPNET才有
缺点包含了第一种方法的缺点skin的样式定制方式还要严重依赖使用ASPNET服务端控件同时也影响性能灵活性也极低
动态载入ASCX文件(ASPNET用户控件)|| 使用master(母版)
这个方法应该也是很多使用ASPNET的人使用的方法有时候它还会与第三种方法结合使用如果对性能需求不是很严格的话中小型项目可以使用
实现使用LoadControl()动态载入ASCX文件或(与)指定页面的MasterPageFile(目标皮肤文件夹的)实现(通常ascx与master还会结合使用)
优点灵活性极高每个皮肤有独立的布局直接使用了CS文件的变量与方法ETC…甚至每套皮肤还有自己独立的代码文件
缺点影响性能有兴趣可以自己去反编译LoadControl方法同时在页面要使用<%%>这种代码块有时候感觉也有点不雅
Xml + xslt
传说xml取代html是趋势??不清楚不了解应该不可能此种方法我没有深入了解过不过大概实现应该是要这样子?每一个XML(输出数据)会有一个对应的XSL文件(控制样式)如下
xml文件
<?xml version=encoding=ISO ?><breakfast_menu><food><name>Belgian Waffles</name><price>$</price><description>two of our famous Belgian Waffles with plenty of real maplesyrup</description><calories></calories></food><food><name>Cakes</name><price>$</price><description>sweet cakes</description><calories></calories></food></breakfast_menu>
xsl文件
<?xmlversion= encoding=ISO ?><html xsl:version= xmlns:xsl=
xmlns=
><body ><xsl:for
each select=
breakfast_menu/food
> <div > <span ><xsl:value
of select=
name
/></span><xsl:value
of select=
price
/></div> <div><xsl:value
of select=
description
/> <span ><xsl:value
of select=
calories
/></span></div></xsl:for
each></body></html>
这样子做有什么好处么我没有体验到
读取模板文件生成aspx文件到每套皮肤的独立文件夹下通过地址重写指定到这些文件夹
这个方法的最终效果对于用户来说和第二种方法应该是差不多的优点就是性能比较高而且还能直接使用CS代码里面的变量方法ETC…另外也可以不会有<%%>代码块的存在可以存在自己的模板语言如同第二种方法的$Subject <!—Loop>标识符一般
优点几乎不影响性能只有第一次读取生成ASPX文件需要损失性能灵活性极高模板代码可读性也可以实现到很高
缺点启动时需要读取分析时间(不过这应该算是小问题)另外有一套皮肤它就要生成与之对应的一套ASPX文件(当然这个可以解决)
利用ASPNET开始才拥有的VirtualPathProvider来实现
虚拟文件机制这个应该算是第六种方法的加强版最终的效果和第六种差不多只是不会生成那些ASPX文件而已取而代之的便是长驻在内存中
实现实现两个类一个继承至VirtualPathProvider一个继承至SkinFileVirtualPathProvider里有个FileExists方法重写成判断请求的路径是否是皮肤文件路径如果是GetFile就实例一个SkinFile(这一个SkinFile我们会对模板进行处理可以拥有自己的模板语言)另外有一个GetCacheDependency方法可以来将模板文件作为虚拟文件机制的缓存依赖文件一旦模板文件被修改了它就会再重新解析模板文件这里先不作赘述具体的查看MSDN的相关文档具可了解
优点与相同
缺点第一次启动需要损失性能(但这也不可避免)
还有更多的实现方法还没用过个人先不发表观点比如使用BuildProvider但这一个需要有比较强的词法分析与语法分析能力