We abandoned Wordpress to build our own CMS

We abandoned Wordpress to build our own CMS

This article was originally posted on our Medium blog—check it out for the latest tips and developments in the field!

Earlier in the year, Kontinentalist rebranded to more clearly express our founding mission—to unleash the potential of untapped data about Asia. But it wasn't just an aesthetic change. While our new website is admittedly stunning, the even bigger change lies under the hood. Our developers, Dylan and Rifqi, share more.

Let us travel back in time to when Konti started, as Peiying mentioned in her article on our rebranding. In the early days of 2017–2018, most of what we did at Konti was experimental — I like to call this “The Konti Prototype”.

The BRI story was the first piece that catapulted us into the public eye. But before that, we’d actually had more than 10–15 stories already published!

No alt text provided for this image

The stories were not hardcoded (at least until we started toying with formats that were beyond the content management system’s capabilities). As the title indicates, Wordpress was our Content Management System (CMS) back then.

A short introduction to our CMS

If you have worked with content, chances are you have used some form of CMS. Today, Wordpress still makes up 40 percent of all websites on the Web. So, how different was ours?

There were three key components that made Konti stories possible:

  • Headless CMS
  • The View (aka our website)
  • Content Block Model

First, the head (view) renders content and handles the reading experience. In our case, it was decoupled from the body (CMS) where the story is created and saved. The two communicated via an application programming interface (API).

This separation allowed us to have more control over scalability, performance, and COPE (Create Once, Publish Everywhere) with different distribution channels, such as mobile and web.

I have briefly touched on Headless CMSes in my post here, and I’ll be skipping the View, as it is focuses on the “How”. Perhaps a story for another time.

What is a Content Block?

Today we will be diving into content blocks — the model that lays the foundation of our stories in our CMS.

A content block is piece of specification / structured information that represents a sensible part of the story (e.g., a paragraph).

The eureka moment for using content blocks came while I was breaking down the content of our story — what is the smallest unit of information possible?

No alt text provided for this image

Text, images, embeds, and more — all these are like LEGO blocks. When put together, they transform into the LEGO set of their creator’s vision / intention.

No alt text provided for this image

With our core content model set, rolling out new content was as easy as designing a new Lego block or set —whether that was carousels, image comparisons, maps, or more.

So, our next question was, how could we pimp Wordpress to fit what we wanted for our stories?

How stories are generated using CMS

Wordpress has a feature — Custom Meta Box — that allows us to customise a post’s metadata. However, as we did not want to invest too much time into customising Wordpress, we used a plugin — ACF — that helped implement and supercharge that feature out of the box.

Let’s use our oldest story — “Dam if you do, dam if you don’t” — to visualise how we generated stories then. For the bulk of a story, a writer creates and orders the story content:

No alt text provided for this image

Together with the API, the View ties up these ends and renders the final story that you see.

No alt text provided for this image

Image caption: story_content and story_references contain blocks of content

No alt text provided for this image

Image caption: the different blocks of a story

And that’s it! Writers now have more types of content and control over the flow of their content without ever touching the code themselves.

But was this the end for our CMS?

At that juncture, the CMS was enough for us. Konti was pretty much all set to ship stories out to our audiences — people who gave a dam (pun intended) about the environment.

Talking about the BRI has been a goal for us from day one. When we started preparing for the BRI story, there were many new elements at play — scrollytelling, maps, charts, and more.

Given the amount of time it takes to understand each of these data storytelling tools’ intricacies to the level needed to design Konti’s content model, I decided to just hardcode it first.

No alt text provided for this image

At Konti, we care about bridging gaps in Asia's knowledge, culture, and other areas. That bridge, to us, is our content.

No alt text provided for this image

Different gaps call for different types of bridge. To nail down the pillars of the bridges, we needed a wider selection of better hammers (our technical tools).

Our writers needed a better array of tools in their arsenals, so that their tools don’t constrain their creativity.

The Problem

With that in mind, we set out to expand the types of content blocks we have. But as we tried to further customise Wordpress and the ACF plugin, we ran into many roadblocks.

Limited control over data structure and content type

The plugin was great for organising content, but it was limited to basic text and link content type.

For example, story_references contains a set of text blocks; hence, it should technically share the same data model as “Text Block”. But instead the logic had to be duplicated.

No alt text provided for this image

To resolve that, we would have to customise the plugin’s core — which would have led to a host of scalability and maintenance issues.

Experiencing the Medium editor

Drawing inspiration from Medium, we wanted a similar experience, in which writers start with a blank canvas and add content on demand.

No alt text provided for this image

This was before Wordpress v5.0 — the Gutenberg Wordpress Editor had not been released yet. Trying to build a custom editor on top of Wordpress would have, again, led to scalability issues.

Scaling

One of the biggest challenges of a product in a growing startup is figuring out how to scale as your products and team grow.

