这是本教程的第3个版本。你不需要阅读前两个,事实上,如果你还没有读过前两个版本,我建议你不用读了。我在撰写新版本的时候是希望它不依赖旧版本的。更重要的事,版本的演进,恰恰反映了我对这个题目的理解的逐步深入,至少我自己希望是这样。如果你确实希望查看以前的版本,页面旁边有相关链接。

本教程的目标

“皮肤”这个词在软件程序中就是指一个程序或者网站的可以更换的外观。几个月来,我在DotNetNuke上累计花费了数个星期的时间,从头到脚、从里到外地学习了它的换肤功能。这并不是说DNN的换肤功能很难学习。正相反,一旦你理解了它的简单性,就很容易学会了。正是由于这个原因,我才打算写一篇教程,希望帮助DNN开发者们花费比我少的多的时间来学习这一功能。

本文是否适合你?

对于一个安装完成的DotNetNuke门户站点来说,有以下这几种用户角色:

  • 普通用户 - 使用或者访问这个DNN门户站点的人
  • 网站管理员 - 被指定管理这个DNN门户站点的人。通常使用"Admin"这个登录名。
  • 主机管理员 - 被称为“超级用户”,或者说登录名为“host”的人。超级用户可以管理一台主机上安装的DNN上创建的所有门户站点。
  • DNN安装人员 - 能够访问DNN安装目录的人。指负责在一台IIS服务器上安装DNN,并负责更新版本的人。
  • 开发人员 - 编写或者修改代码,创建及维护模块,甚至DNN核心本身的人。
  • Web设计人员 - 这才是本教程主要面向的人群。他们负责通过DNN皮肤,设计和修改一个DNN站点的视觉效果。

对DNN换肤功能的理解

几个月以前,我在一个叫做 DotNetRocks 的站点的节目中听到了主持人与 Shaun Walker (他通过扩展微软为演示ASP.NET功能而开发的一个Web应用,创造了DNN) 的对话。Jim Duffy 也在该节目中出现。主持人问 Shaun 如何看待 DotNetNuke 的换肤功能与ASP.NET 2.0 提供的模版页/主题功能的差别(此节目进行是在.NET 2.0发布之前几个月)。Shaun说,DNN的换肤系统架构是经过认真设计的,即使说不比 ASP.NET 2.0 将要提供的功能更强,至少也是旗鼓相当。当然,我在这里只是凭记忆复述他的说法,可能与原话不完全一致。

到写作本文时为止,我仍然同意 Shaun 在此问题上的观点。原因是:两个系统都是非常灵活的,都可以满足你制作各种页面的要求,而不牺牲复用性;然而,DotNetNuke 对我来说显著的一点好处是,不需要任何IDE或开发工具就可以设计皮肤。读者也许会觉得用IDE没什么(假如你是开发人员的话,当然不希望自己的工作被别人替代)。可如果认真考虑一下的话,终究有一天,一定程度上,这一点终究还是会影响到你的。

如果你制作了一个皮肤,你可以把它打包出售。已经有了一个(买卖DNN皮肤)的市场。是的,也许,一天晚上你学会了制作DNN皮肤(希望就是今天,通过阅读本文),然后把它上载到网上。等你第二天早上醒来的时候,已经收到了别人付的$$。这是真的,事实上我就这样做过。如果我能做到,别人也都可以做到,因为我学东西很慢的。我还有“注意力缺损症”呢……

已有的文档

DNN开发团队做得不错,免费提供了正式的文档,并且我觉得讲解得相当详尽了,详尽到了当我第一次试图通读一遍的时候有点消化不了,以至于我把这个文档关掉,干脆开始自己琢磨已经随 DNN 安装好的默认皮肤的 ascx 文件,并把它当作我尝试练手的起点。但是,正像那些读过本教程第一版的人们已经知道的,这不是个好办法。

核心团队还写了一本叫做《专业DotNetNuke网站制作》的书。本网站上到处都有到 Amazon 购买这本书的链接。这本书当中有一章专门介绍皮肤的制作,我觉得相对来说容易读一些。我还没有彻底读完这一章,但其中的图表是很好的参考资源。这本书物有所值,并且买一本也是对核心团队的一种支持。[卖广告不遗余力啊-_-b]

如果你愿意获取所有的文档,很好。不过,我写这篇教程时还是考虑了没有这些资源的读者的。

皮肤在哪里

皮肤文件的路径在 "~\Portals\_default\Skins\" ,其中“~”表示你安装DNN的根目录。

DNN安装文件夹结构

文件类型

如上图所示,其中包括了若干不同类型的文件: ascx, css, htm, jpg, zip, xml 。我们分别来看:

  • ascx - 如果你想成为最好的皮肤创作者,或者想长期做这件事情,不要看这个文件,尤其是如果你是个.NET程序员,知道如何修改 ascx 文件的内容。我想说的是,这正是我掉进去过的一个陷阱。的确,修改 ascx 文件让我几分钟内就很快上手,但是随后很快就开始造成麻烦,带我走向了几个月的痛苦旅程。我不是想炫耀自己的聪明,但我确实希望你在这一点上听从我的意见。
  • css - 层叠样式表。是的,正像在所有Web应用的开发当中一样,你的“样式”是在这里设计出来的。想更多了解 CSS ,可以看我的这篇文章
  • htm - 就是这个!这就是我们打交道最多的文件。当你上载一个皮肤的时候,这个文件被转换成 ascx 文件。这就是我建议你不要自己修改 ascx 文件的原因,除非你需要做一些应急的修补。因为 ascx 文件很容易在 htm 文件被重新解析时被覆盖掉。
  • xml - 这里面保存了所有的 属性(attribute)/值 对,它们会在生成 ASP 控件或服务器端 elements 时被加入到你的页面代码。
  • jpg/gif/png 图片文件,用来创造你的设计。
  • zip - 上传一个 skin 是以上传一个包括了所有相关文件 zip 包的方式进行。这个文件不一定在你的 skin 目录里。

