TweetSubscribe
October CMS is the new star in the sky of CMSes. Built on top of Laravel, it promises joyful coding and a back to basics approach. Read our introduction here and find out how to build plugins for it here. In this article, we’re going to see how we can build a theme.
What We Are Going to BuildWe are going to build a blogging theme. The theme will depend on the rainlab blog plugin, and will contain:
- Default page layout
- About page
- Home page
- Posts page
- Categories page
- Single post page
The entire source code mentioned in this post is available on Github, so you’d do best if you open the repo in another tab and follow along as we explain each file in detail.
Building The ThemeOctoberCMS stores themes inside the themes directory, and they get automatically loaded when visiting the backend theme interface.
To speed up the process, I will use a free theme from startbootstrap.com.
OctoberCMS Theme Folders Structure
The screenshot shows the final structure of our theme. The folder structure is not too complicated – read the docs for more info.
Installing Necessary PluginsBecause we’re going to build a blogging theme, we will install the rainlab blog plugin which provides a handful of components we can use. If you are not familiar with components, be sure to check my previous article about building OctoberCMS plugins.
Scaffolding Our ThemeTo begin building our theme, we only need to create a folder with our unique name. I will call mine rafietheme. If you visit /backend/cms/themes, you’ll see that the new theme has been added to the list.
For now, the theme doesn’t have a description or a name, and October is only using our folder name.
The theme.yaml file inside our root theme directory will contain information about our theme.
// rafietheme/theme.yaml
name: RAFIETHEME
author: RAFIE Younes
authorUrl: http://younesrafie.com
description: Simple blogging theme
If you visit the theme management interface, you’ll see our theme with a new description and author info. Now we will add a placeholder screenshot. OctoberCMS will look for the screenshot in rafietheme/assets/images/theme-preview.png by default.
The version.yaml file tells your theme’s versioning story, and because this is just our first version we can add:
1.0.1: First version
Template StructureOctober template pages are split into three parts. Each section is separated from the others with ==.
Configuration SectionThis section is where we describe our template to the CMS. We can specify the page url, title, etc.
url = "/posts"
title = "Latest Posts"
description = "Just another posts page"
layout = "default"
We can use also initialize components, and configure them. More about that in the docs.
PHP SectionThis section is going to be wrapped inside a cached class, so we are only allowed to use functions or the usekeyword if you want.
You’ll frequently see the onStart method used here. This method is automatically run because it’s part of the page life cycle. Check the list of available functions, as well as some global variables (layout, page, component).
Markup SectionOctober is using Symfony’s Twig template engine, and inherits all the core features. The variables passed from the PHP section are available in the view. The this variable contains information about our page, controller,layout, environment, and params.
Using PlaceholdersPlaceholders are a way to inject content into the page. They can be used as one of the ways to inject your scripts, for example.
// defining the placeholder
...
{% placeholder scripts %}
</body>
</html>
Here we defined a placeholder. Before closing the body tag, we give the user the opportunity to inject some scripts, like so:
{% put scripts %}
<script src="js/slider.min.js"></script>
{% endput %}
Placeholders have other features like injecting default content, or testing if a placeholder exists. Be sure to check thedocs for more examples.
Using PartialsPartials are very useful for separating our page parts, header, footer, etc. As we said before, they are stored inside the partials directory and can be nested using sub-directories.
|---- partials/
|-- header.htm
|-- footer.htm
|-- navigation.htm
|-- comments.htm
|-- ajax/
|- posts.htm
- header.htm: contains the doctype and header definition, also some assets links.
- footer.htm: will contain some copyright text and close the document, also some JavaScript assets.
- navigation.htm: will only contain our navigation menu.
- comments.htm: Because we’re only going to use Disqus, let’s put it in its own partial.
// partials/header.htm
<!DOCTYPE html>
<html lang="en">
<head>
<title>{{ this.page.title }}</title>
{% styles %}
<link href="{{ [
'assets/css/bootstrap.min.css',
'assets/css/clean-blog.min.css'
]|theme }}" rel="stylesheet">
</head>
<body>
Inside every partial or page we can access the this variable which contains the page, layout,controller, param and environment variables, as stated in the docs.
When loading assets, we pass an array of links to the theme filter that combines the files and generates a cached link.
The {% styles %} tag allows the plugin developers to inject their assets to the page, and the same thing applies to {% scripts %}.
To inject your assets to the pages, you have two ways:
- Using the onStart function in your PHP code part of the page:
function onStart(){
$this->addCss('assets/css/main.css');
$this->addJs('assets/js/app.js');
} - Using component placeholders:
{% put scripts %}
<script type="text/javascript" src="{{ ['assets/js/app.js']|theme }}"></script>
{% endput %}
<script src="{{ [
'@jquery'
'assets/javascript/bootstrap.min.js',
'assets/javascript/clean-blog.min.js']|theme }}"></script>
{% scripts %}
</body>
</html>
You’ve noticed that we added @jquery instead of a file path!
This simply means that we want to use the jQuery file available in the back end. These notations are called aliases.
<ul class="nav navbar-nav navbar-right">
<li class="{% if( this.page.id == 'home') %}active {% endif %}">
<a href="{{ 'home'|page }}">Home</a>
</li>
<li class="{% if( this.page.id == 'about') %}active {% endif %}">
<a href="{{ 'about'|page }}">About</a>
</li>
<li class="{% if( this.page.id == 'posts') %}active {% endif %}">
<a href="{{ 'posts'|page }}">Posts</a>
</li>
</ul>
We said before that the page object is available for use inside any page or partial. We use the page.id to set the active menu item, and for the links’ href attribute, we pass the page ID to the page filter that will generate a full URL. Note that the page id is the template filename.
Using LayoutsOctober has a layouts folder where we can register our layouts. We will start with one default layout that we’ll be using for our pages.
description = "Default Layout"
==
{% partial 'header' %}
{% partial 'navigation' %}
{% page %}
{% partial 'footer' %}
In the configuration part, we can specify a description for our layout. Inside the twig markup part we include the necessary partials. The page tag will output the page content using this layout.
We can use most of the partial and page features, and also include HTML markup, assets, etc.
Creating PagesOctoberCMS stores user defined pages insides the pages folder. Let’s start by creating our about page first, and we will explore the different possibilities along the way.
About PageBecause this is our first page, we’re going to make it as simple as possible, and the first part is to use the configuration section.
title = "About"
url = "/about"
layout = "default"
description = "Just another about page"
The template section will contain only some Lorem ipsum HTML content inside a container.
<div class="container">
Lorem ipsum.....
</div>
That’s it! you can visit the new page by hitting the /about URL of your blog’s front end.