---
title: "Templates"
space: "Commera"
url: "https://docs.bwh.tech/commera/theme-reference/templates"
updated: "2026-10-08"
---

Theme templates are Jinja. This page lists the context that every themed page gets, the Jinja helpers that Commera adds, and how to render a themed template from Python.

## Page context

Commera builds the context in this order. A later step can replace a value from an earlier step.

1. `is_rtl`: true when the page language is right-to-left (Arabic).
2. The named groups of the matched route, such as `lang` and `route`. Commera also puts them in `frappe.form_dict`.
3. The Website Settings context from Frappe, including `boot`.
4. `app_name` and `app_logo`, from **Website Settings**. `app_name` is "Commera" when it is not set.
5. The values from every app's `update_website_context` hook.
6. The page controller, `pages/<page>.py`, if one exists in the theme chain.

Frappe's usual Jinja globals also work, such as `frappe`, `_()` and `json`. Use `frappe.lang` for the page language.

### Variables that change the page head

| Variable | Set it to | Effect |
| --- | --- | --- |
| `seo` | A dict of page meta data | `base.html` prints these meta tags instead of the default ones |
| `json_ld` | A list of structured data objects | `base.html` prints these instead of the organisation data |

Commera's core controllers set both. When your controller calls a core controller, as Acme's pages do, the page gets them.

## Jinja helpers

Commera adds these methods to every template.

| Helper | Returns | Use it to |
| --- | --- | --- |
| `shop_theme_asset_url(path)` | `str` | Get the URL of a file in the theme chain's public folders. `path` is relative to `public/themes/<folder>/`, such as `css/acme.css`. |
| `shop_theme_config()` | The settings document, or an empty dict | Read the active theme's **Theme Settings** |
| `format_theme_css()` | `str` | Print the merchant's `--ls-*` colours. `base.html` already calls it. |
| `get_currency_symbol()` | `str` | Get the store currency's symbol. For SAR it returns an HTML `<span>`. |
| `get_brand_assets()` | A dict with `logo`, `footer_logo` and `favicon` | Get the store's brand images. Each falls back to a bundled default. |
| `get_header_data()` | A dict, with `navigation_menu` | Build the header navigation |
| `get_storefront_menu()` | The enabled menu items, as a tree | Build a menu from the merchant's navigation settings |
| `get_search_result_fields()` | A list of field names | Find which fields the merchant shows on a search result card |
| `is_guest_checkout_enabled()` | `bool` | Show or hide guest checkout |
| `seo_page_meta()` | A dict | Get the default page meta data |
| `seo_org_jsonld()` | A list | Get the default organisation structured data |

Commera also adds the filter `can_return`, for the account order pages.

Shop Base Theme adds two macros in `components/macros/branding.html`:

| Macro | Prints |
| --- | --- |
| `brand_logo(css_class="h-10 w-auto object-contain")` | The store logo as an `<img>`, or the store name in a `<span>` when no logo is set |
| `brand_name()` | The store name, from `app_name` |

Import them `with context`. See [Step 2: Add a layout](/commera/build-a-theme/add-a-layout).

## Theme settings

A theme can have its own settings, which the merchant edits: hero slides, banners or a tagline. Store them in a Single DocType, and link it in the theme's **Theme Settings** field.

1. Open the saved Shop Theme record in developer mode.
2. Click **Scaffold Theme Settings**. Commera makes a Single DocType for the theme, in the theme's module.
3. Add your fields to the new DocType.
4. Read them in a template:

    ```jinja
    {% set settings = shop_theme_config() %}
    {% if settings.tagline %}<p>{{ settings.tagline }}</p>{% endif %}
    ```

`shop_theme_config()` returns the **active** theme's settings, and not the parent's. With no **Theme Settings**, it returns an empty dict. A child of a theme that reads its settings must link the same settings, or its own copy of them. See [Step 5: Override a theme](/commera/build-a-theme/override-a-theme).

:::caution[Read fields only]

In a template, `shop_theme_config()` gives the fields of the settings document. Its methods are not available: a method call returns nothing. Get computed values in the page controller instead.

:::

The /commera dashboard's **Theme** screen shows the live theme's settings, so the merchant can edit them there.

## Render a themed template from Python

To render a template through the theme chain outside a page request, for example in an email or a background job, use `render_themed_template`. In this example, `new_arrivals_email.html` is a file that you add to your theme:

```python
from commera.shop_themes.render import render_themed_template

html = render_themed_template(
	"components/includes/new_arrivals_email.html",
	context={"products": products},
	theme_name="Acme",
)
```

| Argument | What it is |
| --- | --- |
| `template` | A template path, such as `components/...`, or a template string |
| `context` | The context dict. Commera does not add the page context. |
| `theme_name` | The theme whose templates and includes to use. When empty, the active theme. It ignores `preview_theme`. |

When no theme applies, it renders the template with Frappe's normal renderer.

`shop_theme_asset_url()` and `shop_theme_config()` do not use `theme_name`. They always use the active theme. Give a `theme_name` other than the active theme only when the template uses neither helper.

`commera.shop_themes.render` is Commera's own code, not a fixed API. Check your calls after each Commera update.

## Next steps

- [Architecture](/commera/theme-reference/architecture): how Commera finds each template
- [Routes and pages](/commera/theme-reference/routes-and-pages)
- [Gotchas](/commera/theme-reference/gotchas)
