Making a basic theme

The first step of making a theme is creating a design. The second step is slicing this into basic HTML - CSS. This tutorial doesn't give information about these steps but assumes you did them both. The slice of day 02:

Day 02 theme

The easiest way to start making a theme is copying the triton theme folder located in fork_folder/frontend/themes. We have to rename the copied theme folder to the name you want to see in the backend, which is in this example "daytwo". This will make sure we're able to install the theme in the backend. See Theme contents.


The next thing you should do is open up your info.xml file. It's located directly in the theme folder and contains some basic information about the theme, your templates and your positions. You should change the content of the name tag, the description tag, and the author tag. If you want to use special characters in the description, don't forget to add CDATA tags ("<![CDATA[" and "]]>"). These tags make sure the text data won't be parsed by the XML parser (more info about CDATA). If you want to give the tumbnail file another name, you can also change the thumbnail tag.

Every theme contains templates which contain positions. Every theme needs at least a Default.html.twig template. Most themes also contain a home.html.twig and can contain as much templates as you want to. In day two we need two templates: home.html.twig: a two column layout for the home and blog page and Default.html.twig: a three column layout for the other pages. These layouts contain positions. The footer and header template don't need to be included in the info.xml since they'll be loaded from the home and default templates.

A position is a place where a user can put modules, widgets or editor content. The Home.html.twig has two positions, since there are two columns to be filled. We call them main and right. The Default.html.twig contains three positions: left, main and right. Try to use names that describe the position like top, left, right, main,... When you change a fork theme, it tries to reallocate all the blocks to positions with the same name, for example: Fork will try to put the blog index in the main position of the blog page.

In the picture you see the main templates: home and in it header. The footer isn't visible but is also included in the home template. The grey parts are the positions.


Templates also contain a format tag. They are a visual representation of the template, to be used in the pages-module. You can see this representation when you edit or create a page in the cms backend.

To add a row, you'll need square brackets: [ ]. The positions are added with the position name. All rows and positions are separated by comma's. If you want to add an empty place, you can add a slash: /. In our example, these formats are really basic. Just one row with two (home) and three (default) columns. The home format looks like: [left,main,main,right] and the default format looks like [main,main,right]. In this example, main is used two times side by side. In the pages-module, the width of the main block will be two times the width of the right (and left) block.

The xml:

<?xml version="1.0" encoding="UTF-8"?>
			DAY 02 is a grid-based sci-fi/space theme for Fork CMS.
			It includes styles for: main navigation, slideshow, blog (category, archives, comments, comment form, widgets), contact form and search.
			<name>Wouter Sioen</name>
	<metanavigation supported="false" />
		<template label="Default" path="Core/Layout/Templates/default.html.twig">
				<position name="main" />
				<position name="left" />
				<position name="right" />
		<template label="Home" path="Core/Layout/Templates/home.html.twig">
				<position name="main" />
				<position name="right" />

It's also worth mentioning it's possible to put a default widget or module in a position. In the next example, we have a top position containing the search form widget. This isn't necessary in the daytwo info.xml.

<position name="top" >
		<widget module="search" action="form" />

If the info.xml isn't a valid XML file, your theme won't work and won't show up in the themes install page! If you haven't installed your theme yet, now is the right time, even though the frontend will contain some strange stuff caused by non-existing positions.

The templates

The next step is updating the copied templates (theme_folder/Core/Layout/Templates) to make sure they contain the right positions. You can delete the positions that don't exist, add new positions or change the names of the positions in the file to the names of the positions in your info.xml. You'll probably need to remove and add some html tags to make sure the structure of your template is the same as the structure of your sliced html without the content. For the day two example, some divs where added (divs with id mainColumn, column, class sidebar,..) and a lot of overhead was removed.


For adding positions you need to use for tags. This example shows the position Main with a lot of comments to explain how it works. Comments are put in between the {* and *} tags. Multiline comments are allowed.

{% for main in positions.main %}
    {% if main.isEditor %}
        <article class="article content">
            {{ main.html|raw }}
    {% elseif main.html %}
        {{ main.html|raw }}
    {% endif %}
{% endfor %}

More info about template syntax can be found in the twig documentation.


A lot of variables can use modifiers. They modify a variable and are used with the syntax {$variable|modifier}. Some modifiers also need extra parameters. For a list of all modifiers check the cheat sheet. The modifier you'll need most in the main templates is the ucfirst modifier. This modifier makes sure a label or string starts with a capital letter.

