enhavo/theme-bundle
Theme bundle for the Enhavo CMS, an open source PHP content management system built on the Symfony fullstack framework with Sylius components. Provides theming support for flexible, complex data structures. This is a subtree split of the main Enhavo repository.
enhavo/theme-bundle is the theme layer of the Enhavo CMS: it decides which frontend theme is active and makes that theme’s templates/assets available to Twig. It is a read-only subtree split of the main enhavo/enhavo repository, so treat it as an internal Enhavo component rather than a standalone library.
Minimal setup:
composer require enhavo/theme-bundle
Register the bundle if your Enhavo skeleton does not already do so:
// config/bundles.php
return [
// ...
Enhavo\Bundle\ThemeBundle\EnhavoThemeBundle::class => ['all' => true],
];
Create the bundle configuration. The configuration tree is the source of truth for exact keys, so inspect DependencyInjection/Configuration.php in the package first; a typical setup looks like:
# config/packages/enhavo_theme.yaml
enhavo_theme:
theme: default
Then create a theme template directory, e.g. templates/themes/default/, and render a theme template from a controller:
return $this->render('@theme/index.html.twig');
Where to look first:
DependencyInjection/Configuration.php — the exact YAML keys and defaults.Theme/ or Resolver/ — the service that determines the active theme.Resources/ / templates/ — how template paths are registered.First useful use case: replacing the frontend layout of an existing Enhavo installation with a project-specific theme without touching vendor templates.
Declare one theme per environment, override per deployment. Keep the theme name in bundle config and vary it by environment (config/packages/dev/enhavo_theme.yaml, config/packages/prod/enhavo_theme.yaml). This makes it easy to run a “design” theme in staging and the production theme in prod.
Resolve the active theme in application code. Inject the bundle’s theme resolver/manager rather than hard-coding a template path. Use bin/console debug:container to find the exact service id, then:
public function __construct(private ThemeResolverInterface $themeResolver) {}
public function index(): Response
{
$theme = $this->themeResolver->getTheme();
return $this->render(sprintf('@theme/%s/index.html.twig', $theme->getName()));
}
Use theme templates as an override layer, not a fork. Put the theme’s templates in a dedicated directory and let Twig’s loader fall back to the base Enhavo templates. Override only the templates you actually need; this keeps upgrades of the main Enhavo repository manageable.
Drive assets per theme. If you use Webpack Encore, build one entry per theme (theme_default, theme_shop, etc.) and select the correct entry in the base layout based on the active theme. Do not assume the bundle compiles assets for you.
Theme-aware admin content. When Enhavo blocks/pages reference templates, resolve the template name through the theme layer so the same content renders correctly after a theme switch. Centralize this in a Twig extension or a small renderer service rather than scattering conditionals through templates.
Testing pattern. In functional tests, set the theme config explicitly for the test kernel and assert that the rendered response contains a theme-specific marker:
self::assertStringContainsString('data-theme="default"', $client->getResponse()->getContent());
Clear the cache between theme-switching tests; Twig caches resolved template paths.
enhavo/enhavo repository.enhavo/theme-bundle on the same release line as the rest of Enhavo and your Symfony version; mixed versions are the most common source of container/config errors.Configuration.php and the bundle’s tests before guessing YAML keys. Symfony will fail fast on unknown keys, but the error can be cryptic.dev, changing the active theme should invalidate the cache; in other environments run bin/console cache:clear after changing theme config.bin/console debug:twig. If a theme template is not found, verify the theme directory was actually registered as a Twig path and check the namespace/prefix used by the bundle.vendor/enhavo/theme-bundle. Changes are lost on composer update; use bundle overrides, service decoration, or a small in-project bundle instead.How can I help you explore Laravel packages today?