Before Ibexa 3, a great way to inject variables into content view templates was to use eZCoreExtraBundle ParameterProvider. Now, with Ibexa 3, there is a way to do the same without the need for a third party bundle.
As an example, let's write a VariableProvider that loads all contents from one relation list field of our viewed content. (example code for PHP 7.4+)
<?php
declare(strict_types=1);
namespace App\Provider;
use ArrayObject;
use eZ\Publish\API\Repository\ContentService;
use eZ\Publish\Core\FieldType\RelationList;
use eZ\Publish\Core\MVC\Symfony\View\ContentView;
use eZ\Publish\Core\MVC\Symfony\View\View;
use eZ\Publish\SPI\MVC\View\VariableProvider;
class RelatedVariableProvider implements VariableProvider
{
private ContentService $contentService;
public function __construct(ContentService $contentService)
{
$this->contentService = $contentService;
}
public function getIdentifier(): string
{
// Will be used in config
return 'related';
}
public function getTwigVariables(View $view, array $options = []): object
{
/** @var ContentView $view */
$content = $view->getContent();
/** @var RelationList\Value $value */
$value = $content->getFieldValue('media');
// Return value is typed object, so we simple use ArrayObject
return new ArrayObject(array_map(
fn (int $contentId) => $this->contentService->loadContent($contentId),
$value->destinationContentIds
));
}
}
Now, let's add it in our view configuration:
ezplatform:
system:
default:
content_view:
full:
article:
template: "@ezdesign/content/full/article.html.twig"
match:
Identifier\ContentType: article
params:
# Calling the VariableProvider is done by the ExpressionLanguage
medias: '@=twig_variable_provider("related")'
Ok, but what if I want to choose the field identifier? Sadly, unlike ParameterProvider, it's not possible to pass options directly (twig_variable_provider accepts only one argument: the provider identifier). But, since the VariableProvider is called through the ExpressionLanguage, we can call a method on the VariableProvider return value, with any argument we want.
Let's change our VariableProvider a bit:
<?php
declare(strict_types=1);
namespace App\Provider;
use eZ\Publish\API\Repository\ContentService;
use eZ\Publish\Core\FieldType\RelationList;
use eZ\Publish\Core\MVC\Symfony\View\ContentView;
use eZ\Publish\Core\MVC\Symfony\View\View;
use eZ\Publish\SPI\MVC\View\VariableProvider;
class RelatedVariableProvider implements VariableProvider
{
private ContentService $contentService;
public function __construct(ContentService $contentService)
{
$this->contentService = $contentService;
}
public function getIdentifier(): string
{
return 'related';
}
public function getTwigVariables(View $view, array $options = []): object
{
return $this;
}
public function load(View $view, string $fieldIdentifier): array
{
/** @var ContentView $view */
$content = $view->getContent();
/** @var RelationList\Value $value */
$value = $content->getFieldValue($fieldIdentifier);
return array_map(
fn(int $contentId) => $this->contentService->loadContent($contentId),
$value->destinationContentIds
);
}
}
The getTwigVariables method will simply return the provider itself, so we can call any method on it in the expression.
Let's change our view configuration accordingly:
ezplatform:
system:
default:
content_view:
full:
article:
template: "@ezdesign/content/full/article.html.twig"
match: Identifier\ContentType: article
params:
# Calling the VariableProvider is done by the ExpressionLanguage
medias: '@=twig_variable_provider("related").load(view, "media")'
Let's see what our example would look like as a ParameterProvider, and list the differences:
<?php
declare(strict_types=1);
namespace App\Provider;
use eZ\Publish\API\Repository\ContentService;
use eZ\Publish\Core\FieldType\RelationList;
use eZ\Publish\Core\MVC\Symfony\View\ContentView;
use Lolautruche\EzCoreExtraBundle\View\ConfigurableView;
use Lolautruche\EzCoreExtraBundle\View\ViewParameterProviderInterface;
class RelatedParameterProvider implements ViewParameterProviderInterface
{
private ContentService $contentService;
public function __construct(ContentService $contentService)
{
$this->contentService = $contentService;
}
public function getViewParameters(ConfigurableView $view, array $options = [])
{
/** @var ContentView $view */
$content = $view->getContent();
/** @var RelationList\Value $value */
$value = $content->getFieldValue($options['field_identifier']);
return array_map(
fn(int $contentId) => $this->contentService->loadContent($contentId),
$value->destinationContentIds
);
}
}
The view configuration:
ezplatform:
system:
default:
content_view:
full:
article:
template: "@ezdesign/content/full/article.html.twig"
match: Identifier\ContentType: article
params:
medias:
provider: related
options:
field_identifier: media
And the service configuration (assuming autowiring and autoconfiguration are enabled):
services:
App\Provider\RelatedParameterProvider:
tags:
- { name: "ez_core_extra.view_parameter_provider", alias: "related" }
To migrate that ParameterProvider:
To celebrate the release of Dataflow 5 for Symfony 7, here is some feedback on ...
🎯 Nous relevons le défi de lancer un grand concours : Vous faire gagner un ...
How to dynamically calculate shipping costs? The official documentation that explains how to create shipping ...
How to create a new product attribute type in Ibexa Commerce
A la recherche d'un poste de travail temporaire ou permanent ? Vous recherchez un environnement ...
Après une découverte de surface d'Ibexa Commerce, entrons plus dans le détail pour comprendre son ...
Ibexa DXP propose un module pour gérer des produits pour la réalisation d'un site e-commerce. ...
Voici une présentation d'IbexaMailing, un module qui ajoute la gestion des newsletters à Ibexa. IbexaMailing est ...
C'est la dernière occasion de vous souhaitez le meilleur pour cette année 2024 et surtout ...
To celebrate the release of Dataflow 5 for Symfony 7, here is some feedback on ...
🎯 Nous relevons le défi de lancer un grand concours : Vous faire gagner un ...
How to dynamically calculate shipping costs? The official documentation that explains how to create shipping ...
How to create a new product attribute type in Ibexa Commerce
A la recherche d'un poste de travail temporaire ou permanent ? Vous recherchez un environnement ...
Après une découverte de surface d'Ibexa Commerce, entrons plus dans le détail pour comprendre son ...
Ibexa DXP propose un module pour gérer des produits pour la réalisation d'un site e-commerce. ...
Voici une présentation d'IbexaMailing, un module qui ajoute la gestion des newsletters à Ibexa. IbexaMailing est ...
C'est la dernière occasion de vous souhaitez le meilleur pour cette année 2024 et surtout ...