Manual Child Theme Development
This page covers the manual workflow for developers maintaining a child theme as a regular plugin in a repository, without the browser-based Theme Builder.
When manual vs. Theme Builder?
| Need | Recommendation |
|---|---|
| Brand theme with variable / asset adjustments | Theme Builder |
| Custom Twig overrides, custom JS, your own plugins | Manual |
| Complex layouts, custom CMS elements | Manual |
| Version control via git | Manual (or builder + snapshot in repo) |
| Fast iteration without local setup | Theme Builder |
Hybrid path
Use the Theme Builder as a starter, extract the ZIP, drop the contents into your repo, then continue manually. Check the snapshot (.guppy-builder.json) into the repo as well.
Theme skeleton with guppy:theme:create
The fastest path to a child theme you can iterate on manually:
bin/console guppy:theme:createInteractive process. Inputs:
- Namespace (e.g.
Dmf,Acme) - Theme name (e.g.
CustomerShop) - Theme title for the admin
- Brand colors (primary, secondary, border, background)
- Asset filenames (plugin icon, preview, logo, share icon, favicon)
Generated structure:
custom/static-plugins/DmfCustomerShopTheme/
├── composer.json
└── src/
├── DmfCustomerShopTheme.php
└── Resources/
├── app/storefront/
│ ├── src/scss/
│ │ ├── base.scss
│ │ └── overrides.scss
│ └── dist/
│ ├── assets/
│ └── storefront/js/
├── config/plugin.png
├── theme.json
└── views/storefront/Auto-generated:
- complete
composer.jsonwith thedmf/sw6-guppy-themedependency - preconfigured
theme.jsonwith the correct inheritance - PHP plugin class with the correct namespace
- default assets copied
Inheritance in theme.json is hard-wired:
{
"configInheritance": [
"@Storefront",
"@DmfGuppyTheme"
]
}Prepare assets first
Have plugin icon, preview image, logo, share icon, and favicon ready before running the command, the generator copies them into Resources/.
Manual creation (without the generator)
If you don't want to use the generator:
custom/plugins/AcmeChildTheme/
├── composer.json
└── src/
├── AcmeChildTheme.php
└── Resources/
├── theme.json
├── config/plugin.png
└── app/storefront/src/scss/
├── overrides.scss
└── base.scsscomposer.json:
{
"name": "acme/child-theme",
"description": "Acme Child Theme",
"type": "shopware-platform-plugin",
"license": "proprietary",
"require": {
"shopware/core": "~6.7.0",
"dmf/sw6-guppy-theme": "^2.0"
},
"autoload": {
"psr-4": {
"AcmeChildTheme\\": "src/"
}
},
"extra": {
"shopware-plugin-class": "AcmeChildTheme\\AcmeChildTheme",
"label": {
"de-DE": "Acme Child Theme",
"en-GB": "Acme Child Theme"
}
}
}theme.json:
{
"name": "AcmeChildTheme",
"author": "Acme",
"views": ["@Storefront", "@Plugins", "@AcmeChildTheme"],
"style": [
"app/storefront/src/scss/overrides.scss",
"@StorefrontBootstrap",
"@Plugins",
"app/storefront/src/scss/base.scss"
],
"script": [
"@Storefront",
"@Plugins"
],
"asset": ["@Storefront", "@Plugins", "app/storefront/dist/assets"],
"configInheritance": ["@Storefront", "@DmfGuppyTheme"],
"previewMedia": "app/storefront/dist/assets/theme-preview.jpg"
}Install and activate the plugin
bin/console plugin:refresh
bin/console plugin:install --activate AcmeChildTheme
bin/console theme:change # pick the sales channel
bin/console theme:compile
bin/console cache:clearAdjust theme variables
In overrides.scss (loads before Bootstrap):
// Override values from abstract/variables/bootstrap.scss
$body-bg: #f00 !default;
$body-color: #000 !default;
// Guppy-specific variables
$icon-base-size: 16px !default;
$product-image-height: 320px !default;
// Bootstrap variables
$primary: #1A223E !default;
$secondary: #F49927 !default;In base.scss (loads after everything):
// Selector styles
.custom-component {
background-color: $primary;
color: $body-color;
}Order matters
Variable overrides belong in overrides.scss, in base.scss they no longer apply because Bootstrap is already compiled.
Full variable and mixin reference: Variables & Tokens.
Twig overrides
Templates mirror the original path and use sw_extends:
{# src/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-acme">
{{ parent() }}
</div>
{% endblock %}Detail: Twig Overrides.
Iteration
After each change:
bin/console theme:compile
bin/console cache:clearWith the storefront watcher running, Ctrl+S is enough, the watcher rebuilds automatically:
bin/watch-storefront.shInstall plugins
DmfGuppyTheme ships a command that pulls recommended plugins via Composer:
bin/console guppy:install:pluginsMore under Recommended Plugins.
Related
- Theme Builder: alternative or starter.
- Architecture: inheritance order.
- Variables & Tokens: SCSS architecture.
- Twig Overrides: template override patterns.