Skip to content

Embed related content

To embed content in another content item, you query for it in the repository. There are two ways to query for a content item:

Embed siblings with Query type

To render the Siblings of a content item (other content under the same parent Location), use the Siblings Query type.

To do it, use the built-in ibexa_query controller's contentQueryAction:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
            content_view:
                full:
                    blog_post:
                        controller: ibexa_query::contentQueryAction
                        template: '@ibexadesign/full/blog_post.html.twig'
                        params:
                            query:
                                query_type: 'Siblings'
                                parameters:
                                    content: '@=content'
                                    limit: 3
                                    sort: 'date_published desc'
                                assign_results_to: items
                        match:
                            Identifier\ContentType: blog_post

The results of the Siblings query are placed in the items variable, which you can use in the template:

1
2
3
4
{{ ibexa_content_name(content) }}
{% for item in items.searchHits %}
    {{ ibexa_render(item.valueObject, {'viewType': 'line'}) }}
{% endfor %}

Embed Relations with a custom controller

You can use a custom controller for any situation where Query types aren't sufficient.

1
2
3
4
5
6
7
                    article:
                        controller: App\Controller\RelationController::showContentAction
                        template: '@ibexadesign/full/article.html.twig'
                        params:
                            accepted_content_types: [ 'article', 'test_target', 'test_source' ]
                        match:
                            Identifier\ContentType: article

This configuration points to a custom RelationController that should render all Articles with the showContentAction() method.

 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
<?php declare(strict_types=1);

namespace App\Controller;

use Ibexa\Contracts\Core\Repository\ContentService;
use Ibexa\Contracts\Core\Repository\LocationService;
use Ibexa\Core\MVC\Symfony\View\View;

class RelationController
{
    private ContentService $contentService;

    private LocationService $locationService;

    public function __construct(ContentService $contentService, LocationService $locationService)
    {
        $this->contentService = $contentService;
        $this->locationService = $locationService;
    }

    public function showContentAction(View $view, $locationId): View
    {
        $acceptedContentTypes = $view->getParameter('accepted_content_types');

        $location = $this->locationService->loadLocation($locationId);
        $contentInfo = $location->getContentInfo();
        $versionInfo = $this->contentService->loadVersionInfo($contentInfo);
        $relationList = $this->contentService->loadRelationList($versionInfo);

        $items = [];

        foreach ($relationList as $relationListItem) {
            if ($relationListItem->hasRelation() && in_array($relationListItem->getRelation()->getDestinationContentInfo()->getContentType()->identifier, $acceptedContentTypes)) {
                $items[] = $this->contentService->loadContentByContentInfo($relationListItem->getRelation()->getDestinationContentInfo());
            }
        }

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

        return $view;
    }
}

This controller uses the Public PHP API to get the Relations of a content item (lines 27-28).

The controller takes the custom parameter called accepted_content_types (line 23), which is an array of content type identifiers that are rendered.

This way you can control which content types you want to show or exclude.

Finally, the controller returns the view with the results that were provided in the items parameter. You can use this parameter as a variable in the template:

1
2
3
4
5
6
7
8
{% block content %}
<h1>{{ ibexa_content_name(content) }}</h1>
<ul>
    {% for item in items %}
        {{ ibexa_render(item, {'viewType': 'embed'} ) }}
    {% endfor %}
</ul>
{% endblock %}