换肤过程概述

三个主要的相关文件是 htm, css 和 xml。如果你真打算这么做的话,也可以把所有的代码、html 标记都写在 htm 文件里面。但我这里要讲的是正规的做法。css 文件包括了字体、颜色、图片、填充、边距等等常用的属性。xml 包括了为 DNN 的服务器端控件所使用的属性(attribute) 信息,在皮肤文件解析的步骤中,从 xml 中读取的数据被写入到所生成的 ascx 里的对应标签当中。这个解析步骤发生在上载 skin 之后,除非上载的包中没有 htm 文件可以解析。如果出现这种情况,可能你是在上传一个 ascx 文件。如果你是通过 FTP 或者 DNN 文件管理器上传了皮肤文件,可以直接到站点的皮肤管理页面上,点“解析文件”的链接,人为执行解析过程。

皮肤对象

除了通过上传模块和皮肤文件来扩充 DotNetNuke 之外,你还可以通过编程创建所谓的“皮肤对象”。像模块和皮肤一样, DNN 核心系统中已经包括了若干“皮肤对象”。[SEARCH],[LOGO],[CURRENTDATE]等等都是皮肤对象的例子。这些东西几乎可以说是 DNN 页面的标志了,基本上所有的 DNN 页面上都有这些元素。

皮肤对象是怎样起作用的

如果你是按正规的方式在 htm 文件中创作皮肤,它们的样子正像我上面呈现的一样:[SEARCH],[LOGO],[CURRENTDATE] 等等。如果你是直接编辑 ascx 文件的,你可能已经意识到你是在跟一些 asp 服务器端标签打交道,就像这样:<DNN:SEARCH id="" runat="Server"></DNN:SEARCH>。正像其他的服务器端标签一样,你需要在页面文件的开头加入一系列指令,注册这些用户控件。

因此,如果你使用 htm 来创作皮肤,当你希望把菜单放在你的 html 页面中的某个位置,你可以直接写 "[SOLPARTMENU]" 到文件里。DotNetNuke 系统会认出这个标记,自动生成对应的服务器端标签和标签注册指令。把一个皮肤对象安装到 DNN 系统中之后,当 DNN 在解析用户上传的皮肤 htm 文件时遇到与之对应的[ABC]标记,就知道应该生成什么样的标签。

HTM - 用法示例

在 HTM 文件中创作皮肤时,不需要包括一个完整网页所需的那些结构标签,如<HTML>, <HEAD>, <BODY> 等。除非你对于借助 CSS 构造无 <TABLE> 的网页布局非常有经验(也许我会另写一篇教程讲解这一问题),建议你还是使用一个 Table 作为页面的主体结构,用来包含皮肤中的各种元素。举个例子:

<table>     <tr>         <td>             [SOLPARTMENU]         </td>     </tr>     <tr>         <td>             We need to put more skin objects in here,              or at least one more for the "content pane",              or this skin would error out as soon as we tried it out.          </td>     </tr>     <tr>         <td>             Copyright, Terms of service, and other              stuff should go down here. Don't put it in yet,              since we'll this the "correct" way through skin object             tokens here in a bit.         </td>     </tr> </table> 

文件中可以包含一个 [CONTENTPANE] 元素,用来在定制页面时摆放模块。

CSS - 用法示例

在 CSS 文件中定义页面的视觉效果。通常样式元素包括字体、颜色等,但也可以指定填充、边距,甚至菜单项使用什么图片。下面例子中的样式表元素定义了菜单项的样式:

.ModuleTitle_MenuItem  {      cursor: pointer;      cursor: hand;      color: black;      font-family: Tahoma, Arial, Helvetica;      font-size: 9pt;      font-weight: bold;      font-style: normal;      border-left: white 0px solid;      border-bottom: white 1px solid;      border-top: white 1px solid;      border-right: white 0px solid;      background-color: Transparent;  }   

 记住一定把样式文件命名为 skin.css ,否则,将必须在 html 文件中人工指定 css 文件的路径。DNN 会自动引入命名为 skin.css 的文件。

注意,我的网站上有专门为 DNN 开发而写的 CSS 教程。你可以本页上方的菜单上找到链接。

XML - 用法示例

怎样才能告诉网页上的主菜单对象,希望让它呈现纵向排列的形式,而不是通常使用的水平的形式呢?要做到这一点,你需要在 XML 文件中加入一些信息,指定一些相关属性的值,用来在生成 [SOLPARTMENU] 对应的服务器端控件代码时,加入对应的属性设置。不仅需要指定属性的名称,还需要指定它的值。看一个例子:

<Objects>     <Object>         <Token>[SOLPARTMENU]</Token>         <Settings>             <Setting>               <Name>Display</Name>               <Value>Vertical</Value>             </Setting>         </Settings>     </Object> </Objects>  

如果没有别的属性需要设置,XML 文件里有这些内容就够了。我们在这里指定的属性和值在 XML 文件当中被称作 Settings 。我们在一个 Setting 项目中声明我们希望修改的属性名称,以及我们需要把这个属性设置成的值。当我们创作一个真正的skin 时会遇到更多的例子。