2010-12-14 43 views

回答

5

“另类”的方式(这是有点晚了,但什么是地狱)

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

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

即:

localhost:8080/Plone/@@myview 

覆盖:

localhost:8080/Plone/myview 

为了克服这个问题,覆盖模板在你的皮肤CMF层和tal:defineView变量指向你的@@myview。然后,您仍然可以从CMF皮肤层模板访问BrowserViews方法。

+0

欢迎来到Stack Overflow!迟到的答案在这里非常受欢迎,我们更关心的是回答正确而不是快速。 – Pops 2011-01-31 13:36:10

+1

啊。谢谢你。在了解“@@”时,我的直接答复是“从什么方面消除歧义?”它还解释了为什么我可以使用'@@ myview'而不是'@@ view'来使用unrestrictedTraverse(),因为'view'(至少在我试过的地方)是一个皮肤模板,而不是浏览器视图。 – Auspex 2011-03-11 01:54:46

3

默认情况下,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导入步骤安装一个。

Martin