Skip to content

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

text
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 output

Full 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').

json
{
  "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:

json
"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:

text
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:

text
overrides.scss (child)        ← loads first, allows variable overrides

@DmfGuppyTheme                ← entire parent theme

base.scss (child)             ← selector styles, loads last

Config inheritance

text
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:

twig
{# 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:

  • PluginBase class with init(), destroy() lifecycle.
  • Registration with PluginManager plus a selector.
  • Activation via data-* attributes in HTML.

Detail in Storefront JS.

Console commands

DmfGuppyTheme registers its own console commands:

CommandServicePurpose
guppy:theme:createConsole\ThemeCreateCommandCreates a child theme skeleton (custom/static-plugins/<TechnicalName>/).
guppy:install:pluginsConsole\InstallPluginsCommandInstalls recommended plugins via Composer (interactive).
guppy:upgrade:scanCommand\GuppyUpgradeScanCommandAnalyses installed Guppy components against a Shopware version.

Configuration in Resources/config/services/commands.xml and services/console.xml.

Plugin dependencies

PluginDependency
DmfGuppyThemedmf/sw6-plugin-splide-slider
DmfGuppyEmotionworldElementsdmf/sw6-guppy-theme: ^2.0
Slider custom elements from DmfCmsCustomElementsDmfSplideSlider

Full plugin list: Plugins.

Design decisions

DecisionRationale
Bootstrap 5 instead of a custom CSS systemCompatibility with the Shopware default storefront, shared knowledge, utilities.
theme.json as the central configurationCustomisation without code changes, clear parent/child split.
Splide instead of Tiny SliderBetter performance, full keyboard navigation, single source of truth plugin.
Skip links and ARIA defaultsAccessibility as a default, not an add-on.
Staging branch workflowSeparation between QA (stage) and production (main). Major releases use RC tags (2.8.0-rc1) instead of a separate branch.