Tous les articles
  • Ibexa DXP
  • Symfony
  • Twig

Ibexa DXP : afficher un type de contenu avec les vues et Twig

Configurer une vue de contenu, écrire le template Twig et ajouter une liste d'articles avec un contrôleur personnalisé et le SearchService.

Dans Ibexa DXP, les contributeurs créent les contenus dans le back-office, et c'est à nous, développeurs, de décider comment ils s'affichent. Le mécanisme central pour ça, ce sont les vues de contenu (content views). Prenons un exemple concret : un type de contenu article, avec les champs title, intro, image et body.

1. Déclarer la vue

Dans config/packages/ibexa.yaml, on associe un template à un type de contenu grâce à un matcher :

YAML
ibexa:
    system:
        site_group:
            content_view:
                full:
                    article:
                        template: '@ibexadesign/full/article.html.twig'
                        match:
                            Identifier\ContentType: article

full est le type de vue utilisé pour une page complète. On peut définir d'autres types, par exemple line pour un élément dans une liste, avec le même principe.

2. Écrire le template

Ibexa fournit des fonctions Twig pour afficher les champs proprement :

Twig
{% extends '@ibexadesign/pagelayout.html.twig' %}

{% block content %}
    <article>
        <h1>{{ ibexa_content_name(content) }}</h1>

        {% if not ibexa_field_is_empty(content, 'image') %}
            {{ ibexa_render_field(content, 'image') }}
        {% endif %}

        {{ ibexa_render_field(content, 'intro') }}
        {{ ibexa_render_field(content, 'body') }}
    </article>
{% endblock %}

ibexa_render_field utilise le bon rendu pour chaque type de champ : texte riche, image avec ses variations, etc. Il vaut mieux l'utiliser plutôt que d'afficher la valeur brute.

3. Ajouter une liste avec un contrôleur

Pour une page « Blog » qui liste ses articles enfants, on branche un contrôleur sur la vue du dossier parent :

YAML
folder_blog:
    template: '@ibexadesign/full/blog.html.twig'
    controller: App\Controller\BlogController::list
    match:
        Identifier\ContentType: folder
        Identifier\Section: blog

Le contrôleur reçoit la vue, interroge le moteur de recherche et ajoute les résultats aux paramètres du template :

PHP
namespace App\Controller;

use Ibexa\Contracts\Core\Repository\SearchService;
use Ibexa\Contracts\Core\Repository\Values\Content\Query;
use Ibexa\Contracts\Core\Repository\Values\Content\Query\Criterion;
use Ibexa\Contracts\Core\Repository\Values\Content\Query\SortClause;
use Ibexa\Core\MVC\Symfony\View\ContentView;

final class BlogController
{
    public function __construct(private readonly SearchService $searchService) {}

    public function list(ContentView $view): ContentView
    {
        $query = new Query([
            'filter' => new Criterion\LogicalAnd([
                new Criterion\ParentLocationId($view->getLocation()->id),
                new Criterion\ContentTypeIdentifier('article'),
                new Criterion\Visibility(Criterion\Visibility::VISIBLE),
            ]),
            'sortClauses' => [new SortClause\DatePublished(Query::SORT_DESC)],
            'limit' => 10,
        ]);

        $articles = array_map(
            static fn ($hit) => $hit->valueObject,
            $this->searchService->findContent($query)->searchHits
        );

        $view->addParameters(['articles' => $articles]);

        return $view;
    }
}

Dans le template, chaque article peut ensuite s'afficher avec sa vue line :

Twig
{% for article in articles %}
    {{ render(controller('ibexa_content::viewAction', {
        contentId: article.id,
        viewType: 'line'
    })) }}
{% endfor %}

Bonnes pratiques

  • Utiliser filter plutôt que query quand on ne fait pas de recherche plein texte : c'est plus rapide et cela ne calcule pas de score de pertinence.
  • Penser à la pagination dès qu'une liste peut grossir, par exemple avec Pagerfanta et l'adaptateur fourni par Ibexa.
  • Laisser faire le cache HTTP : les vues de contenu sont automatiquement étiquetées, et le cache est invalidé à la publication.
  • Pour des listes réutilisables, les Query Types permettent de déclarer une requête une fois et de la configurer directement en YAML.

Avec ces trois briques — vue, template, contrôleur — on couvre déjà la majorité des besoins d'affichage d'un site Ibexa.