Architecture
Guppy strictly follows the Shopware 6 plugin and theme architecture. The theme registers as a shopware-platform-plugin, exposes configuration via theme.json, and uses Twig and SCSS overrides for customisation.
Plugin structure
DmfGuppyTheme/
├── composer.json
├── README.md
├── CLAUDE.md
├── easy-coding-standard.php
├── Makefile
├── bin/
└── src/
├── DmfGuppyTheme.php # plugin bootstrap
├── Console/ # custom CLI commands
│ ├── ThemeCreateCommand.php
│ └── InstallPluginsCommand.php
├── Command/ # additional CLI commands
│ └── GuppyUpgradeScanCommand.php
├── Twig/ # custom Twig extensions
│ └── CategoryOneLevelExtension.php
└── Resources/
├── config/
│ ├── plugin.png
│ ├── services.xml
│ └── services/
│ ├── commands.xml
│ ├── console.xml
│ ├── cms.xml
│ └── custom-fields.xml
├── theme.json # theme configuration
├── views/
│ └── storefront/ # Twig overrides
├── snippet/
└── app/
└── storefront/
├── src/
│ ├── main.js # JS entry
│ ├── js/ # storefront plugins
│ └── scss/ # SCSS architecture
└── dist/ # build outputFull SCSS directory structure
Detailed view in Variables & Tokens.
theme.json model
theme.json is the central control surface. Every field is readable from Twig via theme_config('field-name').
{
"name": "DmfGuppyTheme",
"author": "digital.manufaktur GmbH",
"views": ["@Storefront", "@Plugins", "@DmfGuppyTheme"],
"style": [
"app/storefront/src/scss/overrides.scss",
"@StorefrontBootstrap",
"@Plugins",
"app/storefront/src/scss/skin/shopware/base.scss",
"app/storefront/src/scss/base.scss"
],
"script": [
"@Storefront",
"@Plugins",
"app/storefront/dist/storefront/js/dmf-guppy-theme.js"
],
"asset": ["@Storefront", "@Plugins", "app/storefront/dist/assets"],
"configInheritance": ["@Storefront"],
"config": {
"tabs": { },
"blocks": { },
"fields": { }
}
}Tabs, blocks, and fields
theme.json groups configuration hierarchically:
- Tabs: top-level admin tabs (Layout, Header, Footer, Checkout, …).
- Blocks: groups within a tab (themeColors, typography, layoutGeneral, …).
- Fields: individual configuration fields with type, default, options, and localisation.
Example field:
"guppy-footer": {
"label": {
"en-GB": "Footer variant",
"de-DE": "Footer Variante"
},
"type": "text",
"value": "guppy-default",
"custom": {
"componentName": "sw-single-select",
"options": [
{ "value": "default", "label": { "en-GB": "Shopware Default" } },
{ "value": "guppy-default", "label": { "en-GB": "Guppy Default" } }
]
},
"editable": true,
"tab": "footer",
"block": "layoutFooter",
"order": 100
}Inheritance chain
Style inheritance (SCSS)
The style array in theme.json defines the exact compile order:
overrides.scss (loads first, early variable overrides)
↓
@StorefrontBootstrap (Bootstrap)
↓
@Plugins (Guppy and third-party plugins)
↓
skin/shopware/base.scss (Shopware integration)
↓
base.scss (theme styles)Child theme inheritance
A child theme adds layers on top:
overrides.scss (child) ← loads first, allows variable overrides
↓
@DmfGuppyTheme ← entire parent theme
↓
base.scss (child) ← selector styles, loads lastConfig inheritance
configInheritance: ["@Storefront", "@DmfGuppyTheme"]This order is hard-wired in the generated child theme, field defaults come from the parent, values can be overridden in the child admin.
Twig override model
Templates under Resources/views/storefront/... mirror the storefront theme's original layout. An override with sw_extends only changes the necessary blocks:
{# Resources/views/storefront/layout/header/header.html.twig #}
{% sw_extends '@Storefront/storefront/layout/header/header.html.twig' %}
{% block layout_header_logo %}
<div class="header-logo-custom">
{{ parent() }}
</div>
{% endblock %}Detail in Twig Overrides.
Storefront JS model
Storefront plugins follow Shopware's standard pattern:
PluginBaseclass withinit(),destroy()lifecycle.- Registration with
PluginManagerplus a selector. - Activation via
data-*attributes in HTML.
Detail in Storefront JS.
Console commands
DmfGuppyTheme registers its own console commands:
| Command | Service | Purpose |
|---|---|---|
guppy:theme:create | Console\ThemeCreateCommand | Creates a child theme skeleton (custom/static-plugins/<TechnicalName>/). |
guppy:install:plugins | Console\InstallPluginsCommand | Installs recommended plugins via Composer (interactive). |
guppy:upgrade:scan | Command\GuppyUpgradeScanCommand | Analyses installed Guppy components against a Shopware version. |
Configuration in Resources/config/services/commands.xml and services/console.xml.
Plugin dependencies
| Plugin | Dependency |
|---|---|
DmfGuppyTheme | dmf/sw6-plugin-splide-slider |
DmfGuppyEmotionworldElements | dmf/sw6-guppy-theme: ^2.0 |
Slider custom elements from DmfCmsCustomElements | DmfSplideSlider |
Full plugin list: Plugins.
Design decisions
| Decision | Rationale |
|---|---|
| Bootstrap 5 instead of a custom CSS system | Compatibility with the Shopware default storefront, shared knowledge, utilities. |
theme.json as the central configuration | Customisation without code changes, clear parent/child split. |
| Splide instead of Tiny Slider | Better performance, full keyboard navigation, single source of truth plugin. |
| Skip links and ARIA defaults | Accessibility as a default, not an add-on. |
| Staging branch workflow | Separation between QA (stage) and production (main). Major releases use RC tags (2.8.0-rc1) instead of a separate branch. |
Related
- Local Setup: get the plugin running locally.
- Variables & Tokens: full SCSS architecture.
- Twig Overrides: override patterns with
sw_extends. - Plugin Integration: integrate your own plugins into the Guppy theme.