ibexa/standard-design
The Ibexa standard design bundle supplies the default design and theme for Ibexa DXP, managed by ezplatform-design-engine. As part of the Ibexa DXP ecosystem, it provides standard front-end styling and templates for Ibexa-based sites. Install Ibexa DXP to use this package.
This is not a standalone package — it is the default design + theme shipped with Ibexa DXP and is pulled in transitively when you install the DXP. Do not composer require it into a plain Laravel/Symfony app and expect anything to render.
ibexa/standard-design arrives as a dependency of the content/experience layer.composer show ibexa/standard-design
php bin/console debug:config ibexa_design_engine
You should see a design (typically standard) whose themes list includes standard.vendor/ibexa/standard-design/:
templates/themes/standard/ — the full Twig tree: content views (line, card, embed, full), field templates, pagination, content-type-specific overrides.src/ — the bundle class, DI extension, and default design-engine config that registers the design/theme.assets/ (or packaged public/) — compiled CSS/JS and image variations.The fastest orientation exercise: pick any content item, find the full content view template that renders it under the standard theme, duplicate it into templates/themes/<your_theme>/..., register your theme, and verify the override wins.
Never edit vendor. Treat standard-design as a read-only reference implementation. Every customization goes into templates/themes/<your_theme>/ in your project.
Theme stacking (the core pattern). The design engine resolves templates by walking the theme list in order and using the first theme that has a file at that relative path. Register your theme before standard so you only override what you need and inherit everything else:
# config/packages/ibexa_design_engine.yaml
ibexa_design_engine:
design_list:
my_site:
themes: [my_theme, standard]
image_variations: [my_variation, default]
# config/packages/ibexa.yaml
ibexa:
system:
default:
design: my_site
Mirror the path exactly. If the standard theme has templates/themes/standard/content/view/full/foo.html.twig, your override must live at templates/themes/my_theme/content/view/full/foo.html.twig. The path after the theme directory is the lookup key — a typo silently falls back to standard and you will spend an hour wondering why nothing changed.
Surgical overrides via Twig inheritance. Rather than copying an entire 200-line template, extend it and override only the blocks:
{# templates/themes/my_theme/content/view/full/article.html.twig #}
{% extends '@ibexa/standard/content/view/full/article.html.twig' %}
{% block content_title %}
<h1 class="article-title">{{ ez_render_field(content, 'title') }}</h1>
{% endblock %}
Note: if the namespace/path form differs in your DXP version, use the resolved path that debug:twig reports for @ibexa / @ezdesign — this is the piece most likely to have drifted across major versions.
Reuse the view types. standard ships line, card, embed, and full views plus per-content-type variants. When you build a listing page, do not hand-roll markup — render through ibexa_render_content(content, 'line', {...}) so listings inherit your overrides automatically and stay consistent with search and related-content blocks.
Pagination is a template, not a component. Override the pagination template once in your theme and every paginated list picks it up. Pass the paginator through ibexa_render_content-style helpers or your own Twig function rather than duplicating knp_paginator markup in every controller.
Field rendering — prefer ez_render_field(content, 'identifier', {parameters}) over content.getField('identifier').value. The former goes through the design engine and respects your field-template overrides and image variations; the latter bypasses all of it and will bite you when an editor asks for a differently cropped image.
Asset strategy. Decide early whether you are consuming the theme's pre-built assets or compiling your own. If you extend the design:
Keep one encore_entry_link_tags/script_tags call site in your base layout so swapping themes is a one-line change.
Image variations are declared in design config. Add your variations to image_variations in the design block and reference them by name in field parameters; the alias resolution and caching live in the DXP image layer, not this package.
Local/QA sanity loop after any template change:
php bin/console cache:clear
php bin/console lint:twig templates/themes/my_theme
The license is the first thing to check, not the last. Packagist shows NOASSERTION; the README offers a dual choice — Ibexa Business Use License (requires a paid DXP subscription) or GPL-2. Any automated license-compliance scan in CI will flag this package and block merges. Get a written decision from legal/ops before you build a product on it, and record which branch you are relying on. GPL-2 is a real copyleft obligation, not a formality.
Packagist stats are meaningless here. 3 stars and 0 dependents does not mean "abandoned toy" — it is a monorepo split that every Ibexa DXP installation pulls in transitively. Conversely, don't treat it as a stable public API: its templates change between DXP releases.
Version-lock it to your DXP release. This package tracks the DXP version train. A composer update that bumps it independently of ibexa/core will surface as Twig "block does not exist" or macro-signature errors at render time, not at install time. Constrain it in composer.json alongside the rest of the Ibexa packages and upgrade them together.
Silent fallback is the #1 debugging trap. Wrong theme name, wrong relative path, or theme not in the themes list all produce the standard template rendering successfully — no error, no warning. When an override "doesn't work":
php bin/console debug:config ibexa_design_engine — is your design/theme actually registered?php bin/console debug:twig — which physical file does the template name resolve to?themes/<theme>/ matches byte-for-byte, including singular/plural (content/view/full/ vs contents/views/).Theme order is load-bearing. Putting standard before your theme silently disables every override. It looks correct in config and renders perfectly — just never your code.
Cache is aggressive. Design engine resolution and Twig compilation are both cached. In dev you usually get away with it; in a warm prod cache (or behind a shared cache dir in Docker), template edits appear to do nothing. Always rm -rf var/cache/* in containerized setups where the cache volume is shared.
Do not subclass or bundle-inherit to override. Symfony bundle template inheritance (@IbexaStandardDesign/...) bypasses the design engine and breaks the moment the upstream directory layout changes. Themes are the supported extension point; use them.
Copies rot on upgrade. Every file you copy wholesale is a file you must re-diff on the next DXP upgrade. Keep the copy count low: prefer {% extends %} + block overrides, and keep a short changelog of which standard-theme templates you have taken ownership of.
Editor-facing behavior lives in these templates. Content view templates often encode business rules (which fields show in a line view, truncation, fallback when a field is empty). When an editor reports "the teaser looks wrong on the landing page," the answer is usually in a content view template here rather than in PHP.
Multilingual and siteaccess. Templates resolve per design, and a design can be assigned per siteaccess. If you run multiple siteaccesses with different looks, don't branch inside templates on app.request — declare two designs and let the design engine pick.
Extensions are limited by design. There is no plugin API in this package. The extension points are: theme list order, template path overrides, Twig block overrides, design config (image_variations, theme assets), and Twig functions/globals you register yourself. If you find yourself wanting a hook, you want an event listener in the DXP layer, not a change here.
How can I help you explore Laravel packages today?