Изменение слоя скина на основе URL - PullRequest
2 голосов
/ 06 июня 2011

Я создаю сайт, который будет иметь «настольную» и «мобильную» тему. У меня есть два пакета тем для этого сайта: mysite.theme и mysite.mobile_theme. Mobile_theme - это урезанная версия темы рабочего стола с новыми представлениями и сокращенным набором представлений. Я хочу переключаться между этими двумя темами в зависимости от 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) Я использовал стандартную настройку, чтобы иметь разные регистрации для каждой темы.

На этом этапе, если я выберу mysite.mobile_theme в опции «Скины портала по умолчанию» -> свойства портала, все будет работать правильно : используются мои представления и параметры просмотра из профиля GS mobile_theme: правильно подобрал. Похоже, что тема настроена правильно в целом.

Как уже упоминалось выше, я хотел бы переключаться между этими двумя темами на основе URL.

Сначала я поменял "скин по умолчанию" обратно на "mysite.theme". Затем я создал access_rule в корне на моем сайте Plone, примерно следуя этим инструкциям , чтобы выбрать скин на основе URL. Он находится по адресу plonesite / access_rule и настроен как access_rule для сайта plone: ​​

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(...).

Используя эту настройку, отображаемые вейвлеты корректно меняются в зависимости от того, какой URL я использовал - поэтому похоже, что в какой-то момент меняется скин - но классы / шаблоны представления mysite.mobile_theme не используются в предпочтение mysite.theme's. В итоге:

  • Если я звоню с URL-адреса, содержащего «mobile», я получаю представления mysite.theme, но регистрируются в viewlet mysite.mobile_theme.
  • В противном случае я получаю взгляды mysite.theme и регистрацию в viewlet mysite.theme.

Похоже, мне, возможно, придется подключиться к механизму обхода, чтобы изменить его, поэтому, если "URL-адрес" указан в URL-адресе, выбираются представления mysite.mobile_theme, зарегистрированные для его IThemeSpecific, а не mysite.theme, но Я не уверен, что это правильно, и как бы я поступил об этом.

Кто-нибудь может дать мне несколько советов?

ОБНОВЛЕНИЕ 3 часа после первоначального запроса

Чтобы ответить на мой собственный вопрос (который я не могу сделать в течение еще 5 часов из-за правил SO):

""» Похоже, что вы должны исправить гораздо ниже в стеке, чтобы это работало. Я посмотрел, как это было сделано в plone.gomobile, и они установили скин, выбирая сам код. См:

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

Ответы [ 3 ]

2 голосов
/ 06 июня 2011

Вы можете использовать colle.editskinswitcher . Его основной вариант использования - использовать тему Plone Default на скажем edit.example.com и My Custom Theme на www.example.com. Вы, вероятно, можете настроить его свойства листа, чтобы соответствовать вашему варианту использования.

Поскольку случай использования «мобильной темы» довольно распространен, я бы принял патчи, чтобы сделать это проще; или я сам могу над этим поработать некоторое время.

(Кстати, обратите внимание, что есть ветка fix-browser-layer, которая может помочь, если вы пропустите некоторые элементы, зарегистрированные для определенного слоя браузера; кажется, готов к слиянию, за исключением того, что я сначала хотел бы добавить несколько тестов.)

2 голосов
/ 06 июня 2011

Я сделал это в некоторых прототипах мобильных тем.Пожалуйста, обратите внимание, что два дополнения не готовы к производству:

Соответствующий код:

0 голосов
/ 06 июня 2011

Правильно ли я понимаю, что по мобильному URL ваши скины верны, а ваши Zope3 Views - нет?Что имеет смысл для меня, так как классы представления основаны на интерфейсах.В том же коде выше, где вы используете context.changeSkin, добавьте:

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

и попросите ваш zcml указать for ... IMobileView

[edit: если подумать, это действительно должно бытьчто происходит, когда вы меняете скин - где дополнительным интерфейсом будет ваш "IThemeSpecific" - так что я не уверен, что здесь происходит, но не мешало бы попробовать alsoProvides(context, IThemeSpecific)]

...