Initially, when we started to build our website, the requirements weren’t as complex as they are now. As more features and fixes kept coming in, we kept patching here and there with Wordpress. Five features wouldn’t hurt, yes, but if we waited until we got tens or hundreds of features to amend, we’d be sunk.

For the developers among us: Can you imagine how spaghetti that would make your typical Wordpress plugins, let alone the main data structure? Sure, Wordpress could do the job — but we’d have to deal with these pain points:

  • Wordpress’s database and code structure are specifically built for a general CMS. When our business models are getting more niche, depending on a general CMS framework isn’t a good idea for scaling up.
  • A lone-ranger programmer could build the product and apply changes quickly without worrying about others reading the code. But as our team grew, several devs needed to share their code. Having our own framework would help the product development work tremendously and avoid spaghetti code.
  • Wordpress lets us develop plugins, and it provides native functions to help us with coding plugins. Wordpress’s default way of developing plugins is to communicate with the database as much as possible and store one’s settings in the database, which is not a good idea. This helps with building plugins for general use, but it wasn’t good practice for us. Worse, Wordpress doesn’t come with a database migration feature, making migration more painful with each new story.

Performance

Now, let’s take a look at this entity relationship diagram (ERD) structure:

No alt text provided for this image

This is Wordpress’s database. Functional, neat, and sweet for general CMS purpose, right?

Now imagine you had different types of categories, and you wanted to show posts that appear under certain category types.

In Wordpress, the first step you’d need would be to store the “category type” in the wp_terms and store the categories of the type that you had stored earlier inwp_term_taxonomy. You’d then make the relation with posts in wp_term_relationships .

Now, when you want to show the posts, you’ll need to find the terms, find the taxonomy, and find the relation to the posts. And there’s nothing wrong with this; again, Wordpress is a general-use CMS. It lets people store literally anything and build anything based off wp_termsitself.

But in our case, we didn’t need to create dozens of category types; we’d already figured out our category types and what exactly to build. This meant that following Wordpress’s system didn’t make sense — we could cut the complexity of the query bureaucracy!

Another performance issue that we spotlighted in Wordpress was plugin performance. Having tons of plugins in Wordpress affects your site load, although having good written plugins might be able to solve that. Again, this relates to the scaling issue discussed earlier.

Security

Having Wordpress as our main website platform made us dependent on Wordpress’s security. Since Wordpress still makes up 40 percent of all websites in the Web, darkseekers are familiar with vulnerabilities of Wordpress. It’s the CMS platform that gets hacked most often; here’s why:

  • Out-of-date core software
  • Supply chain attacks
  • Out-of-date plugins or themes

At the end of the day, we didn’t want our product to have to rely on a platform for our security

The Solution

Create our own structure

Yes, this is the main solution to all the problems we have discussed earlier.

When we were making our own CMS structure, we focused on our pain points and considered two questions: What framework should we use, and how should we structure it?

After quite a bit of research, we decided to use Laravel as our main framework for our backend. We kept Nuxt for our main website frontend (Chelone), VueJS for our CMS frontend platform (Caraspace) and created our very own design system based off VueJS (Scute)!

This is roughly what happens under the hood:

No alt text provided for this image

How our apps communicate

Now, with the help of Scute, we have a design system that we can base multiple platforms off, and this automatically make our designs consistent. (Sweet!)

Previously, we relied on Wordpress as our CMS. Now, our very own CMS structure, Caraspace, helps us build the niche requirements of our CMS— such as a dream story editor to help our writers be productive.

Solving scaling issues

Now that we use a framework that is developer-friendly, we are free to structure how we want to scale. When it comes to scaling, we focused on two questions:

  • How might we scale such that we have a solid structure for rapidly developing future features?
  • How might we scale that our app can be easily readable for our dev team members and be consistent in code?

We then dove into design patterns and software engineer architecture to find the approach for us. We found several patterns, design principles, and architectures that fit with our use case, and we use these to solve scalability and consistency issues:

  • MVC Architectural Pattern
  • Service Pattern
  • Repository Pattern
  • IoC (Inversion of Control) Principle
  • Adapter Pattern
  • Factory Pattern

With all these solutions, our product should now scale up much more painlessly than it would’ve in Wordpress. So far, it’s been doing really well, helping us to easily develop our app with more scalability and consistency.

Speed and Performance

Remember when we brought up performance issues? Now that we have more control over things, we built our own ERD structure. We no longer need to go through the bureaucracy of unnecessary database queries whenever we fetch our stories.

What’s next?

Kura-kura (our version name for our main products) marks the end of our days of uncertainty. It’s given us a solid carapace (read: shell) to home our stories under.

We are still constantly improving our product and backtesting for user experience, whether that’s with our writers or readers. I am stoked about the new features to come. One of them is building our own editor , so that our writers can write stories with our new structure more seamlessly.

Just imagine a huge vehicle hauling all the components of a bridge and laying them where they should be — that’s what a good editor should do.

No alt text provided for this image

ed for more Stay tun




要查看或添加评论,请登录

Kontinentalist的更多文章