Commera

Commera

Open in ChatGPT
Ask ChatGPT about this page
Open in Claude
Ask Claude about this page

Architecture

A Commera theme has three parts: a Shop Theme record, a theme folder with templates, and a public folder with assets. All three are in the Frappe app that owns the record's Module.

Folder layout

The folder name is the theme name in lowercase, with spaces and hyphens changed to _. For Acme Catalog, it is acme_catalog. Two themes cannot have the same folder name, so My-Theme and My Theme cannot both exist.

Path in your app What it holds Served to the browser
<app>/themes/<folder>/components/ The layout, includes, macros and sections that pages use No
<app>/themes/<folder>/pages/ One .html per page, each with an optional .py controller No
<app>/themes/<folder>/styles/ CSS sources for a Tailwind build No
<app>/themes/<folder>/tailwind.input.css The Tailwind entry file, for a Tailwind theme only No
<app>/public/themes/<folder>/ CSS, scripts, images, fonts and a Tailwind output file Yes, at /assets/<app>/themes/<folder>/
<app>/<module>/shop_theme/<folder>/<folder>.json The theme record No. bench migrate imports it.

The first save of a new record in developer mode makes these empty folders: components/includes, components/macros, pages and styles in the theme folder, and images and scripts in the public folder. Add other folders under components/ as you need them, for example sections/ and overlays/.

There is no manifest file. The Shop Theme record holds the theme's name, parent and settings.

The Shop Theme record

Field What it does
Theme Name The record's name, and the source of the folder name. Letters, digits, spaces, - and _ only.
Module The module whose app holds the theme's files and the record's JSON. Set it before the first save.
Is Standard Ships the record with the app. Commera writes the record's JSON only when this is ticked, and never deletes a standard theme's folders.
Parent Theme The theme that gives every file this theme does not have
Theme Settings A Single DocType with the merchant's settings for this theme. Use Scaffold Theme Settings on a saved record to make one.
Config Not used. Leave it empty.

Commera does not allow a parent chain that loops back to the same theme.

The theme chain

The chain starts at the active theme and follows Parent Theme to the top. For Acme Catalog, the chain is:

  1. Acme Catalog, in the acme_theme app
  2. Summer Theme, in the Commera app
  3. Shop Base Theme, in the Commera app

Each theme in the chain can be in a different app.

Fallback order

What Where Commera looks If no theme has it
A page, such as pages/products/details.html Each theme in the chain, child first Commera's core page serves the URL
A page controller, such as pages/products/details.py Each theme in the chain, child first. The controller and the page can come from different themes. The page renders without a controller
A components/... file that a template extends, includes or imports Each theme in the chain, child first, then Commera's core templates Jinja raises a "template not found" error
Any other template name, such as templates/... Frappe's normal template loader, which searches every installed app. A theme folder cannot override it. A templates/... file in another app replaces Commera's file for every theme on the site, so do not add one. Jinja raises a "template not found" error
An asset, through shop_theme_asset_url() Each theme's public folder in the chain, child first The helper returns the active theme's URL, so the 404 names your theme

A child can override a page's .html and keep its parent's .py, or the reverse. Acme Catalog adds only pages/products/details.py. For that URL, Summer Theme's template renders with Acme Catalog's controller. For every other URL, Summer Theme's page and controller run.

What Shop Base Theme ships

Shop Base Theme has no pages. Activated alone, it changes no URL. It ships:

File What it gives
components/base.html The HTML skeleton: the lang and dir attributes, SEO meta tags and JSON-LD, analytics tags, the favicon, the merchant's --ls-* colours, Alpine.js and its Persist and Collapse plugins, the cart, translation, wishlist and toast stores, the query string helper, and the toast
components/macros/branding.html brand_logo(css_class) and brand_name()
images/placeholder.svg An image for products without one
scripts/vendor/alpinejs/ Alpine.js and its plugins
scripts/synced-query-params.js Keeps page state, such as the page number, in the query string

The base.html blocks are listed in Step 2: Add a layout.

Next steps

Last updated 5 days ago
Was this helpful?
Thanks!