2010-12-14 18 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