Banner¶
The Banner feature provides a flexible system for displaying contextual banners across the site. Banners can be configured to appear on specific paths or excluded from certain sections, enabling targeted messaging for different areas of the website.
Overview¶
Banners are Dexterity content types that support path-based visibility rules. They can be:
Displayed globally across the entire site
Restricted to specific sections using include paths
Hidden from certain areas using exclude paths
Managed through workflow states (publish/retract)
Cached efficiently using cache tags
Content Type¶
- Banner
A content item that can contain any content (text, images, links) and defines where it should be displayed.
Behaviors:
plone.dublincore- Dublin Core metadataplone.namefromtitle- Automatic ID from titleplone.versioning- Version historywcs.backend.banner.interfaces.IBannerBehavior- Path-based visibility
Configuration:
global_allow: False (Banners are typically only addable in a designated folder)
Schema Fields¶
The Banner behavior (IBannerBehavior) provides:
- include_paths
List of paths where the banner should be displayed. Each path is relative to the site root. Leave empty to display on all pages.
Example:
['/news', '/events']- exclude_paths
List of paths where the banner should NOT be displayed. Exclude paths take precedence over include paths.
Example:
['/private', '/admin']
Configuration¶
Banner settings are managed through the Plone registry:
- wcs.backend.banner_portal_type
Portal type used for banners. Default:
Banner- wcs.backend.banner_folder_id
ID of the folder containing banners within the navigation root. Default:
banners
Registry Configuration¶
<registry>
<record name="wcs.backend.banner_portal_type">
<field type="plone.registry.field.TextLine">
<title>Banner Portal Type</title>
</field>
<value>Banner</value>
</record>
<record name="wcs.backend.banner_folder_id">
<field type="plone.registry.field.TextLine">
<title>Banner Folder ID</title>
</field>
<value>banners</value>
</record>
</registry>
REST API¶
GET @banner¶
Retrieves all banners that should be displayed for the current context.
http
GET /Plone/my-page/@banner HTTP/1.1
Host: localhost:8080
Accept: application/json
curl
curl -i -X GET http://localhost:8080/Plone/my-page/@banner -H "Accept: application/json"
python-requests
requests.get('http://localhost:8080/Plone/my-page/@banner', headers={'Accept': 'application/json'})
Response Structure:
{
"@id": "http://localhost:8080/Plone/my-page/@banner",
"items": [
{
"@id": "http://localhost:8080/Plone/banners/global-banner",
"@type": "Banner",
"title": "Important Announcement",
"description": "Site-wide notification",
"UID": "abc123...",
"include_paths": [],
"exclude_paths": []
},
{
"@id": "http://localhost:8080/Plone/banners/news-banner",
"@type": "Banner",
"title": "News Section Banner",
"include_paths": ["/news"],
"exclude_paths": []
}
]
}
Path Matching Logic¶
The is_valid(context) method determines if a banner should be displayed:
Exclude paths are checked first - If the context path starts with any exclude path, the banner is hidden
Include paths are checked - If include paths are defined, the context must match at least one
Empty include paths - If no include paths are defined, the banner displays everywhere (except excluded paths)
Path Normalization¶
Paths can be specified with or without the portal path prefix:
/newsis equivalent to/Plone/newsBoth formats are automatically normalized
Examples:
Include Paths |
Exclude Paths |
Context Path |
Banner Displayed? |
|---|---|---|---|
|
|
Any |
Yes |
|
|
|
Yes |
|
|
|
No |
|
|
|
No |
|
|
|
Yes |
|
|
|
No |
Caching¶
The Banner feature integrates with the 7inOne caching system using cache tags.
Cache Tag Headers¶
When the @banner endpoint is called by anonymous users, the response includes cache tags:
banner- Generic tag for all banner-related contentIndividual banner UIDs - For precise cache invalidation
Cache Invalidation¶
The BannerUIDContentCollector handles cache invalidation:
On publish or schedule: Invalidates the generic
bannertag (affects all cached@bannerresponses)On retract: Invalidates only the specific banner’s UID
This ensures:
New or updated published banners appear immediately across the site
Retracted banners only invalidate affected cached responses
Integration Guide¶
Fetching Banners via REST API¶
JavaScript Example:
async function fetchBanners(contextUrl) {
const response = await fetch(`${contextUrl}/@banner`, {
headers: {
'Accept': 'application/json'
}
});
const data = await response.json();
return data.items;
}
// Usage
const banners = await fetchBanners('http://localhost:8080/Plone/news/article');
banners.forEach(banner => {
displayBanner(banner.title, banner.description);
});
Python Example:
import requests
response = requests.get(
'http://localhost:8080/Plone/news/@banner',
headers={'Accept': 'application/json'}
)
banners = response.json()['items']
File Locations¶
Content type:
wcs/backend/banner/content.pyInterfaces/Behavior:
wcs/backend/banner/interfaces.pyREST API endpoint:
wcs/backend/banner/restapi.pyZCML configuration:
wcs/backend/banner/configure.zcmlType definition:
wcs/backend/profiles/default/types/Banner.xmlRegistry configuration:
wcs/backend/profiles/default/registry/banner.xmlCache collector:
wcs/backend/caching/banner_collector.pyTests:
wcs/backend/tests/test_banner.py