Leverage Sulu's admin UI for Symfony applications

If you’re starting with Sulu, you might be wondering how to extend the administrative interface. It’s one of the cool things about working with Sulu. You can define your own entities, not just content. With entities, you can apply your own business logic to them while allowing editors to create, update and delete them in the intuitive Sulu interface. In this guide, we’re going to tell you how it’s done.

Leverage Sulu’s innovative backend

Sulu is a full-stack CMS for developing with Symfony. Sulu provides an innovative and beautiful admin UI to integrate with your Symfony applications.

Manage your custom entities alongside content for your websites with a content-editor-friendly UI. Meanwhile Sulu gets out of your way so you can flexibly build your own custom entities and business logic.

Imagine expressing your application’s business logic the way you need to with custom entities in Symfony, overlaid with Sulu’s beautiful admin UI. However Sulu is way more than an admin UI for Symfony applications. Out of the box, Sulu provides a robust content management system with all the essential features websites need. Manage content and data for hundreds of websites in different locales, translated in any number of languages running off a single consistent instance. All of the capabilities that Sulu provides for content management, such as a great admin UI, templating, caching, [etc] are available to use with your Symfony application. If you know Symfony, it’s easy to set up websites with Sulu so you can focus on custom development instead of content management.

Why you may want to extend the admin interface

Sulu has a slick admin interface that editors love. It’s intuitive and looks great, and the best thing about it is that you can use it for your whole project — even the bits that aren’t content. If you want to see the admin interface for yourself, you can experiment with our demo site, sulu.rocks.

Often, developers want to add their own entities and make them editable. Say you have an awards program and need to take submissions, then let colleagues decide on the winners in private. The more complex your business logic, the less suitable the built-in content repository is. You can use the power of Symfony to build your own entity — say, “Award Entry” — and apply the business logic you need. With Sulu, you can extend the admin interface and make this entity editable. This means less unnecessary effort for you and is great for your editors, who only need to remember one set of login details instead of switching between two or more systems.

Sulu limits how much code you have to write, but doesn’t limit how much code you can write. You get the best of both worlds: if you want to use the standard interface with pre-built, tried-and-tested UI elements such as lists, sorting, filters, and forms, you can spin this up by writing configuration, not your own code. However, if you need to sprinkle in a few special touches of your own, such as custom form fields or toolbar actions, there are plenty of extension points for you to intervene using your own React JS code. You can even make much more extensive modifications by replacing entire views, if that’s what you need.

Examples of situations where you need this freedom

  • Boutique e-commerce: Dedicated e-commerce solutions can be very rigid, but if you’re looking for more bespoke products and workflows, Sulu’s flexibility will serve you well. The Allianz Cinema website is a great example.
  • Interactive data and content: Customers can experiment with product options using configurators, or interact with art-directed content and gamification experiences because Sulu tames complex business logic.
  • Tailored content: Sites with unique entity types that are different from standard pages or articles lend themselves to Sulu’s “bring your own entity” approach. The high-traffic Küchengötter recipe portal is a case in point.
  • Community platforms: Manage user-generated content all within a single interface, no matter how bespoke your data structure is.

Things to consider before you begin

Before starting your project, ask yourself the following questions.

  • Do I need custom entities and business logic or are standard pages sufficient?
    • For content-heavy portals, using built-in functionality will save you time and energy due to testing and debugging. It will be easier to maintain in the long run.
    • Building your own entities and business logic gives you more flexibility to deliver on custom requirements.
  • Do my users need the entire system to be manageable within a single interface?
    • It may be an option to integrate a third-party system to take care of specific tasks. Sulu can still pull in that information so the end user won’t notice.
    • A full integration of a third-party system, or building the features yourself in Symfony, is more convenient for editors, especially if they need to login to both (or all) parts of the system.
    • Bringing all systems under one roof can give you more control of customer data for analytics and marketing purposes.

We’re here to help you get it right

As a rule of thumb: if you only need to display information publicly, you probably don’t need to extend the admin UI. If you’ve got more processes running below the surface, Sulu’s got your back as well.

And another rule of thumb: YAGNI – You Ain’t Gonna Need It!

So don’t over engineer. Keep it simple. But don’t bend functionality too far, and don’t skimp on editor experience.

Do you need help planning your project? Get in touch and we can fast-track you to success with our workshops as well as consulting and coding services.

Help

The road ahead — bring your entities and business logic into the Sulu admin interface

Here we give an overview of the steps you need to take. For specific details, we refer you to our developer’s guide to extending the admin interface. You can also consult our Slack channel, or call on our support services.

Create your entities

If your datatypes can’t be modeled using one of Sulu’s built-in entities such as Page or Article, you can extend existing entities or create your own. You should create your entities according to Symfony best practices or take a more sophisticated approach depending on your use case. In order to integrate your entities into Sulu, you need to provide a REST API with any of the standard CRUD operations you need.

If you use Doctrine as a database layer, Sulu gives you extra help later on: you can take advantage of built-in sort, column ordering, and filtering more easily just by writing a config file.

