Может ли шаблон в оболочке CMF быть переопределен страницей браузера Zope 3: - PullRequest
3 голосов
/ 14 декабря 2010

Я пытаюсь переопределить представление, предоставляемое слоем темы CMF, с <browser:page ..., имеющим тот же атрибут name=.Возможно ли это в Plone, или представления обозревателя могут переопределять только представления обозревателя?

Ответы [ 3 ]

5 голосов
/ 31 января 2011

(это немного поздно, но какого черта)

Слои CMF Skin перекрывают представления браузера. Вот почему вы должны поставить @@ перед именем браузера в URL-адресе, т. Е. Чтобы устранить его неоднозначность и убедиться, что браузер вызывается вместо шаблона слоя оболочки CMF.

Короче говоря, если вы поставите @@ впереди, браузер переопределит, иначе нет.

т.е:

localhost:8080/Plone/@@myview 

Переопределение:

localhost:8080/Plone/myview

Чтобы преодолеть это, переопределите шаблон в слое CMF и tal:define переменную View, чтобы указать на @@myview. После этого вы все равно можете получить доступ к методам BrowserViews из шаблона слоя CMF.

3 голосов
/ 19 февраля 2011

По умолчанию механизм скинов 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

2 голосов
/ 17 декабря 2010

Я не уверен в этом, но то, что вы можете сделать быстро, это попробовать его с помощью "пользовательской" папки из plone_skins.

Вы также можете попробовать "Альтернативный" способ из http://plone.org/documentation/kb/applying-a-custom-view-to-a-specific-folder

...