Skip to content

Add menu item

To add a new menu entry in the Back Office, you need to use an event subscriber and subscribe to one of the events dispatched when building menus.

The following example shows how to add a "Content list" item to the main top menu and list all Content items there, with a shortcut button to edit them.

Create event subscriber

First, create an event subscriber in src/EventSubscriber/MyMenuSubscriber.php:

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

namespace App\EventSubscriber;

use EzSystems\EzPlatformAdminUi\Menu\Event\ConfigureMenuEvent;
use EzSystems\EzPlatformAdminUi\Menu\MainMenuBuilder;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

class MyMenuSubscriber implements EventSubscriberInterface
{
    public static function getSubscribedEvents()
    {
        return [
            ConfigureMenuEvent::MAIN_MENU => ['onMainMenuConfigure', 0],
        ];
    }

    public function onMainMenuConfigure(ConfigureMenuEvent $event)
    {
        $menu = $event->getMenu();

        $menu[MainMenuBuilder::ITEM_CONTENT]->addChild(
            'all_content_list',
            [
                'label' => 'Content List',
                'route' => 'all_content_list.list',
                'attributes' => [
                    'class' => 'custom-menu-item',
                ],
                'linkAttributes' => [
                    'class' => 'custom-menu-item-link',
                ],
            ]
        );
    }

}

This subscriber subscribes to the ConfigureMenuEvent::MAIN_MENU event (see line 14) and creates an all_content_list menu item (lines 22-23).

Add route

Next, configure the route that the menu item leads to:

1
2
3
4
5
6
all_content_list.list:
    path: /all_content_list/{page}/{contentTypeIdentifier}
    defaults:
        page: 1
        contentTypeIdentifier: false
        _controller: App\Controller\AllContentListController::listAction

Create controller

The route indicates a controller that fetches all visible Content items and renders the view.

Create the following controller file in src/Controller/AllContentListController.php:

 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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
<?php declare(strict_types=1);

namespace App\Controller;

use eZ\Publish\API\Repository\ContentTypeService;
use eZ\Publish\API\Repository\SearchService;
use eZ\Publish\API\Repository\Values\Content\LocationQuery;
use eZ\Publish\API\Repository\Values\Content\Query\Criterion;
use eZ\Publish\Core\Pagination\Pagerfanta\LocationSearchAdapter;
use EzSystems\EzPlatformAdminUi\Form\Factory\FormFactory;
use EzSystems\EzPlatformAdminUiBundle\Controller\Controller;
use Pagerfanta\Pagerfanta;

class AllContentListController extends Controller
{
    private $searchService;

    private $contentTypeService;

    private $formFactory;

    public function __construct(SearchService $searchService, ContentTypeService $contentTypeService, FormFactory $formFactory)
    {
        $this->searchService = $searchService;
        $this->contentTypeService = $contentTypeService;
        $this->formFactory = $formFactory;
    }

    public function listAction($contentTypeIdentifier = false, $page = 1)
    {
        $query = new LocationQuery();

        $criterions = [
            new Criterion\Visibility(Criterion\Visibility::VISIBLE),
        ];

        if ($contentTypeIdentifier) {
            $criterions[] = new Criterion\ContentTypeIdentifier($contentTypeIdentifier);
        }

        $query->query = new Criterion\LogicalAnd($criterions);

        $paginator = new Pagerfanta(
            new LocationSearchAdapter($query, $this->searchService)
        );
        $paginator->setMaxPerPage(8);
        $paginator->setCurrentPage($page);
        $editForm = $this->formFactory->contentEdit();

        $contentTypes = [];
        $contentTypeGroups = $this->contentTypeService->loadContentTypeGroups();
        foreach ($contentTypeGroups as $group) {
            $contentTypes[$group->identifier] = $this->contentTypeService->loadContentTypes($group);
        }

        return $this->render('list/all_content_list.html.twig', [
            'totalCount' => $paginator->getNbResults(),
            'articles' => $paginator,
            'form_edit' => $editForm->createView(),
            'contentTypes' => $contentTypes,
        ]);
    }
}