<?php
namespace Sulu\Bundle\TagBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use JMS\Serializer\Annotation\Expose;
use JMS\Serializer\Annotation\Groups;

/**
 * @ORM\Entity
 */
class Tag
{
    /**
     * @var string
     * @Expose
     * @Groups({"partialTag"})
     * @ORM\Column(type="string", length=255)
     */
    private $name;

    /**
     * @var int
     * @Groups({"partialTag"})
     * @ORM\Id
     * @ORM\GeneratedValue
     * @ORM\Column(type="integer")
     */
    private $id;
}
Your Entity

Write your business logic

You can write your own business logic using Symfony, in addition to the powerful features that are already built in as standard. Sulu gets out of your way and lets you do your thing.

As long as your entities are integrated into Sulu properly (see above), you can go ahead and write your business logic using Symfony. Some CMSs have all sorts of meta languages and coding standards you have to adhere to, but we delegate this to Symfony which gives you, as a developer, much more freedom to work as you normally do.

<?php
namespace App\Controller;

use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;

class TagController
{
    /**
     * @Route("/tags/{id}", name="app_tag", methods={"PUT"})
     */
    public function edit($id)	
    {
        // Implement your business logic
    }
}
Your Business Logic

Wire up the admin UI

Now it’s time to hook up your entities with the frontend so that editors and admins have a beautiful interface to organize and edit them through. There’s virtual no code to write here: it’s all done in configuring XML files and a minimal amount of PHP. This is great for developers, who prefer this to web interfaces. It also makes it much easier to deploy changes using version control such as Git. Finally, this declarative approach is less error-prone because instead of writing code, you use existing features that are debugged and tested.

You need to configure the following:

  • Forms. List all your forms’ properties and declare the field type for each one. This determines how it’s presented in the admin UI.
<?xml version="1.0" ?>
<form xmlns="http://schemas.sulu.io/template/template"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://schemas.sulu.io/template/template http://schemas.sulu.io/template/form-1.0.xsd"
>
    <key>tag_details</key>

    <properties>
        <property name="name" type="text_line" mandatory="true">
            <meta>
                <title>sulu_admin.name</title>
            </meta>
        </property>
    </properties>
</form>
Form
  • Lists. For example, tell the system which headings are required and how to build a query.
    • If you have an entity that uses Doctrine, Sulu supports creating a list (you can sort, order columns, filter). Write the config file, Sulu will then do the database query.
<?xml version="1.0" ?>
<list xmlns="http://schemas.sulu.io/list-builder/list">
    <key>tags</key>

    <properties>
        <property name="name" visibility="always" searchability="yes" translation="sulu_tag.tag">
            <field-name>name</field-name>
            <entity-name>%sulu.model.tag.class%</entity-name>
        </property>

        <property name="created" visibility="yes" translation="sulu_admin.created" type="datetime">
            <field-name>created</field-name>
            <entity-name>%sulu.model.tag.class%</entity-name>

            <filter type="datetime" />
        </property>
    </properties>
</list>
List
public function configureViews(ViewCollection $viewCollection): void
{
    if ($this->securityChecker->hasPermission(static::SECURITY_CONTEXT, PermissionTypes::EDIT)) {
        $viewCollection->add(
            $this->viewBuilderFactory->createListViewBuilder(static::LIST_VIEW, '/tags')
                ->setResourceKey('tags')
                ->setListKey('tags')
                ->setTitle('sulu_tag.tags')
                ->addListAdapters(['table'])
                ->setAddView(static::ADD_FORM_VIEW)
                ->setEditView(static::EDIT_FORM_VIEW)
        );
    }
}
Set up View

If you have any other amendments you need to make to the UI, just remember that it’s all written in React. So from a tiny intervention such as tailoring a form element’s behavior to writing a whole new view: the Sulu admin UI doesn’t make you write code, but neither does it stop you.

import React from 'react';
import {viewRegistry} from 'sulu-admin-bundle/containers';

class MyReactComponent extends React.Component {
    render() {
        return 'Hello World';
    }
}

viewRegistry.add('example.my_view', MyReactComponent);
Custom View

Dive into the code

The code examples in this guide are just extracts. If you’re looking for more detail, then check out the documentation.

A great place to take a deep dive is our workshop from Symfony Live Berlin, in 2019, which is complete with an example project, including all the code. We regularly update this to the latest Sulu version.

Conclusion

We really care about user experience from an editor’s perspective, which is why we’ve put lots of thought and effort into designing the admin UI. You can make this experience available not only in classic content projects but many other projects you build on Symfony, even those with extensive business logic that isn’t exposed on the website. Since Sulu 2.0, it’s less complex to do this — you don’t have to write JavaScript to integrate your entities. This is great for your end users, editors, and developers alike.

Last Updated 07. January 2021

You might also be interested in these articles

Blocks

Structured Content with Blocks

In this guide we explain what Blocks are for and…
Learn more
Cloud-Ready

Scaling on Demand – Sulu as a Cloud-Ready CMS

Sulu is a cloud-ready CMS, making it ideal for ap…
Learn more