如何仅为自定义类型覆盖模板“folder_full_view_item.pt”?

时间:2014-01-30 18:06:18

标签: templates plone override theming

这个问题以一种令人困惑的方式演变。虽然它的一些部分,特别是一些答案,可能对某些人有用。因此,我会不加修改这个问题,我会尝试重新提出问题here


使用folder_full_view_item.pt覆盖模板z3c.jbot将覆盖所有内容类型的模板。 如何仅针对具有多种类型的产品中的单个内容类型MyType覆盖它?

具有以下结构:

Folder (layout=folder_full_view)
    Document (layout=document_view)
    MyType (layout=mytype_view)

Plone中的默认步骤是:

  1. 模板folder_full_view.pt通过folder_full_view_item.pt调用item.getObject().folder_full_view_item()
  2. Products.CMFPlone的模板folder_full_view_item.pt添加了不同的Viewlet管理器(上面的内容标题等),并通过use-macro="item_macro"调用项目的布局。
  3. 包含项目的模板(document_viewmytype_view等)。
  4. 我需要的是一种覆盖模板folder_full_view_item.pt的方法。在步骤#2中调用folder_full_view_item.pt的覆盖模板MyType和所有其他内容类型的Plone folder_full_view_item.pt

    更新

    似乎无法覆盖模板folder_full_view_item.pt(不使用jbot)。模板item.getObject().folder_full_view_item()中的调用folder_full_view.pt似乎也没有通过“queryMultiAdapter”。

    我在这里介绍了重现它的所有步骤,并确认忽略了folder_full_view_item

    设置PLONE_HOME路径并根据需要删除现有exaple.theme

    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运行buildout:

    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添加到buildout:

    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)复制到主题:

    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
    

    稍微修改覆盖模板以识别它们:

    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
    

    运行buildout并启动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),那么您可以执行以下操作:

    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

    根据建议添加以下内容也不起作用:

    从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
    

    注册浏览器:此图层的页面:

    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()似乎没有通过“常规”图层!

    我已经使用上面的示例测试了以下内容:

    folder_full_view中的

    将来电item.getObject().folder_full_view_item()替换为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
    

    修改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

    curl -s 'http://localhost:8080/Plone/folder' | grep "document_view"
    original document_view
    

    因此,核心问题似乎是:

    通过“常规”发布/图层流程在模板中调用item.getObject().template_name()吗?

    如果没有,如何调用folder_full_view_item形式folder_full_view之类的模板,并通过“常规”发布/图层流程进行调整?

    有人可以提示zope / plone的哪一部分负责此“发布/图层处理”吗?

4 个答案:

答案 0 :(得分:1)

而不是覆盖folder_full_view_item.pt,您应该create your own custom default template代替您的内容类型MyType

答案 1 :(得分:1)

要覆盖此模板,您需要两件事:浏览器图层和将在您的内容类型的上下文中使用的视图。

首先,声明浏览器层:

from zope.interface import Interface

class IMyLayer(Interface):
    """A layer specific for this add-on product.
    """

此浏览器图层需要与您的内容类型一起安装。使用以下内容创建 browserlayer.xml 文件:

<?xml version="1.0"?>
<layers>
  <layer name="my.type" interface="my.type.interfaces.IMyLayer" />
</layers>

然后,当您处于内容类型的上下文中并且浏览器图层处于活动状态时,视图将处于活动状态:

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 ,看看它。

另外,请不要忘记阅读有关Plone开发人员文档的Layers章节。

答案 2 :(得分:1)

尝试使用tal:condition="python:item_type=='MyType'"item_type!='MyType'来满足不同的显示需求。希望这有用。

答案 3 :(得分:0)

由于皮肤工具似乎已被弃用,并且可能涉及性能损失,我宁愿使用专用的浏览器视图来查看自定义内容类型,但要回答这个问题:

您可以使用collective.editskinswitcher(感谢M. v.Rees!),无需重写太多,甚至可以在此过程中获得一些漂亮且易于配置的开发功能(访问者视图,同时实际记录 - in,通过URL区分,例如)。

在这种情况下,我们利用在folderish contenttype-object上设置skin-property的可能性,粗略地说,这些步骤应该成交:

  • 将自定义folder_full_view_item.pt - 模板放置在任何主题的皮肤文件夹中。

  • 在创建contenttype时,添加一个事件监听器,它将刚出生的对象的skin_name设置为主题的皮肤名称(查看方法和道具的c.editskinswitcher,引用HTTP请求为@@switchDefaultSkin?skin_name=YourTheme,顺便说一句。

  • 将另一个主题皮肤设置为portal_skins-properties中所有其他上下文的全局默认值。