ezsystems/ezplatform-design-engine
Design engine for eZ Platform / Ibexa that manages themes and templates, enabling flexible look & feel customization across sites. Provides tools for organizing design assets, resolving template fallbacks, and supporting multi-site branding.
Installation
composer require ezsystems/ezplatform-design-engine
Ensure your project extends EzSystems\DesignEngineBundle\EzSystemsDesignEngineBundle in config/bundles.php.
Basic Configuration
Add the bundle to config/packages/ezplatform_design_engine.yaml:
ezplatform_design_engine:
design_engine:
enabled: true
default_design: "default"
First Use Case: Rendering a Page
Inject the DesignEngine service and use it in a controller:
use EzSystems\DesignEngineBundle\Service\DesignEngine;
public function renderPage(DesignEngine $designEngine, string $contentId)
{
$content = $this->contentService->loadContent($contentId);
$renderedContent = $designEngine->renderContent($content);
return new Response($renderedContent);
}
Key Files to Review
config/packages/ezplatform_design_engine.yaml (core config)src/EzSystems/DesignEngineBundle/Resources/config/services.yaml (service definitions)src/EzSystems/DesignEngineBundle/Service/DesignEngine.php (main service class)Use the DesignEngine service to render content with custom designs:
$designEngine->renderContent($content, 'custom_design_name');
Content object and an optional design name. The engine resolves the design and renders the content accordingly.Extend or register new designs via YAML or PHP:
# config/packages/ezplatform_design_engine.yaml
ezplatform_design_engine:
designs:
custom_design:
template: "@MyBundle/designs/custom.html.twig"
content_types: ["article", "blog_post"]
@Bundle/designs/ for template paths.Access the DesignEngine in Twig templates:
{{ render(content, 'design_name') }}
render Twig function (auto-registered) to render content with a specific design.Listen to DesignEngineEvents to modify rendering:
use EzSystems\DesignEngineBundle\Event\DesignEngineEvent;
// In a service:
public function onDesignRender(DesignEngineEvent $event)
{
$event->getContent()->setField('custom_field', 'value');
}
design.engine.render or design.engine.post_render events.Map designs to content types in config:
ezplatform_design_engine:
designs:
article_design:
template: "@MyBundle/designs/article.html.twig"
content_types: ["article"]
content_types to restrict designs to specific content types.use EzSystems\DesignEngineBundle\Service\DesignEngine;
use Symfony\Component\HttpFoundation\Response;
public function show(DesignEngine $designEngine, Content $content)
{
$html = $designEngine->renderContent($content, 'mobile_design');
return new Response($html);
}
Override serialization for dynamic rendering:
use EzSystems\DesignEngineBundle\Service\DesignEngine;
use ApiPlatform\Core\Serializer\SerializerContextBuilderInterface;
public function __serialize(DesignEngine $designEngine, SerializerContextBuilderInterface $contextBuilder)
{
$context = $contextBuilder->createArrayContext([]);
return [
'html' => $designEngine->renderContent($this, 'api_design'),
'data' => $this,
];
}
Extend the Content class to add design-specific fields:
use EzSystems\DesignEngineBundle\Api\DesignAwareInterface;
class CustomContent implements DesignAwareInterface
{
public function getDesign(): ?string
{
return $this->designField->value;
}
}
design field (if DesignAwareInterface is implemented).DesignAwareInterface if relying on field-based designs.Resources/views/ or Resources/templates/.@MyBundle/designs/custom.html.twig are resolved relative to the bundle’s Resources/ directory.@MyBundle/designs/custom.html.twig) or configure custom template locations.php bin/console cache:clear
ezplatform_design_engine:
design_engine:
cache_enabled: false
DesignEngine warnings.design.engine.render fire before template rendering.design.engine.post_render for post-processing (e.g., modifying HTML).Add a subscriber to log design resolution:
use EzSystems\DesignEngineBundle\Event\DesignEngineEvent;
public function onDesignResolve(DesignEngineEvent $event)
{
$this->logger->debug(
'Resolved design',
['content_id' => $event->getContent()->id, 'design' => $event->getDesign()]
);
}
php bin/console debug:container ezplatform_design_engine.templating.loader
{{ dump(_self) }} in Twig to inspect the template context.php bin/console debug:content-types
php bin/console ezplatform:content-type:rebuild
Extend EzSystems\DesignEngineBundle\Resolver\DesignResolverInterface to add logic:
use EzSystems\DesignEngineBundle\Resolver\DesignResolverInterface;
class CustomDesignResolver implements DesignResolverInterface
{
public function resolve(Content $content): ?string
{
return $content->getField('custom_design_field')->value;
}
}
Register it in services.yaml:
services:
App\DesignResolver\CustomDesignResolver:
tags:
- { name: ezplatform_design_engine.design_resolver }
Override the template loader for custom sources (e.g., database):
use EzSystems\DesignEngineBundle\Templating\Loader\DesignTemplateLoaderInterface;
class DatabaseTemplateLoader implements DesignTemplateLoaderInterface
{
public function getSource(string $name): string
{
return $this->database->fetchTemplate($name);
}
}
Register it as the primary loader in config:
ezplatform_design_engine:
design_engine:
template_loader: App\DesignResolver\DatabaseTemplateLoader
Use design.engine.post_render to modify HTML:
use EzSystems\DesignEngineBundle\Event\DesignEngineEvent;
public function onPostRender(DesignEngineEvent $event)
{
$html = $event->getHtml();
$event->setHtml(str_replace('old-text', 'new-text', $html));
}
Use a resolver to apply designs based on conditions (e.g., user roles):
public function resolve(Content $content): ?string
{
if ($this->security->isGranted('ROLE_ADMIN')) {
return 'admin_design';
}
return null;
}
How can I help you explore Laravel packages today?