Unite CMS – A promising headless CMS

Introduction

A headless CMS is getting more popularity these days because of its decoupling of the backend and the frontend. It is very easy to have a frontend of your choice and a backend of your choice. In this way you can have different technologies of your choice working behind but all together get an awesome CMS experience. Unite CMS is a very good and promising headless CMS which is based on PHP Symfony 4 framework and all the data is fetched by the GraphQL API. There is already a administration section available to manage the CMS whose frontend is made with Vue JS.

How to install

1. Clone the repository

2. Update the database

3. Create the super user

4. Create the main organisation

Note

As per the present code base, there is a problem (which will be hopefully solved in the upcoming version) which will result in an error message like The class 'Gedmo\Loggable\Entity\LogEntry' was not found and the solution to it is to add some code in the file config/packages/doctrine.yaml

A few things to understand

Organization: This is the main base of the CMS. This is the main roof under which we create all other things. More can be found here.

Domain: There can be a lot of domains under one organisation. But for our plan, we will have only one domain per installation. More can be found here.

User creation

There are 2 ways to create users in Unite:

  1. Organisation based (global)
  2. Domain based (local)

Create global user

  1. Go to the organisation
  2. Click on User from the left sidebar under the ‘MANAGE THIS ORGANIZATION

  3. Click on the green Invite user button from the top right corner

API working behind this action is

Create local user

  1. Go to the required group of the domain from the left menubar under MEMBERS

  2. Click on the green Add button from the top right corner
  3. Add or invite new user from here

API working behind creating a new member from here is

Overriding the templates

As this CMS is based on Symfony 4template overriding is done based on the framework.

Overriding the Email templates

Presently the emails sent by the system is based on the Twig templates. We can override any of these templates in the following way:

  1. Create a folder named ‘templates‘ in the base location of the project
  2. Inside that, create another folder named same as the bundle name. This would point to the /Resources/views folder of that particular bundle
  3. Create any sub-folder with the same name as present under the /Resources/views
  4. Finally create the twig template with the same name of the template that is needed to be overridden

Overriding the translations

Just like the templates, we can also override the translations. Translations are not based on bundles like the templates but on translation domains.

Overriding the Email translations

Presently the emails sent by the system is based on the Twig templates. We can override any of these templates in the following way:

  1. Create a folder named ‘translations‘ in the base location of the project
  2. Inside that, create the translation file same as the name of the translation domain. The default translation domain of Symfony is message and the filename is message.{locale}.yml

Create content type

The content type and/or settings type are used to define any type of content in the CMS. The difference between content type and the settings type is just that, content types can have multiple objects of the same type but the settings type can have only one object per type. Some sample type should be like below code

Multilingual

By default Unite CMS can be translated to any number of languages. All the languages can be defined as an array of 2 character language codes. This should be defined per content type objects explicitly. For example

Variables

For convenience of the developers, we can also create variable and use them in different places. Some good candidate could be the wysiwyg settings or the S3 bucket information.

Some defined content types

There are many predefined field types to work with Unite CMS which should be sufficient for start with.

Preview of the content

A preview can be defined to every content type. To define the preview we need to define the preview URL and the fields to query. For example

Sample code for creating contents and settings of a domain

Some code to create some basic content types and setting type are bellow. The title and the identifier of the domain should be changed per project.

Defining permission

All the permission are based on Symfony Expression Language. Anything executed by this expression will be translated to the boolean value. If this value is true, then the user will have the permission to the action. There are two types of permission

1. Domain based
for example:

2. Content based
for example:

Adding custom fields to the user

Custom fields can be added to a group of users. These fields can be later used for some different purposes like permission check. This field can be accessed as “member.data.{field_identifier}”. For example

Getting the data

Unite CMS uses GraphQL to get data from the database via its API. A short documentation can be found in their docs.

Some Sample GraphQL query

GraphQL Playground could be a good tool to execute some GraphQL queries. An online version is also available here. A small documentation for this could also be found in the docs of the Unite CMS.

To get all webpage content from the CMS domain from our sample code in point number 6.

Still to implement

There are still a few points that have not yet implemented in the CMS. A roadmap for the application can be found here.

  1. Still could not find a way to translate the validation messages. (for example at line 298 of the sample code)
  2. No readymade solution for eCommerce yet.
  3. Working with webhooks are still to be explored.

References

Documentation – Unite CMS documentation
Gitlab – Unite CMS repository
Gitter – Unite CMS lobby
Tutorials – Official tutorials (but sometimes they are outdated)


Comments

Leave a Reply

Your email address will not be published. Required fields are marked *