Skip to content

Plugin Integration

This page covers how to develop Shopware plugins that play nicely with the Guppy theme, without breaking the inheritance chain or blocking future theme updates.

Golden rules

RuleWhy
Never patch DmfGuppyTheme directlyUpdates become impossible. Custom code belongs in your own plugin or child theme.
Always override Twig with sw_extendssw_replace breaks the inheritance chain for subsequent plugins.
SCSS via overrides.scss and base.scssReaching into Bootstrap's build directly is fragile.
Mark variables !defaultSo child themes can keep overriding.
Don't change theme.json inheritance["@Storefront", "@DmfGuppyTheme"] is a fixed order.

Composer setup

Package your plugin as a regular shopware-platform-plugin:

json
{
  "name": "acme/guppy-extension",
  "type": "shopware-platform-plugin",
  "license": "proprietary",
  "require": {
    "shopware/core": "~6.7.0",
    "dmf/sw6-guppy-theme": "^2.0"
  },
  "autoload": {
    "psr-4": {
      "Acme\\GuppyExtension\\": "src/"
    }
  },
  "extra": {
    "shopware-plugin-class": "Acme\\GuppyExtension\\AcmeGuppyExtension"
  }
}

Local path repo

For monorepo development, mount the plugin via a Composer path repository, see Local Setup.

SCSS integration

Theme-pipeline styles

Plugins marked as shopware-storefront-plugin and added via the theme's @Plugins slot are picked up automatically by the compile order:

text
overrides.scss

@StorefrontBootstrap

@Plugins   ← your plugin CSS lands here

skin/shopware/base.scss

base.scss

Plugin layout:

text
src/Resources/app/storefront/src/scss/
└── base.scss        # single entry point, picked up by the theme compiler

base.scss:

scss
.acme-component {
    background-color: $sw-color-gray-100;
    border-radius: $border-radius;
    padding: $spacer;

    @include media-breakpoint-up(md) {
        padding: $spacer * 2;
    }

    &:focus-visible {
        @include focus-style;
    }
}

Bootstrap variables only available from base.scss

A plugin can't set variables before Bootstrap (no overrides.scss hook). If you need to override variables, do it from a child theme, see Manual Child Theme Development.

Use the theme's mixins and functions

Plugins can use the theme's mixins without explicit imports, theme:compile resolves them from the Guppy theme:

scss
@include focus-style;
@include line-height(1.4);
@include button-adaptive-hover($primary);

Full list: Variables & Tokens.

Twig integration

Override templates

Plugin templates live under:

text
src/Resources/views/storefront/...

Example: a custom block in the header logo component:

twig
{# src/Resources/views/storefront/layout/header/logo.html.twig #}
{% sw_extends '@Storefront/storefront/layout/header/logo.html.twig' %}

{% block layout_header_logo %}
    {{ parent() }}
    <span class="acme-logo-suffix">Powered by Acme</span>
{% endblock %}

sw_extends not sw_replace

sw_replace breaks the inheritance chain for subsequent plugins. Always use sw_extends.

Theme config in plugin templates

Plugins can read theme_config() regardless of whether the field is defined by the Guppy theme or another plugin:

twig
{% if theme_config('guppy-header') == 'extended' %}
    {# Acme-specific behaviour for the extended header #}
{% endif %}

Register a custom Twig extension

php
// src/Twig/AcmeExtension.php
namespace Acme\GuppyExtension\Twig;

use Twig\Extension\AbstractExtension;
use Twig\TwigFunction;

class AcmeExtension extends AbstractExtension
{
    public function getFunctions(): array
    {
        return [
            new TwigFunction('acmeFormat', [$this, 'acmeFormat']),
        ];
    }

    public function acmeFormat(string $value): string
    {
        return strtoupper($value);
    }
}
xml
<!-- src/Resources/config/services.xml -->
<service id="Acme\GuppyExtension\Twig\AcmeExtension">
    <tag name="twig.extension"/>
</service>

Storefront JS integration

Write your own plugin as a regular Shopware storefront plugin, pattern and examples in Storefront JS.

Build on Splide slider

Instead of writing your own slider, consume DmfSplideSlider:

html
<div class="splide" data-splide-slider-plugin="true">
    <div class="splide__track">
        <ul class="splide__list">
            {# Slides #}
        </ul>
    </div>
</div>

Detail: DmfSplideSlider.

CMS integration

Register your own blocks and elements: see Custom CMS Blocks.

Block reuse (linked blocks, JSON import/export): DmfCmsBlockLibrary.

Asset pipeline

Plugin assets belong under src/Resources/app/storefront/dist/assets/ and are served by the theme compiler. Paths in SCSS / Twig:

scss
background-image: url("#{$app-css-relative-asset-path}/acme/banner.png");
twig
<img src="{{ asset('bundles/acmeguppyextension/assets/acme/banner.png') }}" alt="">

Migrations and custom fields

Custom migrations live under src/Migration/. Custom field definitions via services/custom-fields.xml, analogous to DmfGuppyTheme's custom field setup.

Version compatibility

Required constraint in the plugin:

json
"require": {
  "dmf/sw6-guppy-theme": "^2.0"
}

^2.0 allows MINOR and PATCH theme updates while blocking MAJOR ones (see Changelog).

Validation

Before release, check:

CheckCommand
Plugin loadsbin/console plugin:list | grep AcmeGuppyExtension
Theme compiles cleanlybin/console theme:compile
Storefront renders without JS errorsInspect browser console
Lintermake lint (if available)
Upgrade scan compatiblebin/console guppy:upgrade:scan