DIYPloneStyle: 为plone2.1创建定制外观
Note: This is the print view with all the tutorial pages on one page. The paginated version is available here, if you prefer that.
简介
(译者:本教程的英文原稿位于 这里.)
Plone从2.1版本开始引入了资源注册表(ResourceRegistries)这个新组件, 它提供了一组工具来管理链接到plone页面(模板)的样式表以及Javascript等资源文件。这些工具——portal_css和portal_javascripts ——让您能够以一种类似于“将动作(actions)注册到portal_actions”的方式来注册 CSS和JS文件(例如您可以为它们设置访问条件)。感谢资源注册表,我们现在能够以更清晰和更强大的方式定制Plone的外观。
要定制一个Plone站点,一般通过TTW方式(在ZMI中),
使用Skins Tool中的custom层来完成定制任务。尽管这样做完全可以,但是这种方式仅仅适合于客户这边的简略更改,特别是那些无权访问文件系统的人。如果这就是您想要的,
那么您或许更应该阅读Plone2.0权威指南的第七章。但是如果您期望为Plone构建一个完整的图形化环境,那么最好的方式就是写一个
基于文件系统python代码的产品。
在本指南中,我们将使用DIYPloneStyle——一个针对Plone2.1的简单示例/骨架性质的皮肤产品——作为研究资源注册表如何工作的基础,并 且我们将基于它来构建一个新产品,以支持在任何Plone门户中安装新的定制外观。
DIYPloneStyle是基于如下两个产品的:
- Martin Aspeli的MySkin,一个骨架性质的Plone产品,它可以用它自己的层来安装一个皮肤选择项,但是没有使用资源注册表机制。
- SimplePloneStyle(作者是我),这是另一个骨架产品,它利用了资源注册表机制,但是不能创建新的皮肤选择项。
这两个产品都还没有废弃,仍然很有价值。比如,您可能想要使用SimplePloneStyle来启动这样一个新项目:其中需要有“为所有Plone皮肤选择项注册新样式表”的功能。 又或者,您可能想基于MySkin写一个新产品,它仅仅需要使用几个层来向Plone添加新的皮肤选择项。
- 注意
- 本指南有意没有包括“通过用覆盖Plone宏中的HTML”来订制Plone外观的资料;
代替的,我们聚焦于使用CSS。我们并不推荐修改Plone的HTML的方式,因为这样做可能导致您在升级Plone时遇到麻烦。
如果您真的需要修改Plone的页面模板来定制某些UI元素,那么我们推荐您阅读Ben Calder的 关于如何创建一个定制皮肤的how-to文档,以及Jet Wilda的 "Where is what?"指南。
安装以及基本示例
安装
首先,下载DIYPloneStyle的最新版本,将它解包展开,然后遵守 README.txt 中的安装指令进行安装(对于Plone产品来说这是一个典型的安装过程)。
您的门户现在看起来应该像这样:
如果有任何UI元素看起来和上面的屏幕快照不同,那么请您清空浏览器缓存然后重新载入页面(比如在Firefox中,点击'刷新'按钮的同时按下shift键;而在IE中,直接使用
基本例子
该例子的代码位于DIYPloneStyle/skins/diystyle_example/(文件系统中)
我们将看到该文件夹中的文件并不多:
- 一些图片
其中的大多数都将用来代替Plone自带的那些默认外观图片。也有一些用于顶端槽(top slot)的背景图案以及一个定制的logo图标。
- 一个定制的base_properties.props文件
从这个文件中,您将学会如何替换门户的logo图标,以及如何简单修改门户的样式属性。
- 注意
- 通过定制
base_properties.props文件来修改Plone UI 元素的样式属性是最容易的方式。但是有些问题值得注意,参见后面章节。
- 一个定制样式表(diystylesheet.css.dtml)
跟这个样式表相关的最有趣的事情,或许就是它的名字已经不再是(而且也不能是)
ploneCustom.css.dtml。在本指南的后面章节中,您将学会如何使用Plone2.1中引入的portal_css工具来注册样式表,而不再使用以前的
ploneCustom.css来实现。
准备开始——手动方式
1 卸载这个产品——使用门户的快速安装器(Quick Installer)。
2 重命名这个产品为别的与DIYPloneStyle不同的名字。
3
重命名skins/diystyle/renameThisFile.css.dtml为更适合您的产品的名字。您将在这个文件中添加您自己的CSS规则。
4 重命名skins/diystyle/为更适合您的产品的名字(*)。
5
在config.py中,改变您的皮肤选择项的名字(SKINNAME)。在STYLESHEETS声明中,替换renameThisFile.css为您为该模板选择的名字,省略.dtml后缀名。
6 在Extensions/Install.py中,编辑import声明中的相关行。(参见# CHANGE注释)
7 在tests/testPloneSkin.py中,替换所有DIYPloneStyle为您的产品名(参见# CHANGE注释)。
8 编辑README.txt文件,在其中描述您的产品,删除usage和credits段,并替换作者名和电子邮件地址。
9 清除HISTORY.txt文件中和DIYPloneStyle相关的内容。
10 删除基本例子 - 删除 skins/diystyle_example/目录。 -
在config.py文件中,在STYLESHEETS声明部分,删除声明diystylesheet.css那一行。
常见问题 -- 本章的实践最容易遇到问题,请参见本指南常见问题部分的参考信息以避免出现这样的情况。
现在您已经拥有了一个全新的骨架,使用它您可以为Plone构建新皮肤了。
祝您的新工程一切顺利!
(*)
任何位于您产品的skins/目录下的文件夹都将被门户皮肤工具注册为一个FSDirectoryViews,仅有的几个例外就是那些名字以'.'开头的文件夹,以及名为CVS或者{arch}的文件夹。(这是硬编码到Extensions.utils.getSkinsFolderNames()中的)。
由于在皮肤工具中FSDirectoryViews的名字/id标志必须是唯一的,一个很好的实践就是在您的文件夹名中包含您的产品名,这可以很大程度上确保它们的名字之间不会冲突——特别是您想使用那些常用名时。
准备开始——自动方式
在前一章中您学会了如何手动设置DIYPloneStyle为一个全新的皮肤骨架产品。这是我们后续工作的基础。
然而还有另一种迅速得多的方式来达到同样的目的——使用DIYPloneStyle自带的生成器脚本程序。
在文件系统里的DIYPloneStyle产品文件夹中,有一个bin/目录,在这里面您会发现一个叫做generator.py的python脚本文件。
这个脚本程序能够被用来自动化完成所有前一章中列出的手动设置。
下载和解包展开DIYPloneStyle
- 把解包后的DIYPloneStyle产品文件夹放到您的zope实例的
Products/目录。 - 卸载您以前安装的DIYPloneStyle(以管理员角色登录plone,进入站点设置 > 添加/删除产品 )。
运行该脚本
在Unix/Linux/OSX下
在bash shell中,运行类似于如下提供的命令:
/您的zope实例目录路径/Products/DIYPloneStyle/bin/generator.py --productname MyOwnPloneSkin
在windows下
- 在windows的开始菜单中选择运行,然后键入
cmd,按下确定按钮。 - 使用类似如下提供的命令来运行脚本:
python C:\您的zope实例目录路径\Products\DIYPloneStyle\bin\generator.py --productname MyOwnPloneSkin
在类Unix系统中,您能够从任何目录调用该脚本。
在Windows中您则不能:您的当前工作目录不能是产品目录或其子目录。
我收到一些用户反馈,说是当使用直接从subversion中检出的DIYPloneStyle中的这个脚本时,在Windows下会遇到一些权限问题。
如果您遇到这样的情况,在调用这个脚本之前花点时间删除所有.svn文件夹就可以了。
开始构建
现在您的Zope实例的Products/目录中已经有了一个全新的可安装产品。
唯一需要您自己动手的就是重启动Zope服务器,这样您才可以在Plone中安装它。
- 注意
- 如果您想要知道更多可用的脚本参数,您可以参照它的源代码,或者不带参数执行它,参考它的输出信息。
组织皮肤的层
为了让您更好的理解皮肤工具(Skins Tool)以及它的层间遍历机制,我建议您阅读由Andy McKay著写的官方Plone Book的第七章,特别是在皮肤中使用层 以及使用portal_skins管理皮肤。这里给出的联接不是官方的,但是据我所知它是唯一一个公开可用的直接为这本书提供HTML版本的网站,并且它还是即时更新的。 这两部分主要聚焦于TTW方式的Plone定制工作。尽管对于学习Skins Tools的层间遍历机制而言,这是一种很好的方式,但是我们知道直接在ZMI中进行工作,并不适合为Plone构建一个完全图形化的环境。
当在文件系统中构建一个皮肤产品的时候,概念上都是一样的:
安装函数首先会创建一个皮肤,它包含了所基于皮肤的所有层,然后附加上产品所特定的层。产品特定的层就是指在文件系统中位于产品skins/目录下的那些文件夹。(*)
实际上,如果您的产品仅仅是通过添加几个样式表和替换图形化UI元素来定制一个Plone站点,那么您只需要向您的皮肤选择项添加一个层就足够了。(**)
但是在某些情形下,拥有多个层也是很有用的,主要用于组织分类皮肤元素,如图片,定制(customizations),样式表等等。
skins/目录下的文件夹都将被注册为皮肤工具(Skins Tool)中的一个FSDirectoryView,
然后会被添加到您的皮肤选择项的层中。只有那些名字以 '.' 开始的文件夹,以及名为CVS或者{arch)的文件夹除外(这是被硬编码到
Products.DIYPloneStyle.Extensions.utils.getSkinsFolderNames()中的)。
(**) 如果DIYPloneStyle提供了超过一个皮肤层(也就是说如果它的skins/文件夹包含了不止一个文件夹),这仅仅是为了使得我们在Get Started部分的删除例子步骤更容易些。
设置基本属性
如我们在基本示例部分提到的一样,定制base_properties.props是修改Plone UI元素样式属性最容易的方式,但是这仍然有些问题值得注意。
由于Plone皮肤工具现有工作方式的问题,您必须在该文件中给出所有Plone基本属性,即使您只打算定制其中很少几个。如果您删除该文件中的某些属性,Plone就不能再访问他们了。
所有这些问题使得base_properties.props 方式在维护,升级和定制上都不理想。这就是为什么它将在Plone中被逐步淘汰的理由之一(另一个理由则是为了避免
在CSS文件中使用DTML)。
我还不清楚这将在什么时候如何实现,因此请关注本段的更新。
您可以在CMFPlone/skins/plone_styles/ploneCustom.css 这个文件中找到更多关于Plone预定义属性的信息。
除了Plone中预定义的属性之外,可能您还需要使用您自己的属性。
除了添加新属性到base_properties.props中外,更好的方法是,在你的皮肤层中创建一个新的.props文件,并在css文件中注册使用它(以替代那个base_properties - 参见原始的DIYPloneStyle/skins/diystyle/renameThisFile.css.dtmlDTML 代码)。
注册样式表
在资源注册表内建到Plone之前,要重载Plone默认的CSS规则,唯一的办法就是定制 base_properties.props以及ploneCustom.css这两个文件。
正因为这样,确定需要重载Plone的某些内容,需要我们关注Skins Tool中层的遍历顺序,或者通过设置Zope不太漂亮的Access Rules工具。
就像我们在前一章中看到的,我们仍然得使用base_properties.props来定义我们的基本图形化设置。
但是现在我们能够用CSS工具注册样式表了,ploneCustom.css仅仅保留为向后兼容目的。
没有资源注册表的Plone还有另一个限制就是,没有办法添加条件来决定是否一个样式表应该被载入。
在DIYPloneStyle中,样式表注册是用config.py来设置的,在STYLESHEETS声明中。STYLESHEETS是一个python字典的元组,其中每个字典对应于一个被portal_css工具注册的样式表。
如果您需要在一个样式表上放置一个条件,您得向它对应的字典添加一个expression关键字。其值是一个TAL表达式,它的工作方式与动作(actions)在portal_actions工具中一致。
您能够从STYLESHEETS的内联注释中学到更多样式表属性(字典键)
实践示例
一个非常常见的用例就是要为公开匿名访问定义一个皮肤,同时为成员访问保持一个基本的plone风格。
要实现这个用例,最容易的方式就是在产品特定的样式表上放置一个条件。
在config.py的STYLESHEETS声明中,像下面这样声明您的样式表:
{'id': 'diystylesheet.css', 'expression':'portal/portal_membership/isAnonymousUser'},
常见问题
- 清空所有缓存(!!!)
- 如果您应用到产品的改变并没有得到您期待的结果,或者如果某些皮肤元素在您反安装了相应产品后还持续存在,请确定浏览器以及前端代理缓存(apache,squid)已经清空了,
并且重载入当前页面。
在Firefox中,当点击重载按钮时按下shift键。 在IE中,使用这个键组合<Ctrl-F5>。
不要低估这个可能的问题,它在您可能遇到的皮肤产品(不管是否基于DIYPloneStyle)相关故障中起码占有80%的比率。 - 在必要时反安装您的产品
- 如果您在重命名样式表或javascripts之前忘记这么做,您能够在ZMI中用portal_css和portal_javascripts工具
解决冲突。
如果您在重命名产品或皮肤选择项之前并没有反安装该产品,在文件系统上撤销您的更改,反安装该产品然后再次重命名这些元素。 - 小心任何TTW方式的定制
- 您的某些产品皮肤元素可能已经在ZMI中定制了。并且被
custom皮肤层中的等价物覆写了。 - 检查该产品已经正确载入到Zope中
- 在ZMI中,进入
/Control_Panel/Products/manage_main,检查该产品已经列出了并且没有标记为“损坏的”。
如果没有被列出来,您应该在文件系统上仔细检查该产品的安装,确信启动Zope服务器的用户至少具备对该产品的读访问权限。
如果该产品被标记为“损坏的”,您应该检查您的错误日志并且确定您的业务python代码是有效的(这应该只有在您向您的初始骨架Plone样式产品添加了一个损坏的python类定义时才会出现) - 确信该产品是可安装到Plone的
- 如果您在 站点设置 > 添加/删除产品中发现您的产品被认为是移除的,或者如果您的产品根本就没有列出在快速安装器中(ZMI中的portal_quickinstaller),
这或许意味着您不得不调试您的
Extensions/Install.py脚本。 - 使用测试框架
- DIYPloneStyle自带了基本的单元测试。
如果您想要学习Plone单元测试框架,请参考本指南资源章节的链接。 - 得到社区的支持
- 在添加注释到该页面之前,请发送您的问题到plone-users 邮件列表或者尝试一下在IRC上的#plone频道得到支持。
您也可以通过发送电子邮件给DIYPloneStyle的作者们来联系他们(电子邮件地址列出在产品的README.txt文件中)。
资源
在这里下载DIYPloneStyle的最新发布
基础参考
下面的链接将能够回答大多数本指南没有覆盖到的问题
- 资源注册表
- 项目描述 或者该产品的
README.txt文件对它的功能给出了很好的概述
要学到更多注册表的API相关信息,您可以安装 DocFinderTab。一旦您开始学习Zope/Plone的API,我们推荐你无论如何都要采用这个产品。 - 定制Plone - Plone 2.0 的方式 作者: Alex Limi
- 一个对Plone2.0布局结构和哲学的概览,以及介绍了您能用CSS作什么。
(本文档也可以作为一个很好的全屏模式下使用Opera投影CSS媒体的演示,它将显示plone页面段为投影幻灯片。
TTW方式定制
这些链接可以被用于更好的理解皮肤工具机制,以及跟Plone用户界面元素相关的东西是如何组织的。
- Plone宝典 作者:Andy McKay
- 第七章,关于定制Plone的观感 对于那些需要更好的理解皮肤工具机制的人们来说,这是一个必读读物。
- where is what? 作者:Jet Wilda
- 一个关于什么模板和CSS控制着UI元素, 以及在ZMI中如何找到它们的参考。(覆盖Plone2.0)
文件系统开发
- plone.org的How-to部分
- 在User Interface: Styles and styling, CSS这一部分有大量优秀的资源。
特别是关于创建一个定制皮肤 作者:Ben Calder - Plone开发最佳实践 作者:Joel Burton
- 如果您计划开发基于文件系统python代码的产品,他将给予你很好的忠告。
以下的参考资料可能看起来已经远离了我们的主题,因为他们大部分都是关于开发内容型别的,但是对于学习如何为plone构建python产品,他们都是极具价值的。
- 我的站点 作者:Raphael Ritz
- 这个指南/产品是针对Plone新手的,覆盖了基于文件系统进行产品开发的大多数方面。
- RichDocument 作者:Martin Aspeli
- 尽管这个指南/产品更多是关于为Plone创建新的内容型别的,它还是有一个简短的部分覆盖了资源注册表的使用
- Plone宝典 作者:Andy Mckay
- 同样有一章关于用python写一个产品。
DIYPloneStyle本身自带单元测试。
大多数下面的参考都描述了Zope和Plone的单元测试框架,真得很容易在任何Plone产品中采用它们。
- PloneTestCase
- PloneTestCase是ZopeTestCase 包之上的瘦包装层,用于简化对基于Plone的应用和产品的测试。
- 如何为Plone编写单元测试
- 这篇文档展示了编写单元测试有多容易,以及描述了如何设置您的环境来调用它们.
- the ZopeTestCase Wiki
- 一份全面的关于Zope单元测试框架的文档。
其他的Plone皮肤产品
我们发现大多数针对Plone的图形化设计都还没有利用资源注册表,但是采用这个代码现在应该是非常容易了,参考您阅读的这份指南开始吧 ;-)
- plong.org的产品区
- 是一个集中化的Plone产品仓库。它有一个区域专注于可视化主题 ,可用来作为关于如何应用新的设计到Plone站点的有用例子来源。
- ploneskins.org
- 是另一个Plone皮肤仓库。
CSS设计
- 官方的 W3C CSS 文档
- 由W3C联盟交付的官方层叠样式表文档。
- CSS禅园:CSS设计之美
- 一个基于CSS设计的示范,演示它可达成的视觉效果。
- A List Apart
- 一个web期刊,其宗旨是“探索设计、开发、以及web内容的意义,特别聚焦于根据web标准设计的技术和益处”
- 著名的书籍作者的web站点
- 一些关于CSS设计的书籍作者们都有他们自己的web站点, 比如Eric Meyer,Jeffrey Zeldman,Dan Cederholm以及 Owen Briggs等等,这些站点都是查找文档,例子和技巧处方的好地方。
Mozilla/Firefox工具和扩展
当您需要检视Plone页面元素的CSS属性,或者想要找出什么id或class您想要在您的样式表中覆写时,以下工具是您最好的朋友。
- DOM Inspector
- 这个Mozilla工具能被用来检视和编辑任何web页面的DOM。
- Web Developer
- 添加了一个菜单和工具栏,里面是各种web开发工具。
- Aardvark
- 这个扩展可以显示web页面上一个选定元素的属性(比如ID或class名)。
- EditCSS
- 边条上的样式表修改器。
- ColorZilla
- 高级的Eyedropper,颜色选择器,页面缩放器以及其他的华美工具。它帮助web开发者和图形设计者进行颜色相关任务——不管是基础的还是高级的。
- 察看格式化源码 (format source extension)
- 显示格式化并着色的源码以及可选的每个元素的CSS信息。您可以精确的看到哪个CSS规则匹配一个元素。这些规则的 显示包括了文件名和行号。最顶端的元素拥有最高优先级。您能够折叠/展开/醒目块元素(table,tr,td,div,span,...)。真正酷的特性是:直接在页面中选择一个您感兴趣的块级元 素,马上就可以看到它的源码!为了帮助你快速分析源码,你能够直接在源码中察看图片以及添加注释以折叠块元素。代码视图是基于渲染的文档,因此您也将看到动态(通过Javascript) 创建的以及修改的html元素!对于frames和选择的文本,一样可以工作。
- 察看渲染后的源码图表
- 为一个web页面的渲染源码创建一个华美的图表。
同时显示动态生成的HTML以及静态HTML。
移除JavaScript代码,显示JavaScript输出。
在学习环境中,它非常优秀,是您的一个可视化助手。
