# Wie erbt man korrekt von einem anderen Theme?

**URL:** <https://forum.shopware.com/t/wie-erbt-man-korrekt-von-einem-anderen-theme/68810>\
**Category:** Themes & Design\
**Created:** [6. August 2020 um 09:35 UTC](https://forum.shopware.com/t/wie-erbt-man-korrekt-von-einem-anderen-theme/68810 "2020-08-06T09:35:28Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![halloei](https://avatars.discourse-cdn.com/v4/letter/h/f04885/32.png) [@halloei](https://forum.shopware.com/u/halloei)\
**Post date:** [6. August 2020 um 09:35 UTC](https://forum.shopware.com/t/wie-erbt-man-korrekt-von-einem-anderen-theme/68810/1 "2020-08-06T09:35:28Z")

</div>

Ich habe das Theme “ExternesTheme” eingestellt. Nun möchte ich nur minimale Änderungen daran vornehmen&nbsp;(ein wenig JavaScript hinzufügen und ein paar View-Blöcke überschreiben) und habe dafür ein eigenes Theme “MeinTheme” erstellt.

Mein theme.js sieht so aus:

```
...
"style": [
    "@Storefront",
    "@ExternesTheme"
],
"script": [
    "@Storefront",
    "@ExternesTheme",
    "app/storefront/dist/storefront/js/mein-theme.js"
],
"asset": [
    "app/storefront/src/assets"
],
"views": [
    "@Storefront",
    "@ExternesTheme",
    "@MeinTheme",
    "@Plugins"
],
...

```

Das Problem ist, dass das Skript von ExternesTheme im Browser doppelt ausgeführt wird. Mit der Meldung “all.js:3 Uncaught Error: Plugin “ExternesThemeFoobarPlugin” is already registered.”. Wenn ich _“@ExternesTheme”,_&nbsp;hingegen aus dem “script”-Array entferne, wird es gar nicht geladen.

**Edit:** Dasselbe gilt übrigens für CSS. Nur hindert das doppelte Laden davon die Seite natürlich nicht am Laden.&nbsp;

Wie erbe ich korrekt von ExternesTheme, um meine Änderungen daran vorzunehmen?

---

<div class="post-metadata">

**Author:** ![FloC3](https://avatars.discourse-cdn.com/v4/letter/f/838e76/32.png) [@FloC3](https://forum.shopware.com/u/FloC3)\
**Post date:** [10. Mai 2021 um 17:08 UTC](https://forum.shopware.com/t/wie-erbt-man-korrekt-von-einem-anderen-theme/68810/2 "2021-05-10T17:08:11Z")

</div>

du hast es immerhin geschafft, das irgendwas vererbt wird.  
Ich schaffs nicht, dass mein Child-Theme irgendwas vom Parent-Theme weiß. Weder CSS noch TWIG-Template…

---

<div class="post-metadata">

**Author:** ![FloC3](https://avatars.discourse-cdn.com/v4/letter/f/838e76/32.png) [@FloC3](https://forum.shopware.com/u/FloC3)\
**Post date:** [11. Mai 2021 um 13:59 UTC](https://forum.shopware.com/t/wie-erbt-man-korrekt-von-einem-anderen-theme/68810/3 "2021-05-11T13:59:13Z")

</div>

ich habe mir jetzt meine eigene Theme-Vererbung gebaut. War mir zu blöd, dass Shopware das nicht vernünftig hinkriegt. Wer Interesse hat: meldet euch

---

<div class="post-metadata">

**Author:** ![trade](https://avatars.discourse-cdn.com/v4/letter/t/5fc32e/32.png) [@trade](https://forum.shopware.com/u/trade)\
**Post date:** [11. Mai 2021 um 19:57 UTC](https://forum.shopware.com/t/wie-erbt-man-korrekt-von-einem-anderen-theme/68810/4 "2021-05-11T19:57:47Z")

</div>

Ich arbeite da auch gerade daran. Bin sehr an deiner Lösung interessiert!

---

<div class="post-metadata">

**Author:** ![FloC3](https://avatars.discourse-cdn.com/v4/letter/f/838e76/32.png) [@FloC3](https://forum.shopware.com/u/FloC3)\
**Post date:** [17. Mai 2021 um 12:34 UTC](https://forum.shopware.com/t/wie-erbt-man-korrekt-von-einem-anderen-theme/68810/5 "2021-05-17T12:34:04Z")

</div>

theme.json des Parent-Themes

```
"views": [
        "@Storefront",
        "@Plugins",
        "@ParentTheme"
      ],
      "style": [
        "app/storefront/src/scss/overrides.scss",
        "@Storefront",
        "@Plugins",
        "app/storefront/src/scss/base.scss"
      ],
      "script": [
        "@Storefront"
      ],
      "asset": [
        "app/storefront/src/assets"
      ],

```

und die theme.json des Child-Themes

```
"views": [
    "@Storefront",
    "@Plugins",
    "@ParentTheme",
    "@ChildTheme"
  ],
  "style": [
    "@ParentTheme",
    "@Plugins",
    "app/storefront/src/scss/base.scss"
  ],
  "script": [
    "@ParentTheme"
  ],

```

Beide Themes werden als Plugin installiert. Die Config wird komplett im Parent gemacht, im Child wird nichts eingestellt. Das Child-Theme wird dem Saleschannel als Theme zugewiesen und aktiviert.

Damit ich die Theme-Variablen aus dem Parent im Template zur Verfügung hab, musste ich die Twig-Funktion theme\_config überschreiben. Im Standard hat Shopware hier nur Zugriff auf Daten des aktiven Themes (also das Child, was ja keine Config hat).

habe die Datei 1:1 aus dem Core in mein Parent-Theme kopiert und dann diese beiden Funktionen angepasst

> Storefront\Framework\Twig\Extension\ConfigExtension.php

```
public function getFunctions(): array
    {
        return [
            new TwigFunction('theme_config', [$this, 'theme'], ['needs_context' => true])
        ];
    }

public function theme(array $context, string $key)
    {
        $valueFromActiveTheme = $this->config->theme($key, $this->getContext($context), $this->getThemeId($context));
        $valueFromBaseTheme = $this->config->theme($key, $this->getContext($context), ID_OF_PARENT_THEME);

        if ($valueFromActiveTheme != null && $valueFromActiveTheme != "")
            return $valueFromActiveTheme;
        else
            return $valueFromBaseTheme;
    }

```

zum Schluss musste ich noch die Variablen aus dem Parent-Theme als SCSS-Variablen im Child zur Verfügung stellen. Dazu gibts im Child-Theme einen Subscriber

```
class ThemeVariableSubscriber implements EventSubscriberInterface
{
    /**
     * @var SystemConfigService
     */
    private SystemConfigService $systemConfig;

    /**
     * @var EntityRepositoryInterface
     */
    private EntityRepositoryInterface $themeRepository;

    /**
     * ThemeVariableSubscriber constructor.
     * @param SystemConfigService $systemConfig
     * @param EntityRepositoryInterface $themeRepository
     */
    public function __construct(SystemConfigService $systemConfig, EntityRepositoryInterface $themeRepository)
    {
        $this->systemConfig = $systemConfig;
        $this->themeRepository = $themeRepository;
    }

    /**
     * @return string[]
     */
    public static function getSubscribedEvents(): array
    {
        return [
            ThemeCompilerEnrichScssVariablesEvent::class => 'onAddVariables'
        ];
    }

    /**
     * @param ThemeCompilerEnrichScssVariablesEvent $event
     */
    public function onAddVariables(ThemeCompilerEnrichScssVariablesEvent $event)
    {
        // add theme config variables from parent theme for correct inheritance

        $criteria = new Criteria();
        $criteria->addFilter(new EqualsFilter('technicalName', "ParentTheme"));

        $themeConfig = [];

        /** @var ThemeEntity $theme */
        foreach ($this->themeRepository->search($criteria, Context::createDefaultContext())->getElements() as $theme)
        {
            foreach ($theme->getBaseConfig()["fields"] as $configKey => $baseConfigEntry)
            {
                $themeConfig[$configKey] = $baseConfigEntry["value"];
            }

            foreach ($theme->getConfigValues() as $configKey => $configValue)
            {
                if ($configValue["value"] == null)
                    continue;

                $themeConfig[$configKey] = $configValue["value"];
            }
        }

        foreach($themeConfig as $key => $value)
        {
            if ($value == null)
                $event->addVariable($key, $value, true);
            else
                $event->addVariable($key, $value, false);
        }
    }
}

```