Add template

Finally, create the templates/list/all_content_list.html.twig file indicated in line 56 in the controller:

 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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
{% extends '@ezdesign/ui/layout.html.twig' %}

{% block title %}{{ 'Content List'|trans }}{% endblock %}

{%- block breadcrumbs -%}
    {% include '@ezdesign/ui/breadcrumbs.html.twig' with { items: [
        { value: 'url.list'|trans|desc('Content List') }
    ]} %}
{%- endblock -%}

{%- block page_title -%}
    {% include '@ezdesign/ui/page_title.html.twig' with {
        title: 'url.list'|trans|desc('Content List'),
        icon_name: 'article'
    } %}
{%- endblock -%}

{%- block content -%}
    <section class="container my-4">
        <div class="my-4">
            <div class="dropdown">
                <button class="btn btn-secondary dropdown-toggle" type="button" id="contentTypeFilter" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
                    Content Type
                </button>
                <div class="dropdown-menu" aria-labelledby="contentTypeFilter">
                    {% for group, types in contentTypes %}
                    <h6 class="dropdown-header">{{ group }}</h6>
                        {% for type in types %}
                            <a class="dropdown-item" href="{{ path('all_content_list.list', { 'contentTypeIdentifier': type.identifier }) }}">{{ type.name }}</a>
                        {% endfor %}
                    {% endfor %}
                </div>
            </div>
        </div>
        <div class="ez-table-header">
            <div class="ez-table-header__headline">{{ "Content List"|trans }}</div>
        </div>
        <table class="table">
            <thead>
                <tr>
                    <th>{{ 'Content name'|trans }}</th>
                    <th>{{ 'Content Type'|trans }}</th>
                    <th>{{ 'Modified'|trans }}</th>
                    <th>{{ 'Published'|trans }}</th>
                    <th>{{ 'Edit'|trans }}</th>
                </tr>
            </thead>
            <tbody>
            {% for article in articles %}
                <tr>
                    <td><a href={{ez_path(article)}}>{{ ez_content_name(article.contentInfo) }}</a></td>
                    <td>{{ article.contentInfo.contentTypeId }}</td>
                    <td>{{ article.contentInfo.modificationDate|ez_full_datetime }}</td>
                    <td>{{ article.contentInfo.publishedDate|ez_full_datetime }}</td>
                    <td>
                        <button class="btn btn-icon mx-2 ez-btn--content-edit"
                                title="{{ 'dashboard.table.all.content.edit'|trans|desc('Edit Content') }}"
                                data-content-id="{{ article.contentInfo.id }}"
                                data-version-no="{{ article.contentInfo.currentVersionNo }}"
                                data-language-code="{{ article.contentInfo.mainLanguageCode }}">
                            <svg class="ez-icon ez-icon-edit">
                                <use xlink:href="{{ asset('bundles/ezplatformadminui/img/ez-icons.svg') }}#edit"></use>
                            </svg>
                        </button>
                    </td>
                </tr>
            {% endfor %}
            </tbody>
        </table>
        {{ pagerfanta(articles, 'ez') }}
    </section>
    {{ form_start(form_edit, {
        'action': path('ezplatform.content.edit'),
        'attr':
        { 'class': 'ez-edit-content-form'}
    }) }}
    {{ form_widget(form_edit.language, {'attr': {'hidden': 'hidden', 'class': 'language-input'}}) }}
    {{ form_end(form_edit) }}
    {% include '@ezdesign/content/modal/version_conflict.html.twig' %}
{%- endblock -%}

{% block javascripts %}
    {{ encore_entry_script_tags('ezplatform-admin-ui-dashboard-js', null, 'ezplatform') }}
{%- endblock -%}