The simplest CMS

Olaf DoschkeSoftware Developer
Self-employed fullstack developer with backend preferences.
What's really the simplest Content Management System? No CMS at all, a static homepage, isn't it? This only needs a little HTML knowledge and even that can be minimzed by using an HTML editor.

There are several pros: static HTML has no additional costs in preloading server side code or javascript frameworks, there also is no security risk, the vulnerability of a static HTML site is the FTP server of the host, and things like that. If you use HTML forms that introduces new risks, but that's a separate topic.

The big minus with static HTML pages is that you repeat a lot. each HTML file will need to have the navigation menu for the typical site layout with navigation and page details. So if you introduce a new nav menu item you have to change all the HTML pages you already have. Cumbersome, if not impossible for a large site.

In the past (the 1990s) we had (i)frames to load separate HTML files and put them in a frame layout. That enabled you to have a menu.html for all pages and a detail.html for the page details, the core page. But iframes pose a security risk, mainly that a whole site is loaded into an iframe. But that's also the topic of a separate article, so simply trust me iframes are a bad idea.

We have another simple way to combine content of separate files into a single html page to avoid repeating yourself: SSI

The simplest structure a general HTML page of this simplest CMS can be as follows:
<!--#include file="header.html" -->
                      <!--#include file="navigation.html" -->
                      <!--#include file="detail.html" -->
                      <!--#include file="footer.html" -->

Open in new window

That would need to go into a shtml file, normally called index.shtml, as the home page of your site. The s in shtml is not for secure HTML, but HTML processing SSI - server side includes. The #include comment is one of the SSI "commands" that will then include/load and put together the whole page from its single parts. index.shtml would include index.html or home.html instead of detail.html and next pages could be page1.shtml including page1.html, page2.shtml including page2.html and so on.

The only thing you need to change is the line loading "detail.html"; that would differ per shtml file. Now you still have to copy this code for each page of your site, but it's nothing you will need to change often, and it's really just the file composition. You don't even need a database this way; each page detail part will simply be its own file and so the file system is your database. 

URL Rewriting can round this up and translate each to A very simple rule, and you have user- and search engine-friendly addresses for your pages.

If SSI doesn't work on your webspace but PHP is available, there is a simple thing to use instead: The PHP include function. The core file for this CMS system then simply looks like this:


Open in new window

This should be saved as controller.php. It's a very simple controller of the Model–view–controller (MVC) design pattern -- again, another article -- but you can read up on that concept at The important part is, every link to your site and every internal link now will go through the controller.php as the main script. No matter if you think of the MVC concept or not, this makes it a central place to expand templating all pages, tracking all page views, etc.

And this change from SSI/shtml to PHP also has two other advantages. First you can also write HTML in a PHP file, so you don't lose anything in comparison with SSI. What you gain is, that each file for your page parts can have further PHP functionality; and also, the $__GET[]'detail'] means you now don't need many shtml files like home.shtml, page1.shtml, page2.shtml but instead make the page detail name a parameter of the controller.php you call by The third PHP line now includes the detail file given as parameter. An URL rewrite rule again can make sure you stay with the simple user/SEO friendly URLs by translating each to

For security reasons the PHP code should be a little bit expanded to verify the validity of the $_GET[]'detail'] input by the general rule that each user input can't be trusted, meaning you could test to see if the detail parameter is the name of an existing file. Also 'controller' shouldn't be accepted as value of $_GET[]'detail'].

But that's about it, no database, no need to know any programming language, no installation, no keeping up-to-date with the CMS and its security updates. Just an HTML editor and FTP client, and you can start your own website.

Of course it's a simple CMS, no community, no users and roles, no template system, no real "content management" but your writing of the detail html files, but that's probably fine for a personal jump page that you can make more individual than some social network account.

The header.hml/php can be as simple as...
<!doctype html>
                      <title>Your website</title>

Open in new window

...and you can load your site CSS here, too, of course.

The footer can be as simple as...

Open in new window

...and close the main tags opened in the header.

The navigation could be a simple nav section like:
                        <a href="html.shtml">HTML</a> |
                        <a href="css.shtml">CSS</a> |
                        <a href="js.shtml">JavaScript</a> |
                        <a href="jquery.shtml">jQuery</a>

Open in new window

or as PHP version:

                        <a href="controller.php?detail=html">HTML</a> |
                        <a href="controller.php?detail=css">CSS</a> |
                        <a href="controller.php?detail=js">JavaScript</a> |
                        <a href="controller.php?detail=jquery">jQuery</a>

Open in new window

or in both cases with URL rewriting:

                        <a href="/html/">HTML</a> |
                        <a href="/css/">CSS</a> |
                        <a href="/js/">JavaScript</a> |
                        <a href="/jquery/">jQuery</a>

Open in new window

You add nav menu items here and only here once, and the navigation will show up on all pages already written.

The detail of course would be the page specific html so I haven't given an example for that. It can be anything you want. The advantage is that you really can concentrate on writing the pure content in this part of the page and site.

The little downside I see is that this construct takes apart the opening and closing tags of html and body in the header and footer, so an HTML editor would alarm on that for each single file. To check the overall validity of the html of the whole pages you may use validation services or save the page source code after your webserver has done the SSI/PHP includes.

You can expand the idea and introduce further sections for the mostly static or variable parts of your page -- an ads section, a login, whatever -- to introduce the features of a more advanced CMS that would implement the management of the content.
Olaf DoschkeSoftware Developer
Self-employed fullstack developer with backend preferences.

Comments (2)

Expert of the Year 2014
Top Expert 2014

So basically this article has nothing to do with a CMS at all and should be called Simple Routing in PHP but even then it's creating more work than just using the page.php name to start with
Olaf DoschkeSoftware Developer


Well, Gary. The first sentence of my article says.

What's really the simplest Content Management System? No CMS at all, a static homepage, isn't it?
That already explains the title and if you are disappointed about that, still continue to read and don't want to understand the technique, then finally state how you dislike this article, it's your personal right.

Now what do you expect to happen?

Bye, Olaf.

Have a question about something in this article? You can receive help directly from the article author. Sign up for a free trial to get started.