根据URL更改皮肤层

时间:2011-06-06 12:17:28

标签: plone zope

我正在创建一个具有“桌面”和“移动”主题的网站。我为这个网站提供了两个主题包:mysite.theme和mysite.mobile_theme。 mobile_theme是桌面主题的精简版本,具有新视图和一组简化的Viewlet。我想根据访问该网站的URL(即mobile.mysite.com与www.mysite.com)之间切换这两个主题。

由于移动和桌面主题将分享大量代码,mysite.mobile_theme以下列方式从mysite.theme下载:

1)mobile_theme GS skins.xml有一个基于旧主题的皮肤路径,因此使用了桌面主题的CSS等:

<skin-path name="mysite.mobile_theme" based-on="mysite.theme">

2)IThemeSpecific标记是原始标记的子类,因此我不会覆盖移动网站的视图回溯到mysite.theme中的视图:

from mysite.theme.browser.interfaces import IThemeSpecific as IBaseTheme
class IThemeSpecific(IBaseTheme):
    """Marker interface that defines a Zope 3 browser layer.
    """

3)我在mysite.mobile_theme中注册了各种视图,以覆盖mysite.theme中的某些视图。

4)我使用通用设置为每个主题注册了不同的视图。

在此阶段,如果我在“默认外观”选项门户网站外观&gt;属性中选择了mysite.mobile_theme,一切正常:我使用了我的视图,并使用了mobile_theme的GS中的viewlets设置配置文件正确。所以看起来整个主题设置正确。

然而,如上所述,我想基于URL在这两个主题之间进行交换。

首先,我将“默认皮肤”换回“mysite.theme”。然后我在Plone站点的根目录中创建了一个access_rule,大致跟随these instructions来选择基于URL的外观。它位于plonesite / access_rule,并被设置为plone站点的access_rule:

url = context.REQUEST.get('ACTUAL_URL', '')

if 'mobile' in url:
   context.changeSkin('mysite.mobile_theme', context.REQUEST)
else:
   context.changeSkin('mysite.theme', context.REQUEST)

我也尝试使用context.REQUEST.set('plone_skin', 'mysite.theme')而不是调用context.changeSkin(...)

使用此设置,显示的viewlet根据我使用的URL正确更改 - 所以看起来皮肤在某些时候正在被更改 - 但mysite.mobile_theme的视图类/模板未被用于偏爱mysite.theme的。总结:

  • 如果我从包含“mobile”的网址拨打电话,我会收到mysite.theme的观点,但会看到mysite.mobile_theme的观看资料。
  • 否则,我会收到mysite.theme的观点和mysite.theme的viewlet注册。

看起来我可能必须挂钩遍历机制才能更改它,所以如果“移动”在URL中,则选择针对其IThemeSpecific注册的mysite.mobile_theme视图而不是mysite.theme,但是我我不确定这是否正确,也不知道如何解决这个问题。

任何人都可以给我一些指示吗?

最初询问后3小时更新

回答我自己的问题(由于SO规则我不能再做5个小时):

“”” 看起来你必须在堆栈中进行低得多的补丁才能使其正常工作。我看看它是如何在plone.gomobile中完成的,并且它们选择代码本身的monkeypatch皮肤。参见:

http://code.google.com/p/plonegomobile/source/browse/gomobile.mobile/trunk/gomobile/mobile/monkeypatch.py “”“

3 个答案:

答案 0 :(得分:2)

您可以使用collective.editskinswitcher。它的主要用例是在www.example.com上使用说明edit.example.com和My Custom Theme的Plone Default主题。您可以调整其属性表以适合您的用例。

由于“移动主题”用例相当普遍,我会接受补丁以使其更容易;或者我可以在某个时候自己动手。

(顺便说一句,请注意,当你错过了一些为特定浏览器层注册的项目时,有一个fix-browser-layers分支可能会有所帮助;似乎已经准备好合并,除了我想先添加一些测试。)

答案 1 :(得分:2)

我在移动主题的一些原型中做到了这一点。请考虑两个尚未准备好生产的插件:

相关代码是:

答案 2 :(得分:0)

我是否理解正确的移动网址皮肤是正确的,但您的Zope3视图却不正确?这对我来说很有意义,因为视图类基于接口。在上面使用context.changeSkin的相同代码中,添加:

from zope.interface import alsoProvides
alsoProvides(context, IMobileView)

并让您的视图zcml指定for ... IMobileView

[编辑:第二个想法,这真的应该是当你改变皮肤时会发生什么 - 其他界面将是你的“IThemeSpecific” - 所以我不确定这里有什么用,但它不会伤害尝试alsoProvides(context, IThemeSpecific)]