A tour of the starter theme
This page is for designers who want to see how a theme can be made portable between installations. The extension
cjw_themes_jumper (Composer package se7enxweb/cjw_themes_jumper) carries the design starter, used by the
starter and starter_ger siteaccesses of the demonstration installation. It answers: how the theme splits its
settings, how it finds content without node ids, and how it draws the page with the layouts engine.
Contents
- What it brings
- Global settings and siteaccess settings
- Content by remote id, never by node id
- A settings file of its own
- The pagelayout draws a layout
- Stylesheets
- Ideas worth copying
What it brings
By its README: the design starter (pagelayout, header, offcanvas menu, breadcrumb, pre-footer and footer; full,
line, list, tile, teaser, slide, gallery and embed views), templates for the layouts blocks and their view types,
custom XML tags with plain renderings for every other design (in design/standard/), image aliases cjw_i30 to
cjw_i1920, a map tile proxy module (osm_proxy) so visitors never contact the tile server, and German design
strings.
Global settings and siteaccess settings
The extension is active for every siteaccess (ActiveExtensions[]), but only a few settings are global:
- global (
settings/):design.ini(the design),content.ini(the custom XML tags, so every siteaccess can open and save the content without losing tags),image.ini(aliases),cjw_jumper.iniandosm_proxy.ini; - per siteaccess (
settings/siteaccess/cjw_starter/):site.ini,override.ini,module.ini,collect.ini,explayouts.ini, everything that changes how a site behaves.
The starter siteaccesses pull the per-siteaccess part in with one line:
[SiteAccessSettings]
ExtensionSettingsSiteAccess=cjw_starterResult: the administration and other sites are not affected by the theme's overrides, and a second language siteaccess needs no copies.
Content by remote id, never by node id
Node ids differ between installations. The theme therefore names content by remote id, which stays the same when the content package is installed elsewhere:
- in
override.ini:Match[remote_id]=cjw-starter-o-rootfor the root page's full view; - in
cjw_jumper.ini:[SiteInfo] NodeRemoteID=cjw-starter-n-65; - in templates:
fetch( 'content', 'node', hash( 'remote_id', ezini( 'SiteInfo', 'NodeRemoteID', 'cjw_jumper.ini' ) ) ).
Its settings file says: "Anything not found is left out of the page; the chrome then builds itself from the content tree alone." That is a good rule for any theme.
A settings file of its own
cjw_jumper.ini holds the design's choices: [Header] (the classes of header images, fallback images, landing and
large-header classes, logo images), [Menu], [LayoutSettings] (which layout types and name prefixes belong to the
design, which module views are drawn without a layout). The templates read them with ezini( ..., 'cjw_jumper.ini' ).
A theme setting in its own INI file can be changed per siteaccess without touching templates. See
Design extensions.
The pagelayout draws a layout
design/starter/templates/pagelayout.tpl documents its variables at the top (all prefixed pl_), then:
- fetches the current node from
$module_result.content_info.node_id; - for a full view, resolves the layout of the node with
fetch( 'explayouts', 'resolve_layout_for_node', hash( 'node_id', ... ) )and keeps it only when its type and name belong to this design ([LayoutSettings]ofcjw_jumper.ini); - otherwise builds a "chrome" layout in the template itself: header zone, main zone with a
full_viewblock, footer zone with a two-column pre-footer; - draws it with
{include uri='design:explayouts/layout.tpl' layout=$pl_layout}, or, for the module views listed as plain, draws header,#mainwith{$module_result.content}and footer directly.
So the same block templates draw editor-built landing pages and ordinary pages. See Layouts for designers.
Stylesheets
pagelayout/head/style.tpl loads its files in one ezcss_load call at pack level 1 (merged, not minified), with the
order kept as in the original site ("the cascade order is the pixel contract: never reorder"). It also prints a short
<style> block that hides content blocks of other languages. On a site with an enforced Content Security Policy
such a block would need to move into a stylesheet (for example one rule per language in a packed file, switched by a
class on <html>); see No inline CSS.
Ideas worth copying
- Remote ids instead of node ids, in settings, overrides and templates.
- Behavior settings per siteaccess through
ExtensionSettingsSiteAccess, global settings only where every siteaccess needs them. - A settings file of the theme's own for every design choice.
- Page variables defined once at the top of the pagelayout, documented in a comment.
- A plain fallback for every missing piece of content.
Related pages
- The themes that ship with Exponential
- Designs and siteaccesses
- Override a single node
- Free documentation: this page is free to copy, translate and improve under the GNU FDL 1.3.
Become an Exponential Partner
Partners share their information, provide funding, contribute back and develop the products with us, and that is how Exponential grows. A partner website and dashboard are planned for mid-2027: please become a partner today to speed up our growth rate and land new features faster.