Pagekit: what’s wrong?

Lately, I took some time looking through [PageKit CMS]( It’s a nice project, based on Symfony components and Pimple DI container. Current version is 1.0, so the API is pretty stable and people can start developing extensions and themes.

However, I’ve found some problems here and there, and would like to talk about them, hoping that some of my suggestions might find their way into implementation.


First, Pagekit guys aren’t using Symfony’s Form component (which is a bit complicated, but nevertheless, awesome). Entity editors are implemented as plain HTML forms with a parameter array.

 We need events!

When an edit form is being rendered, no events are dispatched, and there is no way for my extension to detect that the blog post editor is going to render a textarea for the post content.

So, if I decided to implement a plugin for CKEditor, or Redactor, or any other JS <textarea/> enhancer, there would be no other option for me, but to implement my own blog extension.

The solution here is closely coupled to the previous problem. If I was implementing this, I would implement a typical Symfony form for the editor:

class BlogPostType extends AbstractType

    public function buildForm(FormBuilderInterface $builder, array $options)
            ->add('title', 'text')
            ->add('content', 'textarea')
            ->add('excerpt', 'textarea')

Then, once the form is instantiated, I’d dispatch a textarea.created event that would contain the Form instance. And then, anyone could easily catch this event and modify the 'content' and 'excerpt' fields, adding an attribute or an option to them so that CKEditor would be enabled for those fields.


The blog extension has its routes baked inside with annotations. What if my whole website is a blog? I won’t be able to move the blog index from the /blog URL.

A solution here would be to treat extensions as mountable services. There should be a component that would allow mounting publicly accessible extension controllers on any URL I’d like. Any conflicts could be easily handled with Symfony’s awesome routing component.

 A content model

A CMS stands for Content Management System. Content is the backbone of the whole application. Most of the CRUDs we see in a CMS backend are content-related.

Almost any commercial website needs a way to manage SEO-related options, such as per-page meta tags (title, description and keywords at least).

The standard distribution has a Blog extension built-in. A blog post is, basically, a content asset. I’ve read the extension’s sources and got a little disappointed by the implementation.

PageKit does not really differentiate between content models and “plain” models. There is no way to tell if we’re rendering a single blog post or an index page. So, in PageKit there’s no way to hook into the content handling and persistence mechanisms so that these fields could be edited in the content form.


PageKit is a nice and well-designed CMS. It’s really extensible, it has a built-in marketplace and a user-friendly UI. However, it lacks some things that could turn it into a rock-solid basis for production websites. And I hereby would like to invite everyone into contributing into PageKit. Remember, any contribution is welcome, no matter how small it is!


Now read this

Symfony events and persistence

Despite the fact that ORMs are quite evil, often we cannot escape this burden because the decision about using or not using an ORM was taken by someone else on the team, maybe way before we could affect this decision somehow. Well, ORMs... Continue →