Plone 基于URL更改皮肤层

Plone 基于URL更改皮肤层,plone,zope,Plone,Zope,我正在创建一个网站,将有一个“桌面”和“移动”的主题。我有两个网站主题包:mysite.theme和mysite.mobile\u theme。mobile_主题是桌面主题的精简版本,具有新的视图和精简的Viewlet集。我想根据访问网站的URL(即mobile.mysite.com与www.mysite.com)在这两个主题之间切换 由于移动和桌面主题将共享大量代码,mysite.mobile_主题以以下方式从mysite.theme派生而来: 1) mobile_theme GS skins

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

由于移动和桌面主题将共享大量代码,mysite.mobile_主题以以下方式从mysite.theme派生而来:

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

<skin-path name="mysite.mobile_theme" based-on="mysite.theme">
3) 我在mysite.mobile_主题中注册了各种视图,以覆盖mysite.theme中的某些视图

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

在这个阶段,如果我在“默认外观”选项portal skins->properties中选择mysite.mobile_主题,一切正常运行:我的视图被使用,并且mobile_主题的GS配置文件中的viewlets设置被正确选取。这样看来,整个主题的设置是正确的

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

首先,我将“默认皮肤”切换回“mysite.theme”。然后,我在我的Plone站点的根目录中创建了一个访问规则,大致如下,根据URL选择一个皮肤。它位于plonesite/access\u规则,并设置为plone站点的access\u规则:

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\u skin','mysite.theme')
而不是调用
context.changeSkin(…)

使用此设置,显示的viewlets会根据我使用的URL正确更改--因此看起来皮肤在某个点上发生了更改--但是mysite.mobile_主题的视图类/模板没有优先于mysite.theme使用。总之:

  • 如果我从包含“mobile”的URL调用,我会得到mysite.theme的视图,但得到mysite.mobile\u theme的viewlet注册
  • 否则,我将获得mysite.theme的视图和mysite.theme的viewlet注册
看起来我可能需要挂接遍历机制来更改它,因此如果URL中有“mobile”,则会选择mysite.mobile_主题的视图,而不是mysite.theme视图,但我不确定这是否正确,也不确定该如何操作

谁能给我一些指点吗

在最初询问后更新3hr

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

“”“ 看来您必须在堆栈中的较低位置进行修补才能实现这一点。我查看了plone.gomobile中是如何完成的,他们monkeypatch皮肤选择代码本身。请参阅:


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

from zope.interface import alsoProvides
alsoProvides(context, IMobileView)
并让您的视图zcml为。。。IMobileView

[编辑:再想想,这真的应该是当你改变皮肤时发生的事情-额外的界面将是你的“IThemeSpecific”-所以我不确定这里的作用是什么,但是尝试一下
alsoProvides(context,IThemeSpecific)
]

你可以使用。它的主要用例是使用say edit.example.com上的Plone默认主题和www.example.com上的My Custom主题。不过,您可能可以调整它的属性表以适合您的用例

由于“移动主题”用例相当常见,我会接受补丁以使其更容易实现;或者我自己找个时间来做


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

我已经在一些移动主题原型中这样做了。请考虑两个不准备生产的插件:

相关代码为:

  • browserlayer上的修补程序,用于使用我的主题层标记请求:
  • plonetool上要在每个内容页上添加@@mobile的修补程序:
  • 如果浏览器层:

  • 如果您正在使用plone.app.theming,还可以切换您的重氮主题:


我尝试将其添加到我的访问规则中(这是一个脚本(Python)对象,因此我需要对一些模块进行解压)。不幸的是,这对我的结果没有任何影响。这个产品看起来满足了我的需要。我特别喜欢使用iBeforOverseEvent而不是monkey补丁。将此回复标记为已接受的答案。作为记录:现在(2013年),您可以制定仅在特定情况下适用的CSS规则。查找“CSS媒体查询”。使用这种方法,您只需要一个CSS文件和一组HTML。
from zope.interface import alsoProvides
alsoProvides(context, IMobileView)