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