Custom admin interfaces in eZ Platform made easy: The story of Netgen Tags

16 Jan 2018  | 
Edi Modrić
Custom admin interfaces in eZ Platform made easy: The story of Netgen Tags

Back in 2012, just as eZ Publish saw its first release of version 5, Netgen Tags debuted as a rewrite of the legacy eZ Tags extension for eZ Publish 4. It was rewritten completely, same as eZ kernel was. However, up until a year ago, there was no admin interface for managing tags. The legacy eZ Tags admin interface was perfectly adequate, so a new one simply wasn't a priority. A lot has changed since then.

In 2016, an idea was born, governed by some of eZ partners who didn't use eZ Publish Legacy, to reimplement the tags management interface and to finance it using a crowdfunding campaign. The campaign was successful and my colleague Randy did most of the work implementing admin UI in pure Symfony and Twig.

He had one constraint, though: everything he implemented needed to be generic and extendable enough to allow the integration of the the admin UI in different admin panels, such as eZ Platform UI, Netgen Admin UI, and the future eZ Hybrid UI, as well as running it as a standalone interface. Additionally, those integrations were supposed to work without a single change in the base admin UI code or configuration.

It was not an easy task, but it was done, and today, Netgen Tags has the admin interface integrated into three different admin panels (eZ Platform UI, eZ Platform Admin UI, and Netgen Admin UI) in addition to the standalone variant.

I will go through each and try to give you an overview of what was done and how easy or hard it was to implement the integration, while the screenshots will show that in all cases, admin UI looks exactly the same. Hint: eZ Platform UI was a tough cookie to crack, and the rest was easy-peasy. :)

Standalone interface

From the start, we have developed Netgen Tags admin interface to have a customizable pagelayout. This was achieved by using a special Symfony service which is nothing more than a getter and a setter for the template name acting as the pagelayout for the admin interface. The Symfony service was then injected into the Twig templates via Twig globals.

Using the pagelayout from the Tags admin interface templates is then simple as:

{% extends eztags_admin.pageLayoutTemplate %}
 
{% block content %}
    ...
{% endblock %}

A standalone tags admin interface is now a redesigned interface from eZ Tags legacy extension:

Netgen Tags admin standalone

Netgen Admin UI

It turns out integrating the Tags admin UI into Netgen Admin UI is as easy as using a different, slightly modified template as a pagelayout and injecting it into the above-mentioned Twig global variable. The template in question acts as an intermediate template, extending the pagelayout provided by Netgen Admin UI, and providing additional markup needed to display the interface correctly, as well as JavaScript and stylesheets:

{% extends '@NetgenAdminUI/pagelayout.html.twig' %}
 
{% block stylesheets %}
    {{ parent() }}
 
    {% include '@NetgenTags/admin/stylesheets.html.twig' %}
{% endblock %}
 
{% block javascripts %}
    {{ parent() }}
 
    {% include '@NetgenTags/admin/javascripts.html.twig' %}
{% endblock %}
 
{% block pre_content %}
    ...
{% endblock %}
 
{% block post_content %}
    ...
{% endblock %}

To actually inject the new pagelayout to Twig templates from the Tags admin UI, we used a request event listener that takes the global variable and the Twig template name and does this when it recognizes the request as the Netgen Admin UI request:

$this->globalVariable->setPageLayoutTemplate($this->pageLayoutTemplate);

The final thing needed to wire it all together was to implement a so-called menu plugin interface from the Netgen Admin UI which allows displaying the root route of the Tags admin UI in the main menu.

As you can see, not much has changed in the interface when integrated in Netgen Admin UI:

Netgen tags Admin and Netgen Admin UI

eZ Platform UI

Since eZ Platform UI is now deprecated, to be used only by eZ Platform 1.x, I will not go into details on what needed to be done to have the integration working. I will mention however, that due to the eZ Platform UI being a single page JavaScript app developed in deprecated technology (YUI framework) which none of the Netgen team knew, the integration was everything but easy.

It looked as if everything was against us and our motto about not changing the generic admin code and config. Starting from the fact that the eZ Platform UI does not officially support adding custom entries to the top menu, and dealing with the fact that it expects backend routes to have the /pjax prefix, otherwise you need to fix very weird and hard to debug issues, then overriding the eZ Platform UI custom handling of HTML forms to allow for multivalued POST parameters, and, finally, the incompatibility between the usage and the implementation of the base layout templates for eZ Platform UI and Netgen Tags admin UI.

