daniel
Daniel Rotter
Core developer and support guru. Passionate traveler and soccer player.
@danrot90

Sulu 2.1 RC1 is here - with Symfony 5 Support, Nested Blocks and Deep Links

Today we released the first release candidate of Sulu CMS 2.1.

In addition to all the work we’ve put into making Sulu “Symfony 5 ready”, we have also implemented a few new features and improvements for you to try out. Here’s what we have for you in this release:

  • Nested blocks - blocks-within-blocks!
  • Easier to manage massive amounts of content: Filtering lists
  • Quick editing with deep links
  • The state of Symfony 5 Support
  • Update of JavaScript packages

In this post we also give you a peek at the improvements in user experience and developer experience, as well as a shout-out to our community contributors who helped make this release awesome. We’d love your feedback on this release candidate, but we suggest you don’t use this in production.

Get Sulu CMS 2.1 RC here

Sulu CMS - a New Minor Release Twice a Year

To bring new features and improvements to our users we’re working on releasing a new minor version roughly twice a year. However, sticking to a time-based schedule is hard when we want to include certain features with external dependencies. Instead of letting that block us, we’ve published the release candidate for Sulu CMS 2.1 to stay on schedule, while we wait for a special dependency to get unblocked. 

It would e.g. be great to support Symfony 5 already in the 2.1 release, instead of waiting for roughly another six months. So that’s why we decided to be a little bit more flexible with these releases. 

In this release, we already removed a lot of Symfony deprecations, which should make the transition to Symfony 5 easier. Hopefully all of our external dependencies will release new versions compatible with Symfony 5 soon as well, which would allow us to release 2.1 with Symfony 5 support.

However, be aware that this is a release candidate, and if something goes south, we might still change some fundamentals. We would still like you to test this release, but be careful when using it in production.

Of course we’ve documented all breaking changes in our UPGRADE file, in order to make migrating to the latest Sulu version easier for you.

Nested Blocks

With Sulu, you build pages by assembling content blocks that, until now, could not be nested. In the same way content editors have always been able to add a number of arbitrary blocks to a page in Sulu, they also wanted to repeat a certain structure within these blocks. 

An obvious solution would be to nest “blocks within blocks”, but until now it wasn’t possible and this feature was requested quite often. The Nested Blocks issue is the one with the most upvotes in our repository, it often came up at events, and on the community Slack.

Before this release, if you wanted something like this, developers were including snippets in the blocks of pages. This had some serious drawbacks for the content manager:

  • The content was spread over multiple forms, which made it hard to get an overview of the end result.
  • Editing was not really smooth, because it was necessary to switch between multiple forms.
  • The list of snippets could get very long, if there were many pages being built like that.
  • The content was also harder to load for developers finally displaying the page, so they also rightfully requested this feature.

So we’ve listened and implemented nested blocks for this release! 

Here’s how you do it. Developers can define blocks within blocks in their template by nesting them in the XML definition:

<block name="blocks" default-type="default">
    <meta>
        <title lang="en">Blocks</title>
    </meta>
    <types>
        <type name="default">
            <meta>
                <title lang="en">default</title>
            </meta>
            <properties>
                <property name="title" type="text_line">
                    <meta>
                        <title lang="en">Title</title>
                    </meta>
                </property>

                <block name="subblocks" default-type="editor" minOccurs="0">
                    <meta>
                        <title lang="en">Sub Blocks</title>
                    </meta>
                    <types>
                        <type name="editor">
                            <meta>
                                <title lang="en">Editor</title>
                            </meta>
                            <properties>
                                <property name="text_editor" type="text_editor">
                                    <meta>
                                        <title lang="en">Text Editor</title>
                                    </meta>
                                </property>
                            </properties>
                        </type>
                        <type name="media">
                            <meta>
                                <title lang="en">Media</title>
                            </meta>
                            <properties>
                                <property name="media_selection" type="media_selection">
                                    <meta>
                                        <title lang="de">Medienauswahl</title>
                                    </meta>
                                </property>
                            </properties>
                        </type>
                    </types>
                </block>
            </properties>
        </type>
    </types>
</block>

This will result in nested blocks in the Administration interface, i.e. within a block there is another add button, to add more nested blocks:

This results in a much better user experience if applied correctly, because the above problems are solved:

  • All the content is shown within a single form, so there is no need to jump between different forms and accidentally losing data while doing so.
  • Editing is really smooth, because switching between different blocks is done via simple scrolling.
  • The blocks are directly attached to the page they belong to, without the intermediate snippets.

Filtering Lists to Manage Lots of Content

This feature mainly concerns content managers who often work with massive lists in the Sulu administration interface. Especially when used with custom business logic, these lists can contain loads of entries, and the more entries there are, the more useful it would be to be able to filter them using certain criteria.

There was already a filter feature in Sulu 1.x, but we dropped it, because we felt we had  made it too complicated. We realised that most of the time you simply want to quickly filter the list based on a few columns. For this reason, the filters are now more integrated in the list itself, so that changes to the filters are made immediately visible to the user. It is currently not possible to store multiple filters for a single list, but that makes the filters easier to use. For convenience, the last used filter is still stored for each user, i.e. the same filter is still applied if the user returns to the list.

