A Basic Content Management System which is fully customizable in its looks and content properties. Intended to be used mainly for small portfolio websites, it is based on minimalism and simplicity.


I wrote this small CMS System, since i could not find one which would fit my needs. Wordpress and Drupal are simply to big and complicated for a small portfolio page. Others were not fully customizable or were simply not working. So i wrote my own cms. Instead of using a Backend System, it creates its content out of its folder structure. This site is powered by ApoCms.
Download it here if you like: apocms_1.5.zip

It is for free. Use it and/or modfiy it. But please give me a notice if you are using it.


  • A fully customizable template system
  • Simple switching of templates
  • Utilizes XML Database
  • Customizable database fields
  • Thumbnail caching and creation
  • Clean Urls
  • No sql database needed
  • Requires only PHP 5

Figure 1: default template


  • Unzip the folder into your webdirectory
  • Edit the file system/config.php. Most importantly change the BASE_PATH to point to your urls sub directory (leave it on '/' if its the base directory)
  • change the permission of the cache folder to 755 or 775.
  • If you want to use clean URLs, rename the htaccess.txt to .htaccess and change the Setting CLEAN_URLS to true

File Structure

Since the system uses no backend interface, all the content is organized in the subfolders of the '/content' directory. Each subfolder creates a top-level-page. The folder must contain a similar named .xml file (i.e.: /content/home contains the home.xml). Images and Attachments go in the same folder.
If you want to create a top-level-page with multiple subpages, all these subpages go into subfolders, having a number and underscore as prefix. Each of them contains an .xml file named like the folder name without the prefix. For Example '/content/work/02_project' contains the file 'project.xml' and is a subpage of '/content/work/work.xml'.

The '/template' directory contains subfolders with the template files. You define the template file for each page in its xml file. In Figure 1 you see two different template folders named 'default' and 'portfolio'.

The folder '/cache' contains all the thumbnail images. These images get dynamicly created, so you can safely delete its content. You need to put the cache folder's permissions on writeable (chmod 755 or 775 on some servers). If you reupload an image with the same name within the same content folder, you need to delete the created thumbnails in the cache folder to show the new picture.

Figure 2: file structure

Figure 3: config file

Xml Structure

To figure out the xml structure, take a look at the example content supplied in the source package. There are 3 basic types of content xml files: single, list and subpage. types are definied by the 'type' attribute. Each Xml file must only contain one 'page', but can contain multiple 'element' in the 'content' section.

Required fields:
  • single: title, template, content-template, type, content
  • list: title, template, content-template, subpage-template, list-template, type, content
  • subpage: title, content-template, type, content

Html is allowed in elements of type 'html' and if the config setting $settings['SYSTEM']['ALLOW_HTML'] is true. You need to replace all the 〈 〉 with ﹛﹜ though.

Figure 4: xml content file

Template System

You have to supply two template files for each page: the 'template' and 'template-content' file. The template file formats the whole page, the template-content file formats one content element. Subpages need only the 'template-content' attribute, since they take their template file from the top-level-page's 'subpage-template' attribute.

You can get any xml attribute within the template files by typing $this['attribute_name']. Check the default template folder for examples.

Some Additional Template Explanations:
  • to print out all the template vars put 'echo printArray($this->getVars());'' somewhere
  • the content uses the xml defined 'content-template' file to create its elements. fetch and print them with foreach($this['content'] as $element) echo $element['html'];
  • the same goes for subpages, if they are existent: 'foreach($this['subpages'] as $subpage) echo $subpage['html']; they use the xml defined 'list-template' file.

Other available and useful functions are:
  • $this->getPageList(), gives you an array with all the top pages, ordered by directory name
  • pageLink($this['slug'],$this['subpage']) or pageLink($this['slug']) links you to a certain page. Slug is the top level directory name, subpage the subdirectory name.
  • getTemplateDir() gives you the directory of the template folder.
  • getRelTemplateDir() should only be used for the includes of other html folder. i.e. header and footer.
  • $this->getImage($image,500,150) creates a thumbnail with 500x150 size $image in the cache folder of and returns its url.
  • $this->getImage($image) gives you the original sized image. you can only link to images in the content folder.
  • Important: dont forget the echo in front of all commands and vars or you will see nothing. i.e. 'echo pageLink($link);'

Figure 5: template file

Questions and Suggestions

If you have any questions, suggestions or problems or you need help to set ApoCms up, don't hesitate to ask me: lutz[.]farseer.de.