CMF 皮肤中的模板是否可以被 Zope 3 浏览器:页面覆盖?

发布于 2024-10-07 12:37:57 字数 151 浏览 6 评论 0 原文

我正在尝试使用具有相同 name= 属性的 覆盖 CMF 皮肤层提供的视图。这在 Plone 中可能吗,或者浏览器视图只能覆盖其他浏览器视图吗?

I'm trying to override a view provided by a CMF skin layer with a <browser:page ... having the same name= attribute. Is this possible in Plone, or can browser views only override other browser views?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

慈悲佛祖 2024-10-14 12:37:57

(这有点晚了,但到底是什么)

CMF 皮肤层覆盖浏览器视图。这就是为什么您必须在 URL 中的 browserview 名称前面放置 @@ ,即消除歧义并确保调用 browserview 而不是 CMF 皮肤层模板。

所以简而言之,如果你把@@放在前面,browserview就会覆盖,否则不会。

即:

localhost:8080/Plone/@@myview 

覆盖:

localhost:8080/Plone/myview

要解决此问题,请覆盖 CMF 皮肤层中的模板,并 tal:define View 变量指向您的 @@myview。然后,您仍然可以从 CMF 皮肤层模板访问 BrowserViews 方法。

(This is a bit late, but what the hell)

CMF Skin layers override browser views. That is why you have to put @@ in front of a browserview's name in an URL, i.e to disambiguate it and make sure that the browserview is called instead of the CMF skin layer template.

So in short, if you put @@ in front, the browserview will override, otherwise not.

i.e:

localhost:8080/Plone/@@myview 

overrides:

localhost:8080/Plone/myview

To overcome this, override the template in your CMF skin layer and tal:define the View variable to point to your @@myview. You can then still access the BrowserViews methods from the CMF skin layer template.

回忆躺在深渊里 2024-10-14 12:37:57

默认情况下,CMF 皮肤机制在查找视图之前先查找portal_skins。您可以通过自定义 IPublishTraverse 适配器来更改此设置。这有点邪恶,但这可能有效(在 Plone 3 中测试 - 我不是 100% 确定 Plone 4 中的默认行为是什么):

from zope.component import adapts, queryMultiAdapter
from zope.publisher.interfaces.browser import IBrowserRequest 

from Acquisition import aq_base
from ZPublisher.BaseRequest import DefaultPublishTraverse
from Products.CMFCore.Skinnable import SKINDATA, SkinnableObjectManager

from thread import get_ident

_MARKER = object()

class SkinnableTraverser(DefaultPublishTraverse):
    adapts(SkinnableObjectManager, IBrowserRequest)

    def publishTraverse(self, request, name):
        """Let the default traverser do its job, but if the thing that was
        returned was from a skin layer and there's a view with
        the same name, let the view win.
        """

        gotten = super(SkinnableTraverser, self).publishTraverse(request, name) 

        if not name.startswith('_') and not name.startswith('aq_'):
            sd = SKINDATA.get(get_ident())
            if sd is not None:
                ob, skinname, ignore, resolve = sd
                if resolve.get(name, None) is aq_base(gotten):
                    # This was retrieved as a skin resource
                    # Check if it could've been a view also

                    view = queryMultiAdapter((self.context, request), name=name)
                    if view is not None:
                        return view.__of__(self.context)

        return gotten

您需要将其注册为:

<adapter factory=".skins.SkinnableTraverser" />

可能在 overrides.zcml 中。另一种选择是在请求上使用更具体的标记接口,例如通过 browserlayer.xml 导入步骤安装的标记接口。

马丁

By default, the CMF skins mechanism looks in portal_skins before looking up a view. You can change this by customising the IPublishTraverse adapter. It's a bit evil, but this may work (tested in Plone 3 - I'm not 100% sure what the default behaviour is in Plone 4):

from zope.component import adapts, queryMultiAdapter
from zope.publisher.interfaces.browser import IBrowserRequest 

from Acquisition import aq_base
from ZPublisher.BaseRequest import DefaultPublishTraverse
from Products.CMFCore.Skinnable import SKINDATA, SkinnableObjectManager

from thread import get_ident

_MARKER = object()

class SkinnableTraverser(DefaultPublishTraverse):
    adapts(SkinnableObjectManager, IBrowserRequest)

    def publishTraverse(self, request, name):
        """Let the default traverser do its job, but if the thing that was
        returned was from a skin layer and there's a view with
        the same name, let the view win.
        """

        gotten = super(SkinnableTraverser, self).publishTraverse(request, name) 

        if not name.startswith('_') and not name.startswith('aq_'):
            sd = SKINDATA.get(get_ident())
            if sd is not None:
                ob, skinname, ignore, resolve = sd
                if resolve.get(name, None) is aq_base(gotten):
                    # This was retrieved as a skin resource
                    # Check if it could've been a view also

                    view = queryMultiAdapter((self.context, request), name=name)
                    if view is not None:
                        return view.__of__(self.context)

        return gotten

You need to register this with:

<adapter factory=".skins.SkinnableTraverser" />

Possibly in an overrides.zcml. Another option would be to use a more specific marker interface on the request, e.g. one installed via the browserlayer.xml import step.

Martin

我的黑色迷你裙 2024-10-14 12:37:57

我不确定,但你可以快速做的是尝试使用 plone_skins 中的“自定义”文件夹。

您还可以尝试 http: //plone.org/documentation/kb/applying-a-custom-view-to-a-specific-folder

I am not sure about it, but what you can do for fast is to try it with "custom" folder from plone_skins.

You can also try "Alternative" way from http://plone.org/documentation/kb/applying-a-custom-view-to-a-specific-folder

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文