A new CMS is born (Jan 18th, 2019)

A new CMS is born
----------------------------
January 18th, 2019


I feel I need to explain a little why I choose to do it this way. I mean, there are plenty of CMS solutions out there, why build yet another from scratch and with all the risks involved in regard to compatibility and security issues, bugs etc. There are 2 main reasons and I'll try to describe them as quick as possible.

The first reason is that I’m the kind of guy who likes building things he will find uses for them later, and sometimes even because he knows he will need them :). Not entirely practical, especially when you think that many things get started, less get to be built eventually. This way I come clean from the start and simply acknowledge the fact that I like the ideea o building a new technology instead of using an existing one because this is the way I learn and understand technical things. It is hard work indeed and is not necessary everytime (and I don't do it necessarily each time I have an opportunity).

The second reason is that I really don't like existing CMS solutions, perhaps because I come from a different background. I developed desktop applications for years and never bothered with PHP and JS until a few years back when I understood the importance of modern browsers. So of course I used Joomla, Wordpress and other frameworks to get away from developing web sites from scratch but always found them troublesome when I had to do integration, which is an important part of my business. Dealing with changing APIs from one version to another, MVC style of coding which in my opinion doesn't proove to be in any way superior, poor support for the code in documentation or comments always led to occasional frustrations when I needed to find quick solutions to problems I didn't need in the first place. Now, there is a lot more to this discussions and I don't think I need to get in too many details, is sufficient to say that we realized at some point that our business was not website design specifically and we did a pretty poor job when it came to this anyway. On the other hand, we can't escape web development in general so we (better said I) decided to only support our own .quark technology instead of any other third party framework in general, and CMS framework in particular, until maybe a better reason to do otherwise will appear. If we need a CMS, then it will have to run on top of .quark and also provide some basic functionality on its own, we'll make it very light and fast, write as few lines of code as possible, avoid jQuery and other js frameworks that would only slow down page loading and create possible vulnerabilities and so on.

In conclusion, bitnova site had to wait for a third installment until it was doable in this manner. We had a few instances in the past based on Joomla and were not too happy with them. And because time has this bad habbit of passing by, we are actually one year overdue to actually develop this CMS for bitnova site and other self-financed projects. So I thought I would make the most of it and start working on the CMS and publish a set of how-to articles at the same time. Therefore, at the moment of writing this article, bitnova is nothing but an "under construction" page with a link to this text file. Last but not least important, I will publish the CMS as open source under a to be reviewed license (I'll decide that a bit later).

Before going into tech bits, let's enumerate the purposes I need this CMS to serve:

1. I want to use it as a blog platform for my "Hack N' Build" corner, a collection of how-to articles, algorithms, old hardware revival, electronics and so on;
2. It needs to offer a decent functionality as a news and presentation site for my company;
3. To be a starting point for the e-commerce front UI solution I'm working on at the moment, operate on top of .quark framework and allow web apps from that side to generate content to be displayed inside the CMS.

Now we'll start talking about technology more and less about the reasons and I'll begin be restating the criteria I want to keep in mind during the entire development of .quarkCMS framework:

1. It should be very light, under one megabyte (we’ll exclude here template files, icons and other graphical items yet they should not take much space either). In its first few iterations, it should allow a simple management of blog articles, such as this one;
2. The database should be optional at best, a use of a cache functionality of some sort would be much preferred. It could be a plugin system where the actual content would be served by a default or custom data layer, depending on each installation;
3. No jQuery. It may sound plainly stupid for many web developers but I have yet to find the irrefutable advantage of using it other than the fact that allows a quick AJAX (solved in .quark) and possibility of element selection on a variety of attribute types (which is also solved when you decide you will only access through ids);
4. When so desired, it should be able to work on top of .quarkOS as a service and take advantage of its functionality, such as communication with other apps, use of built-in AJAX capability, forms etc;
5. Allow the development and integration of components for displaying specific content (such as product pages on an e-commerce site).

What wasn’t entirely clear was if the CMS should be based on menus as a central mechanism for state definition (as Joomla does) or if it should rely on a chronological order of articles instead and menus added just to ease the navigation (like they are used in Wordpress). It took me some time to realize that is best to leave this issue to be decided at a later date and just focus on a quick basic functionality as until now, the CMS was still just one empty file named cms.php, just to have something in the git repository. And it just so happens I had just the thing, a very small set of functions I wrote back in 2009 for a very basic CMS functionality, collectively called "bitSimpleCMS", so by copying them into quarkCMS I could start working on something immediately. 

I wrote these functions in an era (2009) when I didn't have a particular interest in php and didn't consider it to be either desirable or efficient as a language. So I'll make a breakdown of them below in order to set a reference point for the changes that will be performed in the future sections of this blog (therefore is more like a "how it was done" for the moment). The framework has 5 important files in the website folder: content_vars.php, content_funcs.php, content.xml, index.php and template.php.


1. content_vars.php
----------------------

This file contains declarations for the application variables that will be used throughout the script. These are all global variables, at that time I was not very interested in using objects or passing variable and references to functions instead of simply using them as global. There are variables such as $site_title or $menu_items declared and a small fragment of coude that loads content.xml (described below).


2. content_funcs.php
----------------------

There are four functions in this file: GenerateLangIcons(), GenerateMenu(), GenerateTitle(), GenerateContent(). No arguments are passed to them, they are supposed to "know" what to do based on the global variables. For instance the GenerateMenu() function looks something like this:

    function GenerateMenu()
    {
	global $menu_items;
	global $idx_current_lang;
	
	for ($i = 0; $i < count($menu_items[$idx_current_lang]); $i++)
	{
	    echo '<a class="menu_item" href="index.php?content_id='.$i.'&lang_id='.$idx_current_lang.'"><p>'.$menu_items[$idx_current_lang][$i].'</p></a>';
	}
    }
    
As you can see, half of the function is actually made of global declarations.


3. content.xml
----------------------

The content definition file is where you add new menu items and links to the actual content files. These definitions are read each time the site is loaded or refreshed. The menu is a single 

<content>
    <!-- define languages that will be used -->
    <lang>
        <idx> path/to/language/icon </idx>
        <href> path/to/the/content/in/this/language </href>
    </lang>
    
	.
	declare other languages if necessary
	.

    <!-- set meta fields -->    
    <title> the name of the site </title>
    <description> site description in a few words as possible </description>
    <keywords> words and terms separated by a comma </keywords>
    <author> site author </author>

    <!-- declare menu items -->    
    <item>
	<menu_item> menu item text in the 1st language </menu_item>
	<menu_item> menu item text translation in 2nd lang </menu_item>
	<href> file name or path of the content </href>
    </item>

	.
	continue with other menu items
	.    
    
    <idx_current_page>0</idx_current_page> <!-- set the home page index -->
    <idx_current_lang>0</idx_current_lang> <!-- set the default language -->
    
</content>


4. index.php
----------------------

The index file includes the content_vars and content_funcs files, does the 

<?php
	include "content_vars.php";
	include "content_funcs.php";
?>

<html>
    <head>
	<title><?php echo $site_title;?></title>
	<meta name="description" content="<?php echo $site_description;?>"/>
	<meta name="keywords" content="<?php echo $site_keywords;?>"/>
	<meta name="author" content="<?php echo $site_author;?>"/>
    </head>
    
    <body>
	
	<?php 
	    $content_id = -1;
	    $lang_id = -1;
	    
	    $content_id = $_GET["content_id"];
	    $lang_id = $_GET["lang_id"];
	    
	    if ($content_id > -1) $idx_current_page = $content_id;
	    if ($lang_id > -1) $idx_current_lang = $lang_id;
	    
	    include "template.html";
	?>
    </body>
</html>


5. template.php
----------------------

The template file, like in most other cms frameworks, holds the "display structure". This is where you define areas for particular functions you may want to have in your 
site.

<link rel="stylesheet" href="css/style.css" type="text/css"/>

<div align="center">
    <div class="wrapper">
        <div class="page">
            <div class="menu"><?php GenerateMenu(); ?></div>
            <div class="lang"><?php GenerateLangIcons(); ?></div>
            <div class="title"><?php GenerateTitle(); ?></div>
            <div class="content"><?php GenerateContent(); ?></div>
        </div>

	<div class="poweredby"><a href="http://www.bitnova.ro" target="_blank"><img src="img/poweredby.png"/></a></div>           
    </div>
</div>


In the follow-up article I'll explain how to change the code structure in an object based layout with only minimal changes and how to write a singleton in PHP.
Script executed in: ms
Page rendered in: ms
quarkCMS