Theme configuration via config.xml
A theme can expose settings the admin tunes per sales channel, without you writing an admin view. Drop a config.xml at the theme root, and the branding screen grows extra tabs with the fields you declared. Templates read those values with theme_config('key', 'default').
The XML schema is the same one modules use, so any config sample from a module works here.
Add a config.xml file
Create config.xml next to composer.json. Group fields inside <tab> elements; each tab becomes a tab on the sales channel's Theme configuration screen.
<?xml version="1.0" encoding="UTF-8"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://raw.githubusercontent.com/shopware/platform/master/src/Core/System/SystemConfig/Schema/config.xsd">
<tab>
<title>Design</title>
<title lang="de">Design</title>
<icon>far fa-palette</icon>
<input-field type="single-select">
<name>variant</name>
<label>Design variant</label>
<label lang="de">Design-Variante</label>
<defaultValue>default</defaultValue>
<options>
<option><id>default</id><name>Standard</name></option>
<option><id>futuristic</id><name>Futuristic</name></option>
</options>
</input-field>
</tab>
</config>Read a value from twig
Use theme_config anywhere the storefront renders. The second argument is the fallback for sales channels that have not saved a value yet.
<body class="design--{{ theme_config('variant', 'default') }}">
...
</body>The function resolves the currently rendering sales channel automatically. Outside a storefront request, for example inside a CLI command or a job, it returns the default.
Where values are stored
Values live on the sales channel row in the theme_configs JSON column, keyed by theme.<name>. Switching a channel from one theme to another never mixes their settings because each theme owns its own key.
// sales_channels.theme_configs
{
"theme.evolution": {
"variant": "futuristic",
"header_show_search": true
}
}Available field types
The most useful fields are text, textarea, number, bool, single-select, multi-select, media and color. Every field needs a <name>, a <label> and usually a <defaultValue>. Copy the shape from any module's config.xml for a working sample of each.
Translations
Every <title>, <label> and <helpText> can be repeated with a lang attribute. The admin sees the label matching their active language, falling back to the version with no lang attribute.
<label>Show search bar</label>
<label lang="de">Suchleiste anzeigen</label>A boolean checkbox is only persisted when it is checked. Read it in twig with theme_config('key') is defined, not == true, unless you gave it a <defaultValue>.