如何覆盖模板"folder_full_view_item.pt";仅用于自定义类型? [英] How to override template "folder_full_view_item.pt" only for a Custom Type?
问题描述
这个问题以令人困惑的方式演变.但是它的某些部分,特别是一些答案,可能对某人有用.因此,我将不修改此问题,并尝试在此处重新阐述该问题.
This question has evolved in a confusing way. Some of its parts though, and specially some answers, might be useful for someone. Therefore I'll let this question unmodified and I'll try to reformulate the question here.
使用z3c.jbot
覆盖模板folder_full_view_item.pt
将覆盖所有内容类型的模板.
如何仅对具有多种类型的产品中的单个内容类型MyType
覆盖它?
Overriding the template folder_full_view_item.pt
with z3c.jbot
will override the template for all Content Types.
How do I override it only for a single Content Type MyType
in a Product with many types?
具有以下结构:
Folder (layout=folder_full_view)
Document (layout=document_view)
MyType (layout=mytype_view)
Plone中的默认步骤是:
The default steps in Plone are:
- 模板
folder_full_view.pt
通过item.getObject().folder_full_view_item()
调用folder_full_view_item.pt
. - Products.CMFPlone的模板
folder_full_view_item.pt
添加了不同的ViewletManager(abovecontenttitle等),并通过use-macro="item_macro"
调用了商品的布局. - 包括项目的模板(
document_view
,mytype_view
等).
- The template
folder_full_view.pt
callsfolder_full_view_item.pt
viaitem.getObject().folder_full_view_item()
. - Products.CMFPlone's template
folder_full_view_item.pt
adds different ViewletManagers (abovecontenttitle etc.) and calls the item's layout viause-macro="item_macro"
. - The template of the item (
document_view
,mytype_view
etc.) is included.
我需要的是一种覆盖模板folder_full_view_item.pt
的方法.在步骤2中,为MyType
调用覆盖的模板folder_full_view_item.pt
,为所有其他内容类型调用Plone的folder_full_view_item.pt
.
What I need is a way to override the template folder_full_view_item.pt
. Calling in step #2 the overridden template folder_full_view_item.pt
for MyType
and Plone's folder_full_view_item.pt
for all other Content Types.
更新
似乎无法覆盖模板folder_full_view_item.pt
(不使用jbot).模板folder_full_view.pt
中的调用item.getObject().folder_full_view_item()
似乎也没有通过"queryMultiAdapter".
It seems that the template folder_full_view_item.pt
cannot be overriden (without using jbot). The call item.getObject().folder_full_view_item()
in the template folder_full_view.pt
doesn't seems to go through "queryMultiAdapter" neither.
在这里,我将介绍复制它的所有步骤,并确认已忽略folder_full_view_item
:
I present here all the steps to reproduce it and confirm that folder_full_view_item
is ignored:
设置PLONE_HOME
路径,并在必要时删除现有的exaple.theme
:
Set the PLONE_HOME
path and remove existing exaple.theme
if necessary:
PLONE_HOME=/path/to/Plone-4.3.2
cd ${PLONE_HOME}/zeocluster/src
rm -rf ${PLONE_HOME}/zeocluster/src/example.theme
sed -i '/example\.theme/d' ${PLONE_HOME}/zeocluster/buildout.cfg
使用develop.cfg
运行构建:
sudo -u plone_buildout ${PLONE_HOME}/zeocluster/bin/buildout -c ${PLONE_HOME}/zeocluster/develop.cfg
cd ${PLONE_HOME}/zeocluster/src
rm -rf /home/Plone-4.3.2/zeocluster/src/example.theme
sudo -u plone_buildout ${PLONE_HOME}/zeocluster/bin/paster create \
--no-interactive \
--overwrite \
-o ${PLONE_HOME}/zeocluster/src \
-t plone3_theme example.theme \
expert_mode=all \
namespace_package=example \
package=theme \
skinname='ExampleTheme' \
skinbase='Sunburst Theme' \
empty_styles=False \
include_doc=True \
version=1.0 \
description='An installable theme for Plone 3' \
add_profile=True \
long_description= \
author= \
author_email= \
keywords='web zope plone theme' \
url='http://svn.plone.org/svn/collective/' \
license_name=GPL \
zip_safe=False \
zope2product=True
将example.theme
添加到扩展中:
sed -i '79i\ \ \ \ example.theme' ${PLONE_HOME}/zeocluster/buildout.cfg
sed -i '102i\ \ \ \ src/example.theme' ${PLONE_HOME}/zeocluster/buildout.cfg
注册browser:pages
cat << EOF > ${PLONE_HOME}/zeocluster/src/example.theme/example/theme/configure.zcml
<configure
xmlns:browser="http://namespaces.zope.org/browser"
xmlns="http://namespaces.zope.org/zope"
xmlns:five="http://namespaces.zope.org/five"
xmlns:cmf="http://namespaces.zope.org/cmf"
xmlns:i18n="http://namespaces.zope.org/i18n"
i18n_domain="example.theme">
<five:registerPackage package="." initialize=".initialize" />
<include package=".browser" />
<include file="skins.zcml" />
<include file="profiles.zcml" />
<i18n:registerTranslations directory="locales" />
<browser:page
for="*"
name="folder_full_view_item"
template="folder_full_view_item.pt"
layer="example.theme.browser.interfaces.IThemeSpecific"
permission="zope2.View"
/>
<browser:page
for="Products.ATContentTypes.content.folder.ATFolder"
name="folder_full_view"
template="folder_full_view.pt"
layer="example.theme.browser.interfaces.IThemeSpecific"
permission="zope2.View"
/>
<browser:page
for="Products.ATContentTypes.content.document.ATDocument"
name="document_view"
template="document_view.pt"
layer="example.theme.browser.interfaces.IThemeSpecific"
permission="zope2.View"
/>
</configure>
EOF
将原始文件(document_view.pt
,folder_full_view.pt
和folder_full_view_item.pt
)复制到主题:
copy original files (document_view.pt
, folder_full_view.pt
, and folder_full_view_item.pt
) to theme:
cp -f ${PLONE_HOME}/buildout-cache/eggs/Products.CMFPlone-4.3.2-py2.7.egg/Products/CMFPlone/skins/plone_content/document_view.pt \
${PLONE_HOME}/zeocluster/src/example.theme/example/theme/document_view.pt
cp -f ${PLONE_HOME}/buildout-cache/eggs/Products.CMFPlone-4.3.2-py2.7.egg/Products/CMFPlone/skins/plone_content/folder_full_view_item.pt \
${PLONE_HOME}/zeocluster/src/example.theme/example/theme/folder_full_view_item.pt
cp -f ${PLONE_HOME}/buildout-cache/eggs/Products.CMFPlone-4.3.2-py2.7.egg/Products/CMFPlone/skins/plone_content/folder_full_view.pt \
${PLONE_HOME}/zeocluster/src/example.theme/example/theme/folder_full_view.pt
稍微修改覆盖的模板以识别它们:
slightly modify overriden templates to recognize them:
sed -i '/<metal:content-core define-macro="content-core">/a overriden template at '${PLONE_HOME}'/zeocluster/src/example.theme/example/theme/document_view.pt' \
${PLONE_HOME}/zeocluster/src/example.theme/example/theme/document_view.pt
sed -i '/<metal:entries fill-slot="entries">/a overriden template at '${PLONE_HOME}'/zeocluster/src/example.theme/example/theme/folder_full_view.pt' \
${PLONE_HOME}/zeocluster/src/example.theme/example/theme/folder_full_view.pt
sed -i '/<div tal:replace="structure provider:plone.abovecontenttitle" \/>/i overriden template at '${PLONE_HOME}'/zeocluster/src/example.theme/example/theme/folder_full_view_item.pt' \
${PLONE_HOME}/zeocluster/src/example.theme/example/theme/folder_full_view_item.pt
chown -R plone_buildout example.theme
运行扩展并启动plone:
run buildout and start plone:
sudo -u plone_buildout ${PLONE_HOME}/zeocluster/bin/buildout -c ${PLONE_HOME}/zeocluster/develop.cfg
${PLONE_HOME}/zeocluster/bin/zeoserver restart
${PLONE_HOME}/zeocluster/bin/client1 fg
如果要以编程方式创建测试数据(例如从ipython创建),则可以执行以下操作:
If you want to programmatically create test data (e.g. from ipython) then you could do the following:
utils.sync()
plone_site_name = 'Plone'
# delete 'Plone' site if existing
if app.hasObject(plone_site_name): app.manage_delObjects(plone_site_name)
from Products.CMFPlone.factory import addPloneSite
# create 'Plone' site
plone_site = addPloneSite(
app,
plone_site_name,
profile_id=('Products.CMFPlone:plone',),
extension_ids=('plonetheme.classic:default',
'plonetheme.sunburst:default',),
setup_content=False,
)
plone_site = app[plone_site_name]
# install 'plone.app.theming' and 'example.theme'
plone_site.portal_quickinstaller.installProduct('plone.app.theming')
plone_site.portal_quickinstaller.installProduct('example.theme')
# create some content
plone_site.invokeFactory('Document', 'document')
folder_id = plone_site.invokeFactory('Folder', 'folder')
plone_site[folder_id].setLayout('folder_full_view')
plone_site[folder_id].invokeFactory('Document', 'document')
utils.commit()
更新2
按照建议添加以下内容也不起作用:
Adding the following as suggested doesn't work either:
从zope.interface.Interface定义一个子类:
define a subclass from zope.interface.Interface:
cat << EOF >> ${PLONE_HOME}/zeocluster/src/example.theme/example/theme/browser/interfaces.py
from zope.interface import Interface
class IMyLayer(Interface):
""" """
EOF
将其注册为浏览器层:
cat << EOF > ${PLONE_HOME}/zeocluster/src/example.theme/example/theme/profiles/default/browserlayer.xml
<?xml version="1.0"?>
<layers>
<layer name="imylayer" interface="example.theme.browser.interfaces.IMyLayer" />
</layers>
EOF
注册该层的浏览器:页面:
register the browser:page for this layer:
sed -i 's/layer="example.theme.browser.interfaces.IThemeSpecific"/layer="example.theme.browser.interfaces.IMyLayer"/' \
${PLONE_HOME}/zeocluster/src/example.theme/example/theme/configure.zcml
更新3
呼叫item.getObject().folder_full_view_item()
似乎没有通过常规"层!
The call item.getObject().folder_full_view_item()
seems not to go through the "usual" layers!
我已经使用上面的示例测试了以下内容:
I've tested the following with the example above:
用item.getObject().document_view()
修改原始的document_view.pt
echo "original document_view" > ${PLONE_HOME}/buildout-cache/eggs/Products.CMFPlone-4.3.2-py2.7.egg/Products/CMFPlone/skins/plone_content/document_view.pt
修改example.theme
echo "overriden document_view" > /home/Plone-4.3.2/zeocluster/src/example.theme/example/theme/document_view.pt
调用文档使用覆盖的document_view.pt
curl -s 'http://localhost:8080/Plone/document' | grep "document_view"
overriden document_view
但是调用文件夹(其中有文档)使用原始的document_view.pt
but calling the folder (with a document in it) uses the original document_view.pt
curl -s 'http://localhost:8080/Plone/folder' | grep "document_view"
original document_view
因此,核心问题似乎是:
Thus the central questions seem to be:
通过常规"发布/图层过程在模板中进行呼叫item.getObject().template_name()
吗?
goes the call item.getObject().template_name()
in a template through the "usual" publishing/layers process?
如果没有,如何调用folder_full_view_item
形式的模板folder_full_view
并使其通过常规"发布/图层过程?
If not, how to call a template like folder_full_view_item
form folder_full_view
and make it go trough the "usual" publishing/layers process?
有人可以暗示zope/plone的哪个部分负责此发布/分层过程"吗?
Can someone give a hint for which part of zope/plone is responsible for this "publishing/layers process"?
推荐答案
要覆盖此模板,您需要做两件事:浏览器层和将在您的内容类型的上下文中使用的视图.
To override this template you will need 2 things: a browser layer and the view that is going to be used in the context of your content type.
首先,声明浏览器层:
from zope.interface import Interface
class IMyLayer(Interface):
"""A layer specific for this add-on product.
"""
此浏览器层需要与您的内容类型一起安装.使用以下命令创建一个 browserlayer.xml 文件:
This browser layer needs to be installed with your content type. Create a browserlayer.xml file with the following:
<?xml version="1.0"?>
<layers>
<layer name="my.type" interface="my.type.interfaces.IMyLayer" />
</layers>
然后,当您处于内容类型的上下文中并且浏览器层处于活动状态时,视图将处于活动状态:
Then, the view will be active when you are in the context of your content type and when your browser layer is active:
from five import grok
class FolderFullViewItem(grok.View):
"""Override folder_full_view_item for MyType.
"""
grok.context(IMyType)
grok.layer(IMyLayer)
grok.name('folder_full_view_item')
grok.template('folder_full_view_item')
grok.require('zope2.View')
在 sc.blog 上,我们有一个类似的用例,其中我们覆盖了 folder_summary_view 和 folder_full_view ,看看它.
On sc.blog we have a similar use case on which we override folder_summary_view and folder_full_view, take a look on it.
此外,不要忘记阅读Plone开发人员文档中的 Layers 一章
Also, don't forget to read the Layers chapter on the Plone Developers Documentation.
这篇关于如何覆盖模板"folder_full_view_item.pt";仅用于自定义类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!