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 |