However, we did it, and the interface looks like this:

Netgen Tags and Admin Platform UI

eZ Platform Admin UI

eZ Platform Admin UI, on the other hand, is a revolution for the eZ Platform administration interface design. Instead of being an SPA, it is now a fully fledged Symfony app implemented with Symfony best practices in mind. This makes it possible for eZ and Symfony developers to once again develop custom integrations, something that was, for most of the developers, pretty hard to do on eZ Platform UI 1.x.

Due to the new admin UI being a Symfony app, we can use the same principles we used in Netgen Admin UI when integrating the Netgen Tags admin interface: creating an intermediate pagelayout that sits between the eZ Platform Admin UI main layout and Netgen Tags admin pages, registering an event listener that injects our new pagelayout into the Tags admin Twig templates, and creating an event listener which registers the menu item to the top menu of the admin interface.

The pagelayout looks similar to the one from Netgen Admin UI integration, but it uses embedding instead of extending the original layout:

{% set content = block('content') %}
 
{% embed '@EzPlatformAdminUi/layout.html.twig' %}
    {% block title %}{{ 'pagelayout.title'|trans }}{% endblock %}
 
    {% block content %}
        <div class="ng-tags-app row">
            {% include '@NetgenTags/admin/header.html.twig' %}
 
            <section class="ng-tags-container">
                <div class="tags-sidebar tags-sidebar-resizable">
                    <div class="main-menu">
                        {% include '@NetgenTags/admin/main_menu.html.twig' %}
                    </div>
                </div>
 
                <div class="tags-content">
                    <div class="path">
                        {% include '@NetgenTags/admin/path.html.twig' %}
                    </div>
 
                    {{ content|raw }}
                </div>
            </section>
        </div>
    {% endblock %}
{% endembed %}

The event listener is again, a request listener, which does the exact same thing as the one from Netgen Admin UI integration, but with a different rule to match the siteaccess as being eZ Platform Admin UI siteaccess, matching only if the current siteaccess is part of the special admin_group siteaccess group.

To register a new menu item to the top menu, we use an event listener which injects the menu item to the top menu with the help of KNP Menu library.

Notice how the pagelayout template here does not have javascripts or stylesheets blocks like the Netgen Admin UI variant does? This is due to the fact that the custom assets are included in the eZ Platform Admin UI by using the so-called admin UI components. Basically, you register a Symfony service to which you provide a Twig template to be rendered at a certain place in the page. So, to render stylesheet and JavaScript assets, we need to register two services, which complete our integration:

eztags.ezadminui.component.stylesheets:
     parent: EzSystems\EzPlatformAdminUi\Component\TwigComponent
     public: false
     arguments:
         - "@twig"
         - "@@NetgenTags/ezadminui/stylesheets.html.twig"
     tags:
         - { name: ezplatform.admin_ui.component, group: 'stylesheet-head' }
 
eztags.ezadminui.component.javascripts:
     parent: EzSystems\EzPlatformAdminUi\Component\TwigComponent
     public: false
     arguments:
         - "@twig"
         - "@@NetgenTags/ezadminui/javascripts.html.twig"
     tags:
         - { name: ezplatform.admin_ui.component, group: 'script-body' }

Finally, our interface integrated in eZ Platform Admin UI:

Netgen Tags Admin and eZ Admin UI

Start your engines, get set, go!

As you can see, it is pretty straightforward to migrate from Netgen Admin UI to eZ Platform Admin UI while keeping all your custom integrations still alive and kicking, without any changes to the core of your integrations. What this means is that you can use Netgen Admin UI today with your legacy project (even an eZ Publish 5 one), develop custom admin solutions in Symfony with a nice integration to Netgen Admin UI, and later, when the time is right, switch to eZ Platform 2 and eZ Platform Admin UI, without worrying that you will need to rewrite all of your custom modules just to use the new admin interface.

Comments

blog comments powered by Disqus

Short backstory of our blog: Sharing our experience from various web projects based on eZ Publish / eZ Platform, Symfony, PHP, HTML5, MySQL, jQuery, CSS, etc. and focusing on solving the problems we encountered.

Subscribe to RSS feed

Tags