3. TTW Theming II: Creating a custom theme based on Barceloneta¶
In this section you will:
- Create a theme by inheriting from the Barceloneta theme.
- Using the
manifest.cfg
, register a production CSS file. - Use an XInclude to incorporate rules from the Barceloneta theme.
- Use
?diazo.off=1
to view unthemed versions. - Use conditional rules to have a different backend theme from the anonymous visitors theme.
Topics covered:
- Inheriting from Barceloneta.
- Diazo rule directives and attributes.
- Viewing the unthemed version of a Plone item.
- Creating a visitor-only theme.
Inheriting from Barceloneta¶
Copying Barceloneta makes your theme heavier and will likely make upgrading more difficult.
The Barceloneta theme provides many assets used by Plone’s utilities that you do not need to duplicate. Additionally new releases of the theme may introduce optimizations or bug fixes. By referencing the Barceloneta rules and styles, instead of copying them, you automatically benefit from any updates to the Barceloneta theme while also keeping your custom theme relatively small.
Exercise 1 - Create a new theme that inherits from Barceloneta¶
In this exercise we will create a new theme that inherits the Barceloneta rules and styles.
Create a new theme
and name it “Custom”
In the theming editor, ensure that your new theme contains the files
manifest.cfg
,rules.xml
,index.html
(from Barceloneta) andstyles.less
.
manifest.cfg
, declaring your theme:
[theme]
title = mytheme
description =
development-css = ++theme++custom/styles.less
production-css = ++theme++custom/styles.css
rules.xml
, including the Barceloneta rules:
<?xml version="1.0" encoding="UTF-8"?>
<rules
xmlns="http://namespaces.plone.org/diazo"
xmlns:css="http://namespaces.plone.org/diazo/css"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xi="http://www.w3.org/2001/XInclude">
<!-- Import Barceloneta rules -->
<xi:include href="++theme++barceloneta/rules.xml" />
<rules css:if-content="#visual-portal-wrapper">
<!-- Placeholder for your own additional rules -->
</rules>
</rules>
- a copy of
index.html
from Barceloneta (this one cannot be imported or inherited, it must be local to your theme). styles.less
, importing Barceloneta styles:
/* Import Barceloneta styles */
@import "++theme++barceloneta/less/barceloneta.plone.less";
/* Customize whatever you want */
@plone-sitenav-bg: pink;
@plone-sitenav-link-hover-bg: darken(pink, 20%);
.plone-nav > li > a {
color: @plone-text-color;
}
Then generate the styles.css
file using styles.less
and the “Build CSS” button.
Your theme is ready.
Diazo rule directives and attributes¶
The Diazo rules file is an XML document containing rules to specify where the content elements (title, footer, main text, etc.) will be located in the targeted theme page. The rules are created using rule directives which have attributes; attribute values are either CSS expressions or XPath expressions.
CSS selector based attributes¶
It is generally recommended that you use CSS3 selectors to target elements in your content or theme. The CSS3 selectors used by Diazo directives are listed below:
css:theme
- Used to select target elements from the theme using CSS3 selectors.
css:content
- Used to specify the element that should be taken from the content.
css:theme-children
- Used to select the children of matching elements.
css:content-children
- Used to identify the children of an element that will be used.
XPath selector based attributes¶
Depending on complexity of the required selector it is sometimes necessary or more convenient
to use XPath selectors instead of CSS selectors. XPath selectors use the unprefixed
attributes theme
and content
. The common XPath selector attributes include:
theme
- Used to select target elements from the theme using XPath selectors.
content
- Used to specify the element that should be taken from the content using XPath selectors.
theme-children
- Used to select the children of matching elements using XPath selectors.
content-children
- Used to identify the children of an element that will be used using XPath selectors.
You can also create conditions about the current path using if-path
.
Nota
For a more comprehensive overview of all the Diazo rule directives and related attributes see: http://docs.diazo.org/en/latest/basic.html#rule-directives
Viewing the unthemed Plone site¶
When you create your Diazo rules, it is important to know how the content Diazo is receiving from Plone is structured.
In order to see a “non-diazoed” version page, just add ?diazo.off=1
at the end of its URL.
Exercise 2 - Viewing the unthemed site¶
Use
diazo.off=1
to view the unthemed version of your site.Using your browser’s inspector, find out the location/name of some of Plone’s elements. Then try to answer the following:
What do you think is the difference between “content-core” and “content”? There are several viewlets, how many do you count? Can you identify any portlets, what do you think they are for?
Solution
The “content-core” does not include the “title” and “description” while the “content” combines the “title”, “description” and “content-core”.
Out of the box there are six viewlets (
viewlet-above-content
,viewlet-above-content-title
viewlet-below-content-title
,viewlet-above-content-body
,viewlet-below-content-body
,viewlet-below-content
).There are a few footer portlets which construct the footer of the site.
Exercise 3 - the <drop>
directives¶
Add a rule that drops the “search section” checkbox from the search box. See the diagram below:
Conditional attributes¶
The following attributes can be used to conditionally activate a directive.
css:if-content
- Defines a CSS3 expression: if there is an element in the content that matches the expression then activate the directive.
css:if-theme
- Defines a CSS3 expression: if there is an element in the theme that matches the expression then activate the directive.
if-content
- Defines an XPath expression: if there is an element in the content that matches the expression then activate the directive.
if-theme
- Defines an XPath expression: if there is an element in the theme that matches the expression then activate the directive.
if-path
- Conditionally activate the current directive based on the current path.
Nota
In a previous chapter we discussed the Plone <body>
element and how to take advantage of the custom CSS classes associated with it.
We were introduced to the attribute css:if-content
.
Remember that we are able to determine a lot of context related information from the classes,
such as:
- the current user role, and its permissions,
- the current content-type and its template,
- the site section and sub section,
- the current subsite (if any).
Here is an example
<body class="template-summary_view
portaltype-collection
site-Plone
section-news
subsection-aggregator
icons-on
thumbs-on
frontend
viewpermission-view
userrole-manager
userrole-authenticated
userrole-owner
plone-toolbar-left
plone-toolbar-expanded
plone-toolbar-left-expanded
pat-plone
patterns-loaded">
Converting an existing HTML template into an theme¶
In the Plone “universe” it is not uncommon to convert an existing HTML template into a Diazo theme. Just ensure that when you zip up the source theme that there is a single folder in the root of the zip file. We will explore this in more detail in the next exercise.
Exercise 4 - Convert a HTML template into a Diazo theme¶
In this exercise we will walk through the process of converting an existing free HTML theme into a Diazo-based Plone theme.
We’ve selected the free New Age Bootstrap theme. The theme is already packaged in a manner that will work with the theming tool.
Nota
When being distributed, Plone themes are packaged as zip files. A theme should be structured such that
there is only one top level directory in the root of the zip file. By convention the directory
should contain your index.html
and supporting files, the supporting
files (CSS, javascript and other files) may be in subdirectories.
To get started download a copy of the New Age theme as a zip file. Then upload it to the theme controlpanel.
Consejo
This is a generic theme, it does not provide the Plone/Diazo specific
rules.xml
ormanifest.cfg
file. When you upload the zip file the theming tool generates arules.xml
. In the next steps you will add additional files including amanifest.cfg
(perhaps in the future the manifest.cfg will also be generated for you).Select the downloaded zip file.
Add a
styles.less
file and import the Barceloneta styles.Add a
manifest.cfg
file, setproduction-css
equal tostyles.css
Nota
Clean Blog is a free Bootstrap theme, the latest version is available on github https://github.com/BlackrockDigital/startbootstrap-clean-blog
Consejo
You can identify the theme path by reading your browser’s address bar when your theme is open in the theming tool. You’ll need to include the proper theme path in your
manifest.cfg
, in this case it will most likely be something like++theme++startbootstrap-new-age-gh-pages
[theme] title = New Age prefix = ++theme++startbootstrap-new-age-gh-pages/ production-css = ++theme++startbootstrap-new-age-gh-pages/styles.css
Add rules to include the Barceloneta backend utilities
<?xml version="1.0" encoding="UTF-8"?> <rules xmlns="http://namespaces.plone.org/diazo" xmlns:css="http://namespaces.plone.org/diazo/css" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xi="http://www.w3.org/2001/XInclude"> <!-- Include the backend theme --> <xi:include href="++theme++barceloneta/backend.xml" />
Add rules to include content, add site structure, drop unneeded elements, customize the menu.
Advertencia
Look out for inline styles in this theme (i.e. the use of the
style
attribute on a tag). This is especially problematic with background images set with relative paths. The two issues that result are:- the relative path does not translate properly in the context of the theme;
- it can be tricky to dynamically replace background images provided by inline styles.
Creating a visitor-only theme - conditionally enabling Barceloneta¶
Sometimes it is more convenient for your website administrators to use Barceloneta, Plone’s default theme.
Other visitors would see a completely different layout provided by your custom theme.
To achieve this you will need to associate your visitor theme rules with
an expression like css:if-content="body.userrole-anonymous"
.
For rules that will affect logged-in users you can use the expression
css:if-content="body.:not(userrole-anonymous)"
.
Once you’ve combined the expressions above with the right Diazo rules you will be able to present an anonymous visitor with a specific HTML theme while presenting the Barceloneta theme to logged-in users.
Advertencia
The Barceloneta ++theme++barceloneta/rules.xml
expects the
Barceloneta index.html
to reside locally in your current theme.
To avoid conflict and to accomodate the inherited Barceloneta, ensure that
your theme file has a different name such as front.html
.
Exercise 5 - Convert the theme to be a visitor-only theme¶
In this exercise we will alter our theme from the previous exercise to make it into a visitor-only theme.
Update the
rules.xml
file to include Barceloneta rules.Consejo
Use
<xi:include href="++theme++barceloneta/rules.xml" />
Add conditional rules to
rules.xml
so that the new theme is only shown to anonymous users, rename the theme’sindex.html
tofront.html
and add a copy of the Barcelonetaindex.html
.Consejo
Copy the contents of the Barceloneta
index.html
file then add it to the theme as the newindex.html
file.Change
rules.xml
to look similar to this:<?xml version="1.0" encoding="UTF-8"?> <rules xmlns="http://namespaces.plone.org/diazo" xmlns:css="http://namespaces.plone.org/diazo/css" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xi="http://www.w3.org/2001/XInclude"> <notheme css:if-not-content="#visual-portal-wrapper" /> <rules css:if-content="body:not(.userrole-anonymous)"> <!-- Import Barceloneta rules --> <xi:include href="++theme++barceloneta/rules.xml" /> </rules> <rules css:if-content="body.userrole-anonymous"> <theme href="front.html" /> <replace css:theme-children=".intro header h2" css:content-children=".documentFirstHeading" /> <replace css:theme-children=".summary" css:content-children=".documentDescription" /> <replace css:theme-children=".preamble" css:content-children="#content-core" /> </rules> </rules>