Overview
========
Tools for managing themes in CMF and Plone sites.
plone.theme
===========
This package lets you mark the request with a "layer" interface conditional
on the currently selected skin (theme) in the portal_skins tool.
Most Zope 3 "visual" directives, like <browser:page /> or <browser:viewlet />
accept a 'layer' attribute, which should point to an interface. Recall that a
view is a multi-adapter on (context, request). Most views are registered
so that the 'request' being adapted only needs to provide Interface. This
is equivalent to saying layer="*".
By applying a marker interface to the request, and registering a view or
viewlet with this interface as the adapted 'layer', we can override a more
general view, or make a viewlet that is only shown for a particular layer.
In the context of CMF and Plone, we'd like to tie the layer to the current
skin selection. We do that by name.
What you have to do
-------------------
First, you should create a marker interface:
>>> from zope.interface import Interface
>>> class IMyTheme(Interface):
... """Marker interface for skins part of 'My Theme'
... """
Then, register this as a theme layer in ZCML:
<interface
interface=".interfaces.IMyTheme"
type="zope.publisher.interfaces.browser.IBrowserSkinType"
name="My Theme"
/>
The title here must match the name of the theme/skin selection in
portal_skins.
How it works
------------
Behind the scenes, the <interface /> registration marks IMyTheme with the
"IInterface" IThemelayer, and registers IMyTheme as a utility named "My Theme"
and providing IBrowserSkinType.
We do something to this effect in tests/tests.zcml.
Let us define the "My Theme" skin selection:
>>> from Products.CMFCore.utils import getToolByName
>>> portal_skins = getToolByName(layer['portal'], 'portal_skins')
>>> default_skin = portal_skins.getDefaultSkin()
>>> skin_path = portal_skins._getSelections()[default_skin]
>>> portal_skins.addSkinSelection('My Theme', skin_path)
In tests/tests.zcml we have registered two version of a view called
@@layer-test-view. One, for the default skin layer, simply outputs "Default".
The other outputs "My Theme".
Before we turn on the skin, we will get the default view.
>>> from plone.testing.z2 import Browser
>>> browser = Browser(layer['app'])
>>> browser.open(layer['portal'].absolute_url() + '/@@layer-test-view')
>>> from __future__ import print_function
>>> print(browser.contents)
Default
...
However, if we turn the skin on, we should see the effects of the marker
interface being applied.
>>> portal_skins.default_skin = 'My Theme'
>>> import transaction
>>> transaction.commit()
>>> browser.open(layer['portal'].absolute_url() + '/@@layer-test-view')
>>> print(browser.contents)
My Theme
...
And if we switch back:
>>> portal_skins.default_skin = 'Plone Default'
>>> transaction.commit()
>>> browser.open(layer['portal'].absolute_url() + '/@@layer-test-view')
>>> print(browser.contents)
Default
...
Changelog
=========
.. You should *NOT* be adding new change log entries to this file.
You should create a file in the news directory instead.
For helpful instructions, please see:
https://github.com/plone/plone.releaser/blob/master/ADD-A-NEWS-ITEM.rst
.. towncrier release notes start
4.0.1 (2023-10-07)
------------------
Internal:
- Update configuration files.
[plone devs] (cfffba8c)
4.0.0 (2023-04-27)
------------------
Breaking changes:
- Drop Python 2 and Plone 5.2 support.
[gforcada] (#6)
Internal:
- Update configuration files.
[plone devs] (2a4ba395)
3.0.7 (2020-04-22)
------------------
Bug fixes:
- Minor packaging updates. (#1)
3.0.6 (2018-06-20)
------------------
Bug fixes:
- Tests run on Python 3 [ale-rt]
3.0.5 (2018-04-04)
------------------
Bug fixes:
- Handle case where we get no skinname in Zope4.
[pbauer]
3.0.4 (2018-03-10)
------------------
Bug fixes:
- Minor administrativa fixes.
[gforcada]
3.0.3 (2017-07-03)
------------------
Bug fixes:
- removed unittest2 dependency
[kakshay21]
3.0.2 (2017-02-05)
------------------
Bug fixes:
- Fixed test when using Zope 4. [maurits]
3.0.1 (2016-11-17)
------------------
Fixes:
- Remove ZopeTestCase traces.
[gforcada]
3.0.0 (2015-06-10)
------------------
- 3.x is plone 5 only
[vangheem]
2.1.4 (2015-04-28)
------------------
- Remove dependency on CMFDefault
[tomgross]
2.1.3 (2015-03-27)
------------------
- Test layer is testing layer.
[bloodbare]
2.1.2 (2015-03-21)
------------------
- Move tests from PloneTestCase to plone.app.testing.
[sdelcourt,timo]
2.1.1 (2014-03-02)
------------------
- Remove hard dependency on CMFDefault.
[davisagli]
2.1 - 2011-05-12
----------------
- Update to import BeforeTraverseEvent from zope.traversing instead of
zope.app.publication.
[davisagli]
- Add MANIFEST.in.
[WouterVH]
2.0 - 2010-07-18
----------------
- Update license to GPL version 2 only.
[hannosch]
2.0b2 - 2010-03-05
------------------
- Protect against running multiple times. This can happen when using ++skin++
traversers or VirtualHostMonster.
[wichert]
2.0b1 - 2010-01-02
------------------
- Fix an error introduced by my previous adjustment. If a skin layer
extending the default layer was used (which is typical), then the
default layer would end up with higher precedence than browser
layers not extending the default layer.
[davisagli]
2.0a2 - 2009-11-13
------------------
- Inherit from the CMFDefault layer again, for compatibility with products
that depend only on CMF but are also usable within Plone, and register
views to the CMFDefault layer.
[davisagli]
2.0a1 - 2009-04-05
------------------
- Avoid inheriting from the CMFDefault browser layer and rather define our
own. We don't have anything in common with the CMFDefault layer.
[hannosch]
- Declare test dependencies in an extra.
[hannosch]
- Specify package dependencies.
[hannosch]
1.1 - 2009-04-04
----------------
- Make sure the theme layer takes precedence over other browser layers.
[davisagli]
1.0 - 2007-08-15
----------------
- First stable release
[wichert]
Raw data
{
"_id": null,
"home_page": "https://pypi.org/project/plone.theme",
"name": "plone.theme",
"maintainer": "",
"docs_url": null,
"requires_python": ">=3.8",
"maintainer_email": "",
"keywords": "plone theme manage",
"author": "Plone Foundation",
"author_email": "plone-developers@lists.sourceforge.net",
"download_url": "https://files.pythonhosted.org/packages/c2/98/bff185d14cd1056bdd142d9f808bfd1f2d298d4fe1a16679add81f232e90/plone.theme-4.0.1.tar.gz",
"platform": null,
"description": "Overview\n========\n\nTools for managing themes in CMF and Plone sites.\n\nplone.theme\n===========\n\nThis package lets you mark the request with a \"layer\" interface conditional\non the currently selected skin (theme) in the portal_skins tool.\n\nMost Zope 3 \"visual\" directives, like <browser:page /> or <browser:viewlet />\naccept a 'layer' attribute, which should point to an interface. Recall that a\nview is a multi-adapter on (context, request). Most views are registered\nso that the 'request' being adapted only needs to provide Interface. This\nis equivalent to saying layer=\"*\".\n\nBy applying a marker interface to the request, and registering a view or\nviewlet with this interface as the adapted 'layer', we can override a more\ngeneral view, or make a viewlet that is only shown for a particular layer.\n\nIn the context of CMF and Plone, we'd like to tie the layer to the current\nskin selection. We do that by name.\n\nWhat you have to do\n-------------------\n\nFirst, you should create a marker interface:\n\n >>> from zope.interface import Interface\n >>> class IMyTheme(Interface):\n ... \"\"\"Marker interface for skins part of 'My Theme'\n ... \"\"\"\n\nThen, register this as a theme layer in ZCML:\n\n <interface\n interface=\".interfaces.IMyTheme\"\n type=\"zope.publisher.interfaces.browser.IBrowserSkinType\"\n name=\"My Theme\"\n />\n\nThe title here must match the name of the theme/skin selection in\nportal_skins.\n\nHow it works\n------------\n\nBehind the scenes, the <interface /> registration marks IMyTheme with the\n\"IInterface\" IThemelayer, and registers IMyTheme as a utility named \"My Theme\"\nand providing IBrowserSkinType.\n\nWe do something to this effect in tests/tests.zcml.\n\nLet us define the \"My Theme\" skin selection:\n\n >>> from Products.CMFCore.utils import getToolByName\n >>> portal_skins = getToolByName(layer['portal'], 'portal_skins')\n >>> default_skin = portal_skins.getDefaultSkin()\n >>> skin_path = portal_skins._getSelections()[default_skin]\n >>> portal_skins.addSkinSelection('My Theme', skin_path)\n\nIn tests/tests.zcml we have registered two version of a view called\n@@layer-test-view. One, for the default skin layer, simply outputs \"Default\".\nThe other outputs \"My Theme\".\n\nBefore we turn on the skin, we will get the default view.\n\n >>> from plone.testing.z2 import Browser\n >>> browser = Browser(layer['app'])\n\n >>> browser.open(layer['portal'].absolute_url() + '/@@layer-test-view')\n >>> from __future__ import print_function\n >>> print(browser.contents)\n Default\n ...\n\nHowever, if we turn the skin on, we should see the effects of the marker\ninterface being applied.\n\n >>> portal_skins.default_skin = 'My Theme'\n >>> import transaction\n >>> transaction.commit()\n\n >>> browser.open(layer['portal'].absolute_url() + '/@@layer-test-view')\n >>> print(browser.contents)\n My Theme\n ...\n\nAnd if we switch back:\n\n >>> portal_skins.default_skin = 'Plone Default'\n >>> transaction.commit()\n\n >>> browser.open(layer['portal'].absolute_url() + '/@@layer-test-view')\n >>> print(browser.contents)\n Default\n ...\n\nChangelog\n=========\n\n.. You should *NOT* be adding new change log entries to this file.\n You should create a file in the news directory instead.\n For helpful instructions, please see:\n https://github.com/plone/plone.releaser/blob/master/ADD-A-NEWS-ITEM.rst\n\n.. towncrier release notes start\n\n4.0.1 (2023-10-07)\n------------------\n\nInternal:\n\n\n- Update configuration files.\n [plone devs] (cfffba8c)\n\n\n4.0.0 (2023-04-27)\n------------------\n\nBreaking changes:\n\n\n- Drop Python 2 and Plone 5.2 support.\n [gforcada] (#6)\n\n\nInternal:\n\n\n- Update configuration files.\n [plone devs] (2a4ba395)\n\n\n3.0.7 (2020-04-22)\n------------------\n\nBug fixes:\n\n\n- Minor packaging updates. (#1)\n\n\n3.0.6 (2018-06-20)\n------------------\n\nBug fixes:\n\n- Tests run on Python 3 [ale-rt]\n\n\n3.0.5 (2018-04-04)\n------------------\n\nBug fixes:\n\n- Handle case where we get no skinname in Zope4.\n [pbauer]\n\n\n3.0.4 (2018-03-10)\n------------------\n\nBug fixes:\n\n- Minor administrativa fixes.\n [gforcada]\n\n\n3.0.3 (2017-07-03)\n------------------\n\nBug fixes:\n\n- removed unittest2 dependency\n [kakshay21]\n\n\n3.0.2 (2017-02-05)\n------------------\n\nBug fixes:\n\n- Fixed test when using Zope 4. [maurits]\n\n\n3.0.1 (2016-11-17)\n------------------\n\nFixes:\n\n- Remove ZopeTestCase traces.\n [gforcada]\n\n3.0.0 (2015-06-10)\n------------------\n\n- 3.x is plone 5 only\n [vangheem]\n\n\n2.1.4 (2015-04-28)\n------------------\n\n- Remove dependency on CMFDefault\n [tomgross]\n\n\n2.1.3 (2015-03-27)\n------------------\n\n- Test layer is testing layer.\n [bloodbare]\n\n\n2.1.2 (2015-03-21)\n------------------\n\n- Move tests from PloneTestCase to plone.app.testing.\n [sdelcourt,timo]\n\n\n2.1.1 (2014-03-02)\n------------------\n\n- Remove hard dependency on CMFDefault.\n [davisagli]\n\n2.1 - 2011-05-12\n----------------\n\n- Update to import BeforeTraverseEvent from zope.traversing instead of\n zope.app.publication.\n [davisagli]\n\n- Add MANIFEST.in.\n [WouterVH]\n\n\n2.0 - 2010-07-18\n----------------\n\n- Update license to GPL version 2 only.\n [hannosch]\n\n\n2.0b2 - 2010-03-05\n------------------\n\n- Protect against running multiple times. This can happen when using ++skin++\n traversers or VirtualHostMonster.\n [wichert]\n\n\n2.0b1 - 2010-01-02\n------------------\n\n- Fix an error introduced by my previous adjustment. If a skin layer\n extending the default layer was used (which is typical), then the\n default layer would end up with higher precedence than browser\n layers not extending the default layer.\n [davisagli]\n\n\n2.0a2 - 2009-11-13\n------------------\n\n- Inherit from the CMFDefault layer again, for compatibility with products\n that depend only on CMF but are also usable within Plone, and register\n views to the CMFDefault layer.\n [davisagli]\n\n\n2.0a1 - 2009-04-05\n------------------\n\n- Avoid inheriting from the CMFDefault browser layer and rather define our\n own. We don't have anything in common with the CMFDefault layer.\n [hannosch]\n\n- Declare test dependencies in an extra.\n [hannosch]\n\n- Specify package dependencies.\n [hannosch]\n\n\n1.1 - 2009-04-04\n----------------\n\n- Make sure the theme layer takes precedence over other browser layers.\n [davisagli]\n\n\n1.0 - 2007-08-15\n----------------\n\n- First stable release\n [wichert]\n",
"bugtrack_url": null,
"license": "GPL version 2",
"summary": "Tools for managing themes in CMF and Plone sites",
"version": "4.0.1",
"project_urls": {
"Homepage": "https://pypi.org/project/plone.theme"
},
"split_keywords": [
"plone",
"theme",
"manage"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "278d5c9e0b35c3c2c9ea12181a4dd659a8c49078f54d965d9bfc6c1cd12a1b6d",
"md5": "0b512b2bd9834ecb346a0ad7ce95e263",
"sha256": "49b3ba73cba752b52aeeadd3cc8b4005ed28e00de622c497462c9a10712b7cdd"
},
"downloads": -1,
"filename": "plone.theme-4.0.1-py3-none-any.whl",
"has_sig": false,
"md5_digest": "0b512b2bd9834ecb346a0ad7ce95e263",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.8",
"size": 11171,
"upload_time": "2023-10-06T22:29:37",
"upload_time_iso_8601": "2023-10-06T22:29:37.115255Z",
"url": "https://files.pythonhosted.org/packages/27/8d/5c9e0b35c3c2c9ea12181a4dd659a8c49078f54d965d9bfc6c1cd12a1b6d/plone.theme-4.0.1-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "c298bff185d14cd1056bdd142d9f808bfd1f2d298d4fe1a16679add81f232e90",
"md5": "5a55bf2e1f60003132ce9fc16d777d3b",
"sha256": "476232fc804f050a07f32fe796ce4763e20cdaa658a473d472073598fc9a3de2"
},
"downloads": -1,
"filename": "plone.theme-4.0.1.tar.gz",
"has_sig": false,
"md5_digest": "5a55bf2e1f60003132ce9fc16d777d3b",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8",
"size": 18534,
"upload_time": "2023-10-06T22:29:38",
"upload_time_iso_8601": "2023-10-06T22:29:38.571092Z",
"url": "https://files.pythonhosted.org/packages/c2/98/bff185d14cd1056bdd142d9f808bfd1f2d298d4fe1a16679add81f232e90/plone.theme-4.0.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-10-06 22:29:38",
"github": false,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"lcname": "plone.theme"
}