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:
La conférence annuelle Ibexa se tiendra les 30 et 31 janvier 2025 à Barcelone et ...
Data security, and in particular the security of user passwords, is an absolute priority for ...
2024 aura été une année riche en tempêtes, avec ses hauts et ses bas. Mais ...
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 ...
La conférence annuelle Ibexa se tiendra les 30 et 31 janvier 2025 à Barcelone et ...
Data security, and in particular the security of user passwords, is an absolute priority for ...
2024 aura été une année riche en tempêtes, avec ses hauts et ses bas. Mais ...
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 ...