Now you might think that this means a lot of implementation work for the developer, but actually a lot of this functionality has been implemented in a reusable way. So if you are using our ListBuilder for your REST API and you wish to use that with filters, the only thing you have to do is to configure the list correctly in the list XML file:

<identity-property name="positionId" visibility="never" translation="sulu_contact.position">
    <field-name>position</field-name>
    <entity-name>SuluContactBundle:AccountContact</entity-name>

    <joins ref="position"/>

    <filter type="selection">
        <params>
            <param name="displayProperty" value="position" />
            <param name="resourceKey" value="contact_positions" />
            <param name="type" value="select" />
        </params>
    </filter>
</identity-property>

Based on this definition Sulu is able to:

  • Display the correct UI elements for these filters.
  • Return the correctly filtered list in the REST API for you.

The included API allows a variety of UI elements for filters including checkboxes, text fields, and date fields. Apart from the feature itself, other new improvements make this feature easier to use. Most of these are also improvements to other parts of the system and you can use these when building your own UIs in our Administration interface.

  • The list was redesigned to save space.
  • A Chip UI component has been extracted.
  • The ArrowMenu UI component now adjusts when elements inside of change in size after it has been rendered.
  • Our router service of the administration application now also transforms date, array and object parameters (or any of the possible combinations).
  • A new ResourceCheckboxGroup UI component was implemented, which loads the possible values from the server.
  • The MultiAutoComplete UI component now accepts an external store, which allows to reuse the data loaded from the server in multiple locations, fewer requests means speedier performance.

When you’re editing content in Sulu, you may be looking at referenced media, contacts, or snippets which you can’t edit in the content form because they are different entities. What if you want to change the details of a contact while you have it fresh in your mind? 

Users have requested a solution a few times, specifically proposing a kind of ‘edit in place’ model. However, we wanted to avoid having forms in overlays because it goes against the design patterns we use in Sulu, and it would raise a new set of problems. So we have a new solution!

Now when content editors see other entities that are referenced, such as accounts, contacts, pages, media, or any custom entity implementation, they can click on a deep-link in the form to edit these entities. 

This feature has been implemented for the abstract selection and single selection field types.

field_type_options:
    single_selection:
        single_contact_selection:
            default_type: 'list_overlay'
            resource_key: 'contacts'
            view:
                name: 'sulu_contact.contact_edit_form'
                result_to_view:
                    id: 'id'
            types:
                list_overlay:
                    adapter: 'table'
                    list_key: 'contacts'
                    display_properties: 'fullName'
                    empty_text: 'sulu_contact.no_contact_selected'
                    icon: 'su'-user
                    overlay_title: 'sulu_contact.single_contact_selection_overlay_title'

In Sulu 1.x we had a similar feature where editors could click on elements in the admin interface to navigate to an underlying entity, so this will be familiar to you if you used that version of Sulu. In contrast to Sulu 1.x this feature has now also been added to the smart content and teaser selection field types. In order for this to work the configurations for these components had to be extended. This is documented in our documentation for smart contents and teaser selections.

Symfony 5 Support

As already mentioned in the introduction, we are towards supporting Symfony 5 in the Sulu 2.1 release. The RC1 is not completely there yet, but we are on our way. We have removed all of our directly used Symfony deprecations, and now we’re only waiting for a few external dependencies to release their versions with Symfony 5 support. Once that is done I am confident that we can ship Sulu 2.1 fully compatible with Symfony 5.

To pave the way, we decided to drop support for Symfony 4.3, because not only is it easier to support only 4.4 and 5.0, but also Symfony 4.3 will stop getting security fixes this July. The update from Symfony 4.3 to 4.4 should be fairly simple, since it is not a major release and therefore should not contain any breaking changes.

Update of JavaScript Packages

We have also updated all the JavaScript packages included in the Sulu administration interface. This way we keep pace with the latest package versions, and it is a lot easier to update if you update regularly, because there are less reasons for the application to break.

Improvements in User Experience

There are two more improvements from a user’s point of view I would like to mention:

First, the URL field for entities using the RouteBundle has now changed the way it handles the generation of the URL. Previously the URL was generated while saving the page, i.e. the user saw the resulting URL after saving the page. This behavior was different from the one for pages, where the URL was generated right after the fields required for the generation were entered.

Second, we have replaced some of the Font Awesome icons with icons from our own icon set, which suit better with our design.

Improvements in Developer Experience

We have added quite a number of improvements for developers and operators of Sulu:

Contributions from Our Community

Of course we also want to give a shoutout to our community members, who also helped by making this release better.

Thank you Karsten Frohwein, who also helps out a lot in our slack channel, for improving the output of our commands — yes, we do typos as well!

Jaap Romijn made similar fixes to our comments, where the order is sometimes a little bit confusing.

Daniel Ruf has made several small improvements in our codebase. Thank you for that!

Finally, kudos go also to Pablo Lozano for implementing support for Azure Blob Storage.

Sulu CMS keeps getting better thanks to your input and help. Now that’s where you come in...

Test, Test, Test, …

I hope you like all the new features we’ve introduced, and I really want to encourage you to test all the new (and old) features included in this release. It is a release candidate, so whatever feedback you have (especially if we broke something or didn’t think about a specific use case)  might still go into the final release.

Don’t forget to “star” and watch the Sulu repository for updates!

Download Sulu CMS 2.1 RC