Ibexa DXP comes with a native controller to display your content, known as the
ViewController. It is called each time you try to reach a Content item from its URL alias (human-readable, translatable URI generated for any content based on URL patterns defined per Content Type). It is able to render any content created in the admin interface or via the Public API Guide.
It can also be called straight by its direct URI:
A Content item can also have different view types (full page, abstract in a list, block in a Page, etc.). By default the view type is full (for full page), but it can be anything (line, block, etc.).
Configuring views: the ViewProvider¶
The ViewProvider allows you to configure template selection when using the
ViewController, either directly from a URL or via a sub-request.
The ViewProvider takes its configuration from your SiteAccess in the
content_view section. This configuration is necessary for views to be defined and is a hash built in the following way:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
Template matching and non-existent Field Types
Template matching will NOT work if your content contains a Field Type that is not supported by the repository. It can happen when you are in the process of migrating from eZ Publish 4.x, where custom datatypes have been developed.
In this case the repository will throw an exception, which is caught in the
ViewController, and if you are using Legacy Bridge it will end up doing a fallback to legacy kernel.
The list of Field Types supported out of the box is available here.
You can define your template selection rules, alongside other settings, in a different bundle. For details, see Importing configuration from a bundle.
To be able to select the right templates for the right conditions, the view provider uses matcher objects which implement the
The matcher identifier can comply to 3 different formats:
- Relative qualified class name (e.g.
Identifier\ContentType). This is the most common case, it is used for native matchers. It is relative to
- Full qualified class name (e.g.
\Foo\Bar\MyMatcher). This is a way to specify a custom matcher that doesn't need specific dependency injection. Note that it must start with a backslash (
- Service identifier, as defined in Symfony service container. This is the way to specify a more complex custom matcher that has dependencies.
Injecting the Repository
If your matcher needs the repository, make it implement
eZ\Publish\Core\MVC\RepositoryAwareInterface or extend the
eZ\Publish\Core\MVC\RepositoryAware abstract class. The repository will then be correctly injected before matching.
The value associated with the matcher is passed to its
setMatchingConfig() method. The value can be anything that is supported by the matcher.
Native matchers support both scalar values or arrays of scalar values. Passing an array amounts to applying a logical OR.
It is possible to combine multiple matchers:
1 2 3 4
The example above can be translated as "Match any content whose ContentType identifier is
folder , AND having
frontpage as ParentContentType identifier".
The following table presents all native matchers.
||Matches the ID number of the Content item.|
||Matches the ID number of the Content Type that the Content item is an instance of.|
||Matches the ID number of the group containing the Content Type that the Content item is an instance of.|
||Matches the ID number of a Location. In the case of a Content item, matched against the main location.|
||Matches the Remote ID number of a Location. In the case of a Content item, matches against the main Location.|
||Matches the ID number of the parent Content Type. In the case of a Content item, matched against the main location.|
||Matches the ID number of the parent Location. In the case of a Content item, matched against the main location.|
||Matches the remoteId of either Content or Location, depending on the object matched.|
||Matches the ID number of the Section that the Content item belongs to.|
||Matches the identifier of the Content Type that the Content item is an instance of.|
||Matches the identifier of the parent Content Type. In the case of a Content item, matched against the main Location.|
||Matches the identifier of the Section that the Content item belongs to.|
||Matches the depth of the Location. The depth of a top level Location is 1.|
||Matches the virtual URL of the Location (i.e.
Beside the built-in matchers, you can also use your own services to match views:
1 2 3 4 5 6 7 8 9
The service must be tagged with
and must implement
Content view templates¶
Every content view offers a set of variables you can use in templates and controllers.
You can view the whole list of variables by using the
dump() Twig function in your template.
You can also dump a specific variable, for example
Main content-related variables include:
||eZ\Publish\Core\Repository\Values\Content\Content||The Content item, containing all Fields and version information (VersionInfo)|
||eZ\Publish\Core\Repository\Values\Content\Location||The Location object. Contains meta information on the Content (ContentInfo) (only when accessing a Location)|
||Boolean||If true, indicates if the Content item/Location is to be displayed without any pagelayout (i.e. AJAX, sub-requests, etc.). It's generally
||String||The base layout template to use when the view is requested to be generated outside of the pagelayout (when
dump() function also displays other variables, such as specific configuration including the SiteAccess
Template inheritance and sub-requests¶
Like any template, a content view template can use template inheritance. However keep in mind that your Content may be also requested via sub-requests (see below how to render embedded Content items), in which case you probably don't want the global layout to be used.
If you use different templates for embedded content views, this should not be a problem. If you'd rather use the same template, you can use an extra
no_layout view parameter for the sub-request, and conditionally extend an empty pagelayout:
1 2 3 4 5
Default view templates¶
Content view uses default templates to render content unless custom view rules are used.
Those templates can be customized by means of container- and SiteAccess-aware parameters.
Overriding the default template for common view types¶
Templates for the most common view types (content/full, line, embed, or block) can be customized by setting one the
Add this configuration to
config/packages/ezplatform_admin_ui.yaml to use
templates/content/view/full.html.twig as the default template when viewing content with the
full view type:
Alternatively, you can do it using the design engine. For example, if your theme is
themes/site/default/content/<viewType>.html.twig to override the core template.
Customizing the default controller¶
The controller used to render content by default can also be changed. The
ezsettings.default.content_view_defaults container parameter contains a hash that defines how content is rendered by default. It contains a set of content view rules for the common view types. This hash can be redefined to whatever suits your requirements, including custom controllers, or even matchers.
ViewProvider selects the right template (view type, correct parameters, etc.) for displaying a given Content item based on the configuration.
The ViewProviders are objects implementing the
By default, the Configured ViewProvider is used. It selects templates using the view configuration.
When to develop a custom
- You want a custom template selection based on a very specific state of your application
- You depend on external resources for view selection
- You want to override the default one view provider (based on configuration)
ViewProvider objects need to be properly registered in the service container with the
ezpublish.view_provider service tag.
1 2 3 4
type should point to a class implementing the
View\View interface. It determines which type of View will be handled by the
ViewProvider. Out of the box it's
priority is an integer giving the priority to the
ViewProvider. The priority range is from -255 to 255.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
This section presents the events that are triggered by Ibexa DXP.
|Event name||Triggered when...||Usage|
||After the SiteAccess matching has occurred.||Gives further control on the matched SiteAccess. The event listener method receives an
||Right before a view is rendered for a Content item, via the content view controller.||This event is triggered by the view manager and allows you to inject additional parameters to the content view template. The event listener method receives an
||The API throws an exception that could not be caught internally (missing field type, internal error...).||This event allows further programmatic handling (like rendering a custom view) for the exception thrown. The event listener method receives an
Ibexa DXP comes with a Twig helper as a global variable named
This helper is accessible from all Twig templates and allows you to easily retrieve useful information.
||Returns the current SiteAccess.|
||Returns the root Location object.|
||Returns the requested URI string (also known as semanticPathInfo).|
||Returns the "system" URI string. System URI is the URI for internal content controller. If current route is not a URL alias, then the current Pathinfo is returned.|
||Returns the view parameters as a hash.|
||Returns the view parameters as a string.|
||Returns the translation SiteAccess for a given language, or null if it cannot be found.|
||Returns the list of available languages.|
||Returns the config resolver.|