RT Cunningham

My Homegrown CMS – Nginx and PHP, with No Database Server

Homegrown CMS I’ve been working on my homegrown CMS for far longer than I care to remember. Years, not months, weeks or days. I’ve also changed things around more often than I can remember.

It’s barely a CMS (content management system). It’s much closer to a simple website manager. I even gave it a working title of “Website Manager”. I wrote a few articles about it in the past but I’ve long since deleted those articles. They weren’t very informative.

Homegrown CMS – Nginx and PHP

If you can see the thumbnail image above, I did that. Well, kind of. I used Irfanview to combine the Nginx logo with the PHP logo as a panorama image.

I started using WordPress as the blogging platform for all my websites in 2006. It has grown in complexity since then and it’s more or a less a “one size fits all” CMS now.

I started working on my homegrown CMS a few years ago, when I grew tired of hunting for code instructions. The older WordPress Codex and the newer Code Reference sites are a bit difficult to follow for mediocre web developers like me.

One of the software requirements for WordPress, like many competing products, is a database. That means it needs a web server, PHP and the MySQL (or drop-in replacements) to function. My goal is to do everything without the complexity of WordPress and without a database server of any kind. It’s not as hard to do as some web developers would have you believe.

Homegrown CMS – Web Development on Windows 10

I bought the laptop I’m using at the beginning of last month. It took me a few weeks to get around to setting it up for web development.

I didn’t need to use software stacks offered by such products as WinNMP or Winginx. All I needed to do was extract the Windows binaries provided by nginx.org and php.net into their own directories, install the latest Visual C++ Redistributable Package and set up a couple of Windows batch files. Since the start-up batch file leaves a console window open, I used the RunHiddenConsole utility to hide it.

The “start” batch file:

pushd C:\nginx
ECHO Starting PHP FastCGI...
c:\nginx\RunHiddenConsole.exe "C:\php\php-cgi.exe" -b -c "C:\php\php.ini"
ECHO Starting Nginx
start c:\nginx\nginx.exe

The “stop” batch file:

taskkill /f /IM nginx.exe
taskkill /f /IM php-cgi.exe

The PAUSE commands allow me to see what’s going on before they finish executing. Without them, the console windows disappear too fast for me to read the text on them. I’m not using a “restart” batch file. I find it simple enough to run the stop and start batch files in sequence.

Homegrown CMS – Data Storage

I’ve tested storing and retrieving arrays and variables using various PHP functions. I settled on a simple file format. An example is categories like these:

Education and Employment|education-and-employment|1
Entertainment and Recreation|entertainment-and-recreation|2

It’s way simpler to use file, list, explode and file_put_contents than the functions dealing with encoding, serializing and parsing. I’m using field separators (or pipes) and line endings like this:

file = file('/path-to-file.dat');
foreach ($file as $line) {
  list($category_name, $category_slug, $category_id) = explode('|', trim($line);
  do something
  $newfile[] = ... (per line)
file_put_contents('path-to-file.dat', $newfile');

A simple representation of simple code, at least for me.

Homegrown CMS – Resources

Web pages are getting more complex. I have to consider the Open Graph protocol for Facebook and other social networks. I have to consider structured data for Google and other search engines. Regardless of anything else, I have to consider responsive images.

None of these have a direct relationship to my homegrown CMS but I’ll have to consider them when I work on my theme template. If I find it too difficult, I’ll ignore the social network and search engine additions.

I’m currently working on the data storage phase. The next time I write about my homegrown CMS project, I hope I’ll be finished with it. I may or may not use a native commenting system and I may or may not support feeds. Commenting and feed reading aren’t popular with this website anyway.

Update August 24, 2018

I want to mention something without writing another article.

I don’t need a bunch of different images with responsive breakpoints. All I need is a thumbnail image with a width of 150 pixels or less and a full-sized image of 1024 pixels or less. It only takes a second or two to upload two images.

When I want to do so, I can link the thumbnail to the full-sized image. If I’m not mistaken, the Open Graph protocol requires at least 200 pixels in width. I guess I won’t be using that protocol. The responsive CSS for the full-sized image would be like this:

.responsive {
    width: 100%;
    max-width: 100%;
    height: auto;

That’s only to display full-sized images, which I always hide behind a click. That is, when I link to them from the thumbnail images. Yes, my homegrown CMS is going to be simpler than I anticipated.

The original PHP logo is by Colin Viebrock (Download Logos and Icons) [CC BY-SA 4.0 ], via Wikimedia Commons. The combined Nginx/PHP image is by RT Cunningham, with the same Creative Commons license.


RT Cunningham
August 20, 2018
Web Development