Wie erbt man korrekt von einem anderen Theme?

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);
        }
    }
}