A "Not WordPress"-CMS based on Symfony
Tags: php, symfony
Published: 2021-10-21 13:22:10

PHP offers many interesting Content Management Systems. The most popular is WordPress. It's offered on many shared hosting services, it's got a plethora of plugins and themes, and for a company wanting to expand the features there are many developers to choose from. But if you are a Symfony developer you can be a bit perplexed<a href="#perplexing">*</a> going into WordPress-development. If that's not the way for you, maybe Bolt CMS is?

In a series of articles I will describe Bolt CMS with 3 different perspectives: content creators/editors, designers, and developers. In this first article I focus on Content Creators.

## Bolt CMS for Content Creators
The aim of Bolt CMS is "easy content creation". A few tools that makes this possible are:
* Rich content editors
* Built-in internationalization
* User-defined Content Types


Logging into a Bolt-application will show you an interface like the picture below. It's got a sidebar, a main-section, and asides. In the sidebar you can navigate between different content-types and settings. The main-section displays a list of the latest modified contents. The aside displays a few Bolt widgets. *You can check out a live demo on https://demo.boltcms.io/bolt/.*

![Bolt CMS Dashboard](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bvvpc0h40vxzizo0n7mu.png)

Content types is defined in a special file called contenttypes.yaml. You define anything from a singleton like Homepage, to pages, entries and persons in this file. For now, everything is configured just the way most editors would like it. And if it isn't, they can edit this file (contenttypes.yaml) and they get the content type they want - without resorting to a plugin or coding in PHP.

Let's define a new page. Hover over *Pages* and click on *new*.
![Click in the sidebar for pages to get to create a new entity of this type.](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0o9c3zg0lirkrudzx0l4.png)

This takes you to a page whit input fields corresponding to how the page-entity is specified in contenttypes.yaml. 
![The edit view for page contains input fields for title, teaser and a text editor for body.](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ga6rv92s8zp4c0bai766.png)
 
 Clicking on **Save changes** will publish this new page, granted that *Status* is *Published* - which is this content type's default status. Having done that, you can now check out the page by clicking on *View saved version* under *Primary Actions*.
![The published Page](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wekuqquf1y1v1jtsa9pa.png)
 
In similar ways to how a Content Creator can create a Page, they can create whatever content type they like. Is there a blog on their website, they can write a new entry to it in a similar way. But let's see how a creator would go about if they would like a new Content Type that is not currently present.

### Defining a new Content Type
In the sidemenu hover over *Configuration* and then click on *Content Types*.
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/27l6y9364rkbcldksdol.png)

This will take you to an in-browser yaml-editor where all the current Content Types are defined. We are now going to define a new type called "Projects". We will scroll towards the end of the file and enter the following:
```yaml
projects:
    name: Projects
    singular_name: Project
    fields:
        title:
            type: text
        image:
            type: image
        content:
            type: redactor
    icon_many: "fa:palette"
```
Indentations are important in YAML, so make sure to be adding proper amount of spaces (**not** tabs). We can see YAML as a key-value pair of relation. Where `projects` is the key for our Content Type. This key contains an array of other keys, properly indented. `name` is the *readable* name of the type, and often it is the same as the first key but capitalized. As this is the plural version of the type, there is also a `singular_name`. Under `fields` we can properly define what the *Project* Content Type should contain. We are keeping it properly simple here and want this type to have a *title*, *image* and a text-component called *content*. The text-component is powered by *redactor* so we can do a bit of *rich text editing*.

The configuration for the Content Type is finished here with specifying which Font Awesome icon we would like to represent it with in the sidebar. We use `"fa:palette"` in this example. Clicking on *Save Changes*, then *Projects* appear in the sidemenu. 

![After clicking on Save the new Content Type appears in the side-menu.](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/09fbz341ebo75y3yi6g5.png)
 
It can go pretty fast going from defining a new Content Type to creating it. Just click on *new* for Projects and fill out the fields in the editor-view. 
![In the editor view you can now fill in the different fields as they were defined in the previous step.](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w82h8k135enyq2hsnmzp.png)
 
When you are done you can view it on the homepage: either under `/project/[project-id]` or under a listing page at `/projects`. If it doesn't show up, hover over *Maintenance* back on the dashboard and click on *Clear cache*. This will update the routes and take into account any new Content Types.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5zg63ivpzqs8hkgicu1t.png)

## *<span id="perplexing">Things that can perplex a Symfony developer about WordPress</span>:
* The application is located in the public-folder.
* It's not Composer-based.
* OOP is the exception.
* Something else but Doctrine can manage CRUD.
* Praise **The Loop**.