Skip to main content

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.zope 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

5.0.0 (2026-05-18)

Internal:

  • Update configuration files. [plone devs]

5.0.0a1 (2025-11-19)

Breaking changes:

  • Replace pkg_resources namespace with PEP 420 native namespace. Support only Plone 6.2 and Python 3.10+. (#3928)

4.0.4 (2025-09-11)

Internal:

  • Move distribution to src layout [gforcada] (#4217)

4.0.3 (2025-01-23)

Bug fixes:

  • Fix DeprecationWarnings. [maurits] (#4090)

4.0.2 (2024-11-30)

Bug fixes:

  • Fix removed unittest.makeSuite in python 3.13. [petschki] (#27)

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]

Release files for plone.theme 5.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for plone.theme 5.0.0
File Size Uploaded
plone_theme-5.0.0.tar.gz 19.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for plone.theme 5.0.0
File Interpreter ABI Platform
plone_theme-5.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 30.0 kB

Release files / plone_theme-5.0.0.tar.gz

Download URL plone_theme-5.0.0.tar.gz
Size 19.2 kB
Tags Source
SHA-256 checksum
How to use checksums
d01e9d075863bb6c7ec500a8b37cd8ac03d019e19fd5a7569223ade3ad29c2f4
BLAKE2b-256 checksum
How to use checksums
a008acaf05468e4948133863b71f008a3c307a6f6fc5d4ba274b923c59060ef7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.2

Release files / plone_theme-5.0.0-py3-none-any.whl

Download URL plone_theme-5.0.0-py3-none-any.whl
Size 10.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
2b63aebb513e799ea79163f681a9e1ec4429b57fed05f1c587bfeffdf2f0b80e
BLAKE2b-256 checksum
How to use checksums
a764072ea9e15b3be025a2db64ffeea1500a8d122457330a9565ee64c73e6465
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.2
Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page