Cockpit – a headless, API-first CMS
Cockpit is a headless Content Management System (CMS), developed by Artur Heinze. The core is written in PHP and it has a permissive license (MIT). “Headless” means: backend for data and content, but no inbuilt frontend for websites.
This article focuses mostly on Cockpit v1. Soon after the rewrite to v2, I left the project.
Toggle table of contents
My role
For multiple years, I helped as a volunteer to move the project forward. I fixed bugs, helped sorting out missing or outdated documentation, reported multiple security issues and wrote many addons.
After a few months, I became moderator in their community/support forum. Moderating was a low effort. The user base is small and – as I observed in many development focused forums – the troll count was immensely low. Mostly I helped explaining (hidden) core concepts or solving weird edge cases. To be honest: helping strangers was one motivation, but solving random code puzzles was the real fun. The forum and issue section became my favorite place for procrastination.
It was an interesting and intense time of my life.
Some numbers
- 1 Frontend written
- 23 Addons, 2 of them compatible with v2
- 51 Pull Requests for v1 (31 merged, 5 open, 15 closed)
- 66 Issues opened for v1
- 13 Pull Requests for v2 (8 merged, 1 open, 4 closed)
- 21 Issues opened for v2
And I’m always astonished, when looking at my forum statistics:
- 636 days visited
- 4 days read time
- 916 topics viewed
- 3.1k posts read
- 28 likes given
- 215 likes received
- 36 topics created
- 467 posts created
- 66 solutions
How Cockpit works
As mentioned, it’s headless. Cockpit focuses on data modeling and providing interfaces to access that data:
- Admin panel: graphical user interface (GUI) for creating collections, modeling and maintaining data
- REST API: access to data sets from outside, secured with API keys
- CLI: many tasks can be done and automated via command line
- as PHP library: access to all modules, functions and data with custom-made applications
The admin panel (backend) can be modified with addons. A frontend can be written in any language, accessing data via REST API. When frontend and backend live on the same server, they can communicate directly via PHP API or even via CLI.
At its’ core, Cockpit speaks JSON – or more specifically: MongoDB. Everything is document-oriented. Coming from SQL, I had to readapt:
- No relations: e. g. renaming a category means changing a string in all documents. This can be automated using the event system to check for changed categories after saving. But without shifting the mental model to a non-relational database, these things were confusing.
- Syntax and logic: applying filters (
$and,$or) instead of trying to translateWHEREclauses.
And – although Cockpit speaks MongoDB – it comes with an abstraction layer (MongoLite) to use SQLite as database. And I like SQLite: no server, no passwords, no sql export before and after changing things in a local development setup – just copy and paste.
Why I chose it
In May 2018, after moving from WordPress to Github Pages (jekyll) with prose.io as UI, I searched again for alternatives. Until then, the term “headless” never crossed my mind. After knowing, what I was looking for, the concept convinced immediately.
Self-hosting and a permissive license were mandatory and I was most skilled in PHP – which left only two options: Cockpit and Directus[1]. Both had Gravatar implemented. I asked for an option to disable it, to respect users’ privacy. A few hours later, Artur committed an update and disabled it completely. Months later, I got an answer from Directus. They never thought about Gravatar being a privacy problem and considered changing it.
Obviously, my decision was long done.
Why I left
From the beginning, I was more interested in the PHP (and the CLI) API, than in the REST API. On top of the headless Cockpit CMS v1, I wrote my own frontend (head) Multiplane. So my usage was unusual, not like intended. But I always cared about the headless paradigm when writing addons.
Over the years, I had a deep understanding of all internals. My ecosystem relied on Cockpit’s configurability and hackability. Then Cockpit grew up. Version 2 was released. It looked nice and I liked many changes. Most of my addons could have been rewritten for compatibility, but Multiplane became incompatible. I really tried to find workarounds, but it was unfixable. My vision of Cockpit didn’t match Artur’s anymore.
For a while, I kept a fork of Cockpit v1 alive – until I had to admit, that years of my work became worthless. Sure, I learnt a lot. And I don’t blame Artur for moving forward and building a stable business model. But it still hurts.
On top of that:
- V2 re-introduced a security issue and multiple accessibility issues, I fixed in v1 already – very annoying.
- Some core addons became proprietary, which was fine in general. But I couldn’t skim git diffs anymore to understand the motivation for some random looking core changes. Also annoying.
- Multilingualism was poorly implemented.
- Accessibility was clearly an after-thought.
In the forum thread about my reasoning for leaving, I go into more (technical) details.
Addons
Some of my addons were used in production for years, some were experimental and unfinished.
- Babel
- Manage translations of addons and modules
- addon for Cockpit CMS v1 and v2
- BetterMarkdown
- Cache, tasks lists and table of contents for markdown conversion
- addon for Cockpit CMS v1
- BlockEditor
- Visual block editor
- draft/experimental
- addon for Cockpit CMS v1
- BootManager
- addon dependency management, module loading order, conditional loading
- draft/experimental
- addon for Cockpit CMS v1
- DashboardGrid
- Custom dashboard with grid
- addon for Cockpit CMS v1
- Feed
- RSS Feeds for collections
- draft/experimental
- addon for Cockpit CMS v1
- FormValidation
- Form validator and form builder
- addon for Cockpit CMS v1
- ImageResize
- Resizes uploaded images automatically to predefined sizes
- addon for Cockpit CMS v1
- Migrate
- Migrate and convert models, data, accounts etc. from Cockpit CMS v1 to v2.
- draft/experimental, never published as official addon
- addon for Cockpit CMS v1 and v2
- ModuleLink
- Field with linked data from modules
- draft/experimental
- addon for Cockpit CMS v1
- MoreOptions
- Utility addon with more options (collection grouping, color picker)
- draft/experimental, mostly superseded by rljUtils addon
- addon for Cockpit CMS v1
- Multiplane addon
- Frontend logic (head) for the headless Cockpit CMS
- addon for Cockpit CMS v1
- MultiplaneDocsMods
- Modifications for Multiplane docs
- simple 2-way bind between markdown files and SQLite database
- addon for Cockpit CMS v1
- phpLiteAdmin
- phpLiteAdmin interface for debugging and data inspection
- addon for Cockpit CMS v1
- rljUtils
- Utility addon with security hardening, cosmetics and helpers
- addon for Cockpit CMS v1
- SelectRequestOptions
- Select field with options based on custom requests
- addon for Cockpit CMS v1
- SheetExport
- Spread sheet export (csv, odt, xls, xlsx)
- draft/experimental
- quickly modified version of the sheet export from my Tables addon
- addon for Cockpit CMS v1
- ShowInMenu
- re-enable the feature to display collections etc. in the system menu
- superseded by rljUtils addon
- addon for Cockpit CMS v1
- SimpleImageFixBlackBackgrounds
- provides a modified SimpleImage library to prevent black backgrounds in transparent images on some systems with a non-bundled PHP-GD version (really nasty bug)
- addon for Cockpit CMS v1
- Tables
- Manage SQL tables with 1:m and m:n relations
- addon for Cockpit CMS v1
- UniqueSlugs
- generates unique url paths (called “slugs”) from page titles
- addon for Cockpit CMS v1
- VideoLinkField
- extract, download and store thumbnails and meta data from videos on YouTube and Vimeo
- addon for Cockpit CMS v1
- WhiteLabel
- Custom logo and custom colors
- addon for Cockpit CMS v1
Other stuff
- Cockpit v1 fork
- Fork of Cockpit CMS v1 (next branch)
- stable release for usage with composer and PHP 8.1
- contains some improvements from v2
- Cockpit scripts repository
- A collection of code snippets and notes to modify Cockpit CMS v1 and v2
- WPMultiplane
- Cockpit CMS v1 and Multiplane implementation as a WordPress plugin
- draft/experimental
- still not sure, if brilliant or utterly stupid
Footnotes
This was before their complete rewrite to node.js. ↩︎