🏗️Why I Built My Own CMS - Lesson Learned


Web Development

As my web hosting was expiring, and I desired to switch to a VPS, a situation arose while I was managing the transfer of a personal website. Since my entire site was built on October CMS, I sought a different platform. Despite my extensive experience with WordPress, on which the previous version of the site had also been built, I yearned for something simpler and a fresh start for the site. WordPress is a robust CMS with many features that I find unnecessary in its default state. This led me to reminisce about a project I had undertaken for a client, where I had created a straightforward editing environment for drink menus using PHP. This sparked my interest in attempting to develop a simple custom CMS that would encompass only the essentials for a small blog. Little did I know the extent of the challenge I was embarking upon and the array of obstacles that would need to be overcome. Nevertheless, I was undeterred by these potential hurdles and eagerly embraced the challenge.

Uploaded Image

Coding? No! Name first.​

​First thing of all projects is a suitable name. Yeah why not. Why not spend the whole day coming up with a name and design and no coding. I’ve come up with combination of Synth (I was just listening to synthwave music) and Shore (as a home or bay or something that was close to home). Great! SynthShore CMS. Now to coding. NO! Logo first.

Uploaded Image

​Now to coding! I successfully implemented/transferred the login logic, establishing a database to store login credentials, and creating a basic dashboard for testing purposes.

Uploaded Image

​I then outlined the key components required for a functional blog:

​​A section to display articles.

The capability to create and edit articles.

A space to input site information (such as title, description, favicon...)

​This appeared to be a straightforward task. Thus, I proceeded to tackle the article editor. This led me to contemplate the necessary elements for such an editor, resulting in the following list:

​Article title.

Slug (part or the url after ondrejmichal.cz/article/....).


Excerpt for article SEO description and for articles listing.

Featured image.

WYSIWYG content editor.

​All of this data needed to be stored within the site's database, housed in a dedicated articles table. The coding journey commenced, with elements like "article title," "slug," and "excerpt" presenting relatively simple solutions involving input and initial evaluation (needed to check if the article with same slug exists, if so, the random sequence of characters appears at the end of the slug). However, the WYSIWYG editor proved to be more intricate. Initially, I considered utilizing TinyMCE, but then I opted for a more ambitious approach and also make my self a chalenge - creating a custom editor from scratch, tailored to my specific needs. In the end, the WYSIWYG editor turned out to be the feature that took the most time and had the most errors during development.

Uploaded Image

​I explored the various options and at the end I focused on the "content editable" attribute in the HTML documentation. In the end I used this atribute on the div and all of the wysiwyg function using Javascript. While "execCommand" was my original choice for basic editing such as "bold" and "italic", I recognize its potential obsolescence in JavaScript documentation. I'm going to replace it with a custom function in the future when browser will make this feature deprecated. More complex functions, such as adding links, changing paragraph styles, or inserting images, required the creation of custom functions and logic using Javascript. Often this involved managing cursor position and content selection.​ However, It was a challenge, cause you need, for example when changing format of the paragraph to heading, find the parent tag of the selection and then change it to the other tag. But the problem was verifying that you chose the right parent. In the first attempt I falsely selected the parent tag, which was a <div> attribute with editable content, the function changed it to <p> tags. 😅 It's probably fair to say that I wanted to and at the end did write everything in Vanilla Javascript. Crazy, I know. 

<button class="tool-items fa fa-bold" onclick="document.execCommand('bold', false, '');"></button>

Regarding image insertion, authors upload images from their computers. The logic subsequently saves these images under modified filenames within a designated site folder, generating a link that is then incorporated into the editor for author to view. Most of the functions is using the XMLHttpRequest() so there is no page reloads. To manage uploaded images, I made a dedicated page with listing of all uploaded images. Rather than introducing a individual image deletion option, I took an alternative approach more aligned with my preferences. When querying the images for this listing, I concurrently check if they are referenced in any articles. If not, the image is dimmed. With a single command, I can remove all unused images. The same methodology applies to the "Featured Image," which file path is stored in a Articles table.

Another challenge was the categorization system. I aimed to enable articles to be assigned to specific categories, facilitating the creation of category pages on the frontend. To address this, I made a separate page exclusively for adding and deleting categories. Within the editor, I implemented a section allowing authors to select an appropriate category for each article. Categories are stored in a dedicated table, with only the category ID linked to each article. Deleting a category results in all associated articles being automatically categorized as "Uncategorized."

Another intention was to make a way to allow articles to be saved as drafts, enabling authors to create and develop concepts before deciding to publish. Additionally, I aimed to offer the functionality to transition an already published article back to a draft status, moving it to the conceptual stage. To achieve this, I implemented a new column in the article table named "Published," which holds a boolean value. This column facilitates the distinction between published articles and those in the conceptual phase.​​ On the Frontend I just  querying articles with "WHERE Published = 1"

The frontend implementation is straightforward, involving database queries, styling, configuring slug permalinks using .htaccess, and crafting the overall page design. I have homepage with short information, page for articles queries /articles/ which have option to navigate to specific category. If something doesn't exist (like if querying no existing article, page or category) web will redirect to 404page. In terms of design, I aimed for a simple and minimalistic aesthetic, drawing inspiration from the following websites: Alex Pate Lee Robinson and Conor Dewey

Not great, not terrible​

​While this CMS prototype performs adequately, it is not without its limitations. Many aspects are still incomplete, the code is a mess, and opportunities for improvement definitely remain. However, this CMS is mainly intended for my personal use and mostly as a learning project. I must say that as a project for learning purposes, creating your own CMS is great. You get experience in frontend, backend logic and do something more complex that “make a Wordpress site”. This simple CMS took me about 14 days as a side project outside of my full time work.

Uploaded Image

​What now? Probably make something similiar, but take it more seriously, make code more clean, use javascript framework (SolidJS looks interesting) and probably try headless (generator of static pages without database), which is great for simple blog sites. 

What's next for this blog? I've been neglecting my blog while concentrating on projects and my full-time job at the faculty. I'd like to create more posts primarily about web development, with a focus on Frontend, useful tips and tools I use. Which will be also educational for myselft. Best way to learn is to teach others. I still consider myself a junior/medior in programming, given that I was/am more of a seasonal programmer and because I'm a jack of all trades (programming, design, UI, online marketing, photography, data analysis). Additionally, I'm eager to explore game development, as I'm quite passionate about games myself and have numerous ideas for story-driven games.

This website is using SynthShore CMS