When this is done, you shouldn't see loops and if tags appearing in the frontend anymore. If they still appear, there's probably a position in your template with a wrong name. Don't forget to create all needed templates and to edit or create footer.html.twig and header.html.twig if you use them.

More variables

Note: Don't forget to add the {{ siteHTMLHead|raw }}, {{ siteHTMLStartOfBody|raw }} and {{ siteHTMLEndOfBody|raw }}.

They make you able to add extra scripts with the backend. In the settings tab you'll have the textboxes '

script(s)' and 'End of script(s)'. Scripts like google analytics can be pasted there. These script(s) will be added where the siteHTMLHeader/siteHTMLStartOfBody/siteHTMLEndOfBody tag is placed, so place it right before the start/end of the and tag.
  {# Site wide HTML in the head tag #}
  {{ siteHTMLHead|raw }}

    {# Site wide HTML just after the body tag #}
	{{ siteHTMLStartOfBody|raw }}


    {# Site wide HTML just before closing body tag #}
	{{ siteHTMLEndOfBody|raw }}

Another thing you should include in the head is the {{ meta|raw }} and {{ metaCustom|raw }} tags. They load the overal meta tags and the page specific meta tags. The links to the favicon and apple touch icon are placed in the head too.

{# Meta #}
<meta charset="utf-8" />
<meta name="generator" content="Fork CMS" />
{{ meta|raw }}
{{ metaCustom|raw }}

<title>{{ pageTitle }}</title>

{# Favicon and Apple touch icon #}
<link rel="shortcut icon" href="{{ THEME_URL }}/favicon.ico" />
<link rel="apple-touch-icon" href="{{ THEME_URL }}/apple-touch-icon.png" />


When you have these templates ready, it's time for the styles! This is easy, just copy paste the css of your slice to the core css folder of your theme (theme_folder/Core/Layout/css) and rename it to screen.css. If you have multiple css files, it is easiest to combine them all in one file. The link to the screen.css file is added in a template with:

{% for css in cssFiles %}
    <link rel="stylesheet" href="{{ css.file }}" />
{% endfor %}

If you don't want to combine them in one file, you should make an imports folder in the css folder and use the @import tag in your screen.css file.

Images, fonts and javascript

The images, fonts and javascript should go in the folders theme_folder/Core/Layout/images, theme_folder/Core/Layout/fonts and theme_folder/Core/Js. When you used another folder structure for the slice, you'll need to change paths in the css file for background-images and @font-face.

You can include scripts in your templates with the variable THEME_URL.

<script src="{{ THEME_URL }}/Core/Js/html5.js"></script>

Include the following code in your template to use the core js files (including jQuery, necessary for some things to work):

{% for js in jsFiles %}
    <link rel="stylesheet" href="{{ js.file }}" />
{% endfor %}

When this is done, the basic layout of your website should be ok. If the modules don't look the way you want them, it may be possible to style them with css. Sometimes you'll need to change the template files of the modules.


If you want to change the structure of a module, you'll need to add a modules folder directly in your theme folder. If you copied the Triton theme, this folder is already present. Everything in this folder should follow the same structure as the Frontend/Modules folder. The files in your theme modules folder will overwrite the file in the exact same position in the Frontend/Modules folder. If you want to change the index page for the blog module, you'll need to add "Blog/Layout/Templates/Index.html.twig" in your modules folder. This is the same for every module/widget you want to style. It's easiest to copy the core files you want to overwrite in your own folder and edit them. This way you start from a working module that hasa basic structure. You'll also see all the variables that where already used.

When changing module themes, a very useful modifier is dump. This modifier shows all the children of a variable. In the blog index the code {$items|dump} gives this:


With this modifier you're able to have a representation of all the different variables available.

While creating module templates, you'll probably need more than just loops and if tags. Creating nested iterations, checking if it's the first/last item of a loop and cycles are some things available to help you. More info in the cheat sheet.

Finishing the theme

Before your theme is finished you'd better check if everything is styled the right way. Some things are easy to forget like pagination, form validation,... You should test the theme carefully by changing settings in the backend, adding content, placing widgets and modules in other positions, testing every page in the frontend,... With all these steps, you should be able to create a Fork CMS theme without writing one single line of php! Isn't that wonderful?