Quintagroup主题模板,用于Plone 3,具有嵌套命名空间
项目描述
qplone3主题模板
quintagroup.themetemplate是Zopeskel的“Plone 3主题”模板的增强版本,包含addcontent本地命令,允许您通过添加附加元素来扩展基本Plone主题,例如:皮肤层、组件、视图、CSS和JS资源,以及zexp文件中的对象。这个包在功能上相当于Archetype模板。
quintagroup.themetemplate包用于开发所有Quintagroup的Plone 3主题,地址为http://skins.quintagroup.com。
Quintagroup的Plone主题, 2006-2012
内容
概述
创建主题包
扩展主题
发布说明
概述
此主题模板允许您创建初始主题包骨架,即创建具有嵌套命名空间的plone3主题Python包(这与Zopeskel中的默认plone3_theme模板不同)
之后,您可以通过以下元素扩展主题包
皮肤层
组件
视图
CSS、JS资源
zexp文件中的对象
使用paster create PasteScript命令创建包。使用扩展此产品的paster addcontent本地ZopeSkel命令(扩展资源)扩展主题
创建主题包
让我们创建plone-3主题Python包。使用paster create命令
>>> paster('create -t qplone3_theme quintagroup.theme.example --no-interactive --overwrite') paster create -t qplone3_theme quintagroup.theme.example --no-interactive ...
您将获得包含以下内容的标准Python包内容
quintagroup 顶级命名空间。
quintagroup.theme.example-configure.zcml - 添加到package-includes目录的zcml文件
检查一下
>>> package_dir = 'quintagroup.theme.example' >>> objects = ['setup.py', 'quintagroup', 'quintagroup.theme.example-configure.zcml'] >>> objects.sort() >>> [o for o in objects if o in os.listdir(package_dir)] ['quintagroup', 'quintagroup.theme.example-configure.zcml', 'setup.py']
qplone3_theme 模板 - 创建具有嵌套命名空间的主题。
默认情况下 - 主题位于 quintagroup.theme.<包名第三部分> 命名空间
在我们的例子中 - quintagroup.theme.example
因此请检查命名空间
>>> theme_namespace = os.path.join(package_dir,'quintagroup','theme','example') >>> os.path.isdir(theme_namespace) True
主题包含 3 个子目录(browser、profiles、skins)
>>> cd(theme_namespace) >>> dirs = ('skins', 'browser', 'profiles') >>> [True for d in dirs if d in os.listdir('.')] [True, True, True]
以及初始化文件(__init__.py、configure.zcml)
>>> files = ('__init__.py', 'configure.zcml') >>> [True for d in files if d in os.listdir('.')] [True, True]
browser 目录
Browser 目录包含
‘templates’ 资源目录
包含 IThemeSpecific 标记接口的 interfaces.py 模块
configure.zcml,其中注册了主题标记接口
>>> ls('browser') __init__.py configure.zcml interfaces.py templates >>> cat('browser/interfaces.py') from plone.theme.interfaces import IDefaultPloneLayer <BLANKLINE> class IThemeSpecific(IDefaultPloneLayer): ... >>> cat('browser/configure.zcml') <configure ... <interface interface=".interfaces.IThemeSpecific" type="zope.publisher.interfaces.browser.IBrowserSkinType" name="Custom Theme" /> ...
正如我们所见,默认主题名称是“Custom Theme”,但在创建主题时,您可以指定自己的名称。查看这个...
首先创建具有不同皮肤名称的配置文件
>>> conf_data = """ ... [pastescript] ... skinname=My Theme Name ... """ >>> file('theme_config.conf','w').write(conf_data)
使用您自己的皮肤名称创建相同的主题并检查此操作
>>> paster('create -t qplone3_theme quintagroup.theme.example --no-interactive --overwrite --config=theme_config.conf') paster create ... >>> cd(package_dir) >>> cat('quintagroup/theme/example/browser/configure.zcml') <configure ... <interface interface=".interfaces.IThemeSpecific" type="zope.publisher.interfaces.browser.IBrowserSkinType" name="My Theme Name" /> ...
skins 目录
它只包含 README.txt 文件,还没有皮肤层。这是 localcommand 的工作;)
但是请检查我是否正确...
>>> cd('quintagroup/theme/example') >>> ls('skins') README.txt
profiles 目录
包含“default”和卸载配置文件
>>> 'default' in os.listdir('profiles') True >>> 'uninstall' in os.listdir('profiles') True
默认配置文件中包含以下内容
import_steps.xml - 任何原因。
skins.xml - 注册皮肤目录
>>> cd('profiles/default') >>> 'import_steps.xml' in os.listdir('.') True >>> 'skins.xml' in os.listdir('.') True
skins.xml 配置文件使主题在安装时默认,并使用来自“Plone Default”的主题层列表,没有任何新层(目前还没有)
>>> cat('skins.xml') <?xml version="1.0"?> ... <object name="portal_skins" ... default_skin="My Theme Name"> ... <skin-path name="My Theme Name" based-on="Plone Default"> <!-- -*- extra layer stuff goes here -*- --> <BLANKLINE> </skin-path> ...
import_steps.xml - 从 _setuphandlers.py_ 模块调用 _setupVarious_ 函数以进行附加安装步骤
>>> cat('import_steps.xml') <?xml version="1.0"?> ... <import-step id="quintagroup.theme.example.various" ... handler="quintagroup.theme.example.setuphandlers.setupVarious" ... </import-step> ...
查看 setuphandlers.py 模块
>>> cd('../..') >>> cat('setuphandlers.py') def setupVarious(context): ...
扩展主题
ZopeSkel 包带来的最佳特性之一是 localcommand。
这部分显示了如何使用附加的有用功能扩展主题(使用 qplone3_theme ZopeSkel 模板生成)
皮肤层
视图
小部件
小部件
CSS
JavaScript
zexp文件中的对象
因此,在 qplone3_theme 生成的包中,您可以使用 addcontent ZopeSkel 本地命令。
注意:localcommand(在我们的例子中为 addcontent)应在生成的主题包的任何子目录中调用。它将不会在这个包之外工作
>>> paster('addcontent -a') paster addcontent -a ... css_dtml_skin: A DTML file in skin layer with CSS registration css_resource: A Plone 3 CSS resource template ... import_zexps: A template for importing zexp-objects into portal on installation js_resource: A Plone 3 JS resource template N portlet: A Plone 3 portlet ... skin_layer: A Plone 3 Skin Layer ... N view: A browser view skeleton viewlet_hidden: A Plone 3 Hidden Viewlet template viewlet_order: A Plone 3 Order Viewlet template ...
我们可以看到可用于我们主题的扩展子模板列表。‘N’ 字符告诉我们这些子模板已注册用于其他(原型)模板,但这无关紧要 - 它们可以正确扩展我们的主题。
添加 SKIN LAYER
为此,使用 skin_layer 子模板和 addcontent 本地命令
>>> paster('addcontent --no-interactive skin_layer') paster addcontent --no-interactive skin_layer Recursing into profiles ...
此命令将新的‘skin_layer’(默认名称)目录添加到 _skins_ 目录中,其中包含仅有的 CONTENT.txt 文件
>>> 'skin_layer' in os.listdir('skins') True >>> ls('skins/skin_layer') CONTENT.txt
skins.xml 配置文件也进行了更新
>>> cat('profiles/default/skins.xml') <?xml version="1.0"?> ... <object name="portal_skins" allow_any="False" cookie_persistence="False" default_skin="My Theme Name"> ... <object name="skin_layer" meta_type="Filesystem Directory View" directory="quintagroup.theme.example:skins/skin_layer"/> ... <skin-path name="My Theme Name" based-on="Plone Default"> ... <layer name="skin_layer" insert-after="custom"/> <BLANKLINE> </skin-path> ...
我们可以看到
skin_layer 目录被注册为文件系统目录视图
skin_layer 文件系统目录视图被添加到我们的主题层列表中
添加 PORTLET
在添加新的小部件之前,小部件目录中只有初始化文件可用
>>> ls('portlets') __init__.py configure.zcml
使用 portlet 子模板添加小部件
>>> paster('addcontent --no-interactive portlet') paster addcontent --no-interactive portlet ... Recursing into portlets ...
执行此本地命令后...
主题根目录中的 configure.zcml 文件 - 包括小部件注册
>>> cat('configure.zcml') <configure ... <include package=".portlets" /> ...
exampleportlet.pt 模板和 exampleportlet.py 脚本添加到小部件目录中
>>> files = ('exampleportlet.pt', 'exampleportlet.py') >>> [True for d in files if d in os.listdir('portlets')] [True, True]
并且 portlets/configure.zcml - 注册新小部件
>>> cat('portlets/configure.zcml') <configure ... <plone:portlet name="quintagroup.theme.example.portlets.ExamplePortlet" interface=".exampleportlet.IExamplePortlet" assignment=".exampleportlet.Assignment" view_permission="zope2.View" edit_permission="cmf.ManagePortal" renderer=".exampleportlet.Renderer" addview=".exampleportlet.AddForm" editview=".exampleportlet.EditForm" /> ...
最后,新小部件类型在 portlets.xml 配置文件中注册
>>> cat('profiles/default/portlets.xml') <?xml version="1.0"?> ... <portlet addview="quintagroup.theme.example.portlets.ExamplePortlet" title="Example portlet" description="" i18n:attributes="title; description" /> ...
感谢 ZopeSkel 开发者为此子模板;)
添加 CSS 资源
使用 css_resource 子模板
>>> paster("addcontent --no-interactive css_resource") paster addcontent --no-interactive css_resource Recursing into browser ... Recursing into profiles ...
此模板将(如果尚不存在)_stylesheets_ 目录添加到 _browser_ 目录中
>>> 'stylesheets' in os.listdir('browser') True
在 _stylesheets_ 资源目录中添加了空的 main.css 样式表资源
>>> 'main.css' in os.listdir('browser/stylesheets') True >>> cat('browser/stylesheets/main.css') <BLANKLINE>
新的资源目录在 configure.zcml 中注册
>>> cat('browser/configure.zcml') <configure ... <browser:resourceDirectory name="quintagroup.theme.example.stylesheets" directory="stylesheets" layer=".interfaces.IThemeSpecific" /> ...
并且 cssregistry.xml 配置文件被添加到 profiles/default 目录中,其中注册了 main.css 样式表
>>> 'cssregistry.xml' in os.listdir('profiles/default') True >>> cat('profiles/default/cssregistry.xml') <?xml version="1.0"?> <object name="portal_css"> <BLANKLINE> <stylesheet title="" id="++resource++quintagroup.theme.example.stylesheets/main.css" media="screen" rel="stylesheet" rendering="inline" cacheable="True" compression="safe" cookable="True" enabled="1" expression=""/> ...
将 CSS 资源作为 dtml-file 添加到皮肤层中
此模板实际上与上一个模板完全相同,但添加了 layer_name 变量,用于指定要在其中添加 css dtml-file 的皮肤层。当然,css 资源被添加到指向 skins/<layer_name>/<css_reseource_name>.dtml 文件的 skins 目录中。
此子模板在将CSS注册为资源层之前具有多个优点
在dtml文件中,您可以使用dtml语言的强大功能
如果需要,客户可以覆盖此资源
重要:要向注册的皮肤层添加CSS资源,您应与skin_layer子模板一起使用此子模板。
使用css_dtml_skin子模板
>>> paster("addcontent --no-interactive css_dtml_skin") paster addcontent --no-interactive css_dtml_skin Recursing into profiles ... Recursing into skins ...
此模板将main.css.dtml文件添加到skins/skin_layer文件夹
>>> 'main.css.dtml' in os.listdir('skins/skin_layer') True
main.css.dtml文件已准备好作为dtml文档使用
>>> cat('skins/skin_layer/main.css.dtml') /* ... /* <dtml-with base_properties> (do not remove this :) */ ... /* </dtml-with> */ <BLANKLINE>
并且 cssregistry.xml 配置文件被添加到 profiles/default 目录中,其中注册了 main.css 样式表
>>> 'cssregistry.xml' in os.listdir('profiles/default') True >>> cat('profiles/default/cssregistry.xml') <?xml version="1.0"?> <object name="portal_css"> <BLANKLINE> <stylesheet title="" id="++resource++quintagroup.theme.example.stylesheets/main.css" media="screen" rel="stylesheet" rendering="inline" cacheable="True" compression="safe" cookable="True" enabled="1" expression=""/> ...
添加JAVASCRIPT资源
使用js_resource子模板
>>> paster('addcontent --no-interactive js_resource') paster addcontent --no-interactive js_resource Recursing into browser ... Recursing into profiles ...
此模板将(如果尚不存在)在_browser_目录中添加_scripts_目录
>>> 'scripts' in os.listdir('browser') True
在_scripts_目录中添加了空的foo.js JavaScript文件
>>> 'foo.js' in os.listdir('browser/scripts') True >>> cat('browser/scripts/foo.js') <BLANKLINE>
如果尚未注册,新资源目录已在configure.zcml中注册
>>> cat('browser/configure.zcml') <configure ... <browser:resourceDirectory name="quintagroup.theme.example.scripts" directory="scripts" layer=".interfaces.IThemeSpecific" /> ...
在profiles/default目录中添加了cssregistry.xml配置文件(如果尚不存在),并注册了新的foo.js JavaScript资源
>>> 'jsregistry.xml' in os.listdir('profiles/default') True >>> cat('profiles/default/jsregistry.xml') <?xml version="1.0"?> <object name="portal_javascripts"> ... <javascript id="++resource++quintagroup.theme.example.scripts/foo.js" inline="False" cacheable="True" compression="safe" cookable="True" enabled="1" expression="" /> ...
测试视图子模板
视图子模板有两种类型
viewlet_order
viewlet_hidden
第一个用于添加新视图并设置ViewletManager的视图顺序,第二个仅隐藏指向的ViewletManager中的视图。
有序的新视图
使用viewlet_order子模板
>>> paster('addcontent --no-interactive viewlet_order') paster addcontent --no-interactive viewlet_order Recursing into browser ... Recursing into templates ... Recursing into profiles ...
此模板将在_browser_目录中添加(如果不存在;)_viewlets.py_模块。添加了Example ViewletBase类,该类绑定到templates/example_viewlet.pt模板
>>> 'viewlets.py' in os.listdir('browser') True >>> cat('browser/viewlets.py') from Products.CMFCore.utils import getToolByName from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile from plone.app.layout.viewlets import common ... class Example(common.ViewletBase): render = ViewPageTemplateFile('templates/example_viewlet.pt') <BLANKLINE>
检查templates目录中的模板文件
>>> 'example_viewlet.pt' in os.listdir('browser/templates') True >>> cat('browser/templates/example_viewlet.pt') <BLANKLINE>
新视图已在configure.zcml中注册
>>> cat('browser/configure.zcml') <configure ... <browser:viewlet name="quintagroup.theme.example.example" manager="plone.app.layout.viewlets.interfaces.IPortalHeader" class=".viewlets.Example" layer=".interfaces.IThemeSpecific" permission="zope2.View" /> ...
viewlets.xml配置文件已添加到profiles/default目录,其中包含新的视图注册,并按指定的视图管理器排序
>>> 'viewlets.xml' in os.listdir('profiles/default') True >>> cat('profiles/default/viewlets.xml') <?xml version="1.0"?> <object> ... <order manager="plone.portalheader" based-on="Plone Default" skinname="My Theme Name" > ... <viewlet name="quintagroup.theme.example.example" insert-after="*" /> <BLANKLINE> </order> <BLANKLINE> </object>
隐藏现有的视图
在这种情况下,您可以使用viewlet_hidden子模板
>>> paster('addcontent --no-interactive viewlet_hidden') paster addcontent --no-interactive viewlet_hidden Recursing into profiles ...
如上日志所示,只有添加/更新配置文件的内容
profiles/default目录中有一个viewlet.xml配置文件,该文件隐藏了指定视图管理器中的视图
>>> 'viewlets.xml' in os.listdir('profiles/default') True >>> cat('profiles/default/viewlets.xml') <?xml version="1.0"?> <object> ... <hidden manager="plone.portalheader" skinname="My Theme Name"> ... <viewlet name="example" /> <BLANKLINE> </hidden> ... </object>
添加ZEXPs导入
想象一下这样的情况:您正在开发一个主题,该主题使用一些额外的门户对象(用于某些potlets的文本文档)。然后,您的主题客户可以根据他的需求编辑这些对象。
对于这种情况,存在import_zexps子模板。
import_zexps子模板通过在主题安装时将zexp格式文件的列表导入到门户根目录中的机制扩展了您的主题。
>>> paster('addcontent --no-interactive import_zexps') paster addcontent --no-interactive import_zexps ... Recursing into import ... Recursing into profiles ... Inserting from profiles.zcml_insert ... ... Inserting from setuphandlers.py_insert into ... ...
如上日志所示
在主题的根目录中添加了“import”目录
更新了配置文件内容
更新了profiles.zcml文件
在setuphandlers.py模块中插入了一些内容
添加了空的“import”目录,您将在此目录中放置要安装到门户根目录的zexp对象。
>>> ls('import') CONTENT.txt
在profiles/import_zexps目录中添加了import_steps.xml,其中包含额外的quintagroup.theme.example.import_zexps步骤
>>> 'import_zexps' in os.listdir('profiles') True >>> 'import_steps.xml' in os.listdir('profiles/import_zexps') True >>> cat('profiles/import_zexps/import_steps.xml') <?xml version="1.0"?> ... <import-step id="quintagroup.theme.example.import_zexps" version="..." handler="quintagroup.theme.example.setuphandlers.importZEXPs" title="My Theme Name: Import zexps objects"> Import zexp objects into portal on My Theme Name theme installation </import-step> <BLANKLINE> ...
使用新的通用设置配置文件更新了profiles.zcml配置
>>> cat('profiles.zcml') <configure ... <genericsetup:registerProfile name="import_zexps" title="My Theme Name: Import ZEXPs" directory="profiles/import_zexps" description='Extension profile for importing objects of the "My Theme Name" Plone theme.' provides="Products.GenericSetup.interfaces.EXTENSION" /> <BLANKLINE> ...
检查setuphandlers.py模块 - 必须定义importZEXPs函数
>>> cat('setuphandlers.py') def setupVarious(context): ... def importZEXPs(context): ...
然后只需准备zexp对象并将它们复制到import目录。
发布说明!
在发布主题之前,我建议清理setup.py脚本
删除theme_vars参数(其值仅对主题开发有用)
删除entry_points参数(同样原因)。目前对plone来说,它是无用的。
还要删除paster_plugins参数(它在主题开发期间与entry_points一起使用时才有意义)
上述步骤可以防止主题分发/部署时可能出现的错误。
注意
quintagroup.themetemplate v0.25与ZopeSkel >= 2.15兼容
变更日志
0.25 (2010-06-24)
修正了包的版本[mylan]
解决了与ZopeSkel >= 2.15的不兼容性问题[mylan]
更新了测试[mylan]
0.2.2(未发布)
更新了import_zexps子模板 - 将此步骤移入单独的通用设置配置文件[mylan]
为更新的import_zexps子模板更新了测试[mylan]
0.2(未发布)
添加了新的css_dtml_skin子模板[mylan]
为css_dtml_skin子模板添加了测试[mylan]
0.14(未发布)
重构主题变量存储 - 现在存储在单独的theme_vars.cfg文件中,没有distutils编写器 [mylan]
清理代码 [mylan]
0.11 (2009-04-13)
移除setup.cfg [mylan]
0.10 (2009-04-13)
更新README [olha]
0.9 (2009-04-11)
更改包名/命名空间为quintagroup.themetemplate. [mylan]
0.8 (2009-04-10)
更新测试,README [mylan]
更新viewlet-order子模板 [mylan]
修复卸载错误 [mylan]
0.7 (未发布)
添加卸载配置文件以修复主题卸载后的皮肤工具 [piv]
0.1 (未发布)
首次导入具有嵌套命名空间的Theme模板。支持ZopeSkel的“addcommand”本地命令来扩展Theme模板,支持使用portlet和本地模板进行扩展。[mylan]
项目详情
下载文件
下载适用于您的平台的文件。如果您不确定选择哪个,请了解更多关于安装包的信息。
源代码分发
构建分发
quintagroup.themetemplate-0.25.tar.gz的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 88f34f3028505dc4c1174ec5b505382b0f40e3b50140401126bdde2116677034 |
|
MD5 | a46b462f520642b98235b384aefa82f6 |
|
BLAKE2b-256 | 98f7f88e85445019d96a54e698c183c25f032fb9204f2cc96cbfad553899e6fd |
quintagroup.themetemplate-0.25-py2.4.egg的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 663e86a7f5bb40ba38a5ad672c99866766eb13e0b5766b14431ebef9ce95a2c6 |
|
MD5 | 16121ae3a5fe496c895b47ea3e314bf8 |
|
BLAKE2b-256 | fc7b8f1a4d7ed838c18ee123aad835920d65fb1d69a23c930e5da2233263a6f2 |