如何覆盖模板"folder_full_view_item.pt";仅用于自定义类型? [英] How to override template "folder_full_view_item.pt" only for a Custom Type?

查看:93
本文介绍了如何覆盖模板"folder_full_view_item.pt";仅用于自定义类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个问题以令人困惑的方式演变.但是它的某些部分,特别是一些答案,可能对某人有用.因此,我将不修改此问题,并尝试在此处重新阐述该问题.

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:

  1. 模板folder_full_view.pt通过item.getObject().folder_full_view_item()调用folder_full_view_item.pt.
  2. Products.CMFPlone的模板folder_full_view_item.pt添加了不同的ViewletManager(abovecontenttitle等),并通过use-macro="item_macro"调用了商品的布局.
  3. 包括项目的模板(document_viewmytype_view等).
  1. The template folder_full_view.pt calls folder_full_view_item.pt via item.getObject().folder_full_view_item().
  2. Products.CMFPlone's template folder_full_view_item.pt adds different ViewletManagers (abovecontenttitle etc.) and calls the item's layout via use-macro="item_macro".
  3. 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.ptfolder_full_view.ptfolder_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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