The following is an extensive guide on how themes should work in OctoberCMS
?>This guide assumes that you have a basic understanding of html
, css
, twig
, and OctoberCMS theming. If you do not, I suggest you read the documentation below.
MDN Docs on HTML :fas fa-external-link-alt:
MDN Docs on CSS :fas fa-external-link-alt:
Symphony's Documentation on Twig :fas fa-external-link-alt:
OctoberCMS Theming Docs :fas fa-external-link-alt:
When creating themes in OctoberCMS, use this structure:
โโโ ๐ theme-name
โโโ ๐ assets
| โโโ ๐ css
| | โโโ #๏ธโฃ styles.css <!-- main css file. do not change name. -->
| โโโ ๐ js
| | โโโ ๐ script.js <!-- main js file. do not change name. -->
| โโโ ๐ img
| | โโโ ๐ผ๏ธ image.jpg <!-- all theme images go gere -->
โโโ ๐ content <!-- how all content will be structured. -->
| โโโ ๐ page_name
| | โโโ ๐งcontent_name.htm
| โโโ ๐ page_name_2
| | โโโ ๐งcontent_name_2.htm
โโโ ๐ layouts
| โโโ ๐ง default.htm <!-- main layout file. do not change name. -->
| โโโ ๐ง page.htm <!-- main layout file for pages. do not change name. -->
โโโ ๐ pages
| โโโ ๐ง home.htm <!-- home page. do not change name -->
โโโ ๐ partials
โโโ ๐ง head.htm <!-- head code for pages. do not change name. -->
โโโ ๐ง header.htm <!-- navigation code for pages. do not change name. -->
โโโ ๐ง foot.htm <!-- foot code for pages (before closing </body> tag). do not change name. -->
โโโ ๐ง footer.htm <!-- footer for pages. do not change name. -->
!>Note: this is a strict guideline. Do not change the names of these files or folders under any circumstance. These are put in place to make sure everyone knows where the files are and how to get to them, thus creating a workable, consistent coding environment.
Below is a explanation on what files each folder will have and how each folder will be structured.
The ๐assets
folder is where we will store all of our #๏ธโฃcss
, ๐js
, and ๐ผ๏ธimg
files. The files in these folders will style and create the functionality of theme so it's imperative that we keep the file count small and easy to navigate.
The ๐css
folder should contain one main file to style the entire theme. This file name is called #๏ธโฃstyles.css
. If this file does not exist, you will need to create it.
!>The name of this file will not be changed and we will not add any other #๏ธโฃ.css
files here unless they are modules or extensions.
If you need to add other modules on the site that require a #๏ธโฃ.css
file, add them here.
For example, if you would like to add jquery.fancybox, add this #๏ธโฃ.css
file in this folder.
โโโ ๐ css
โโโ #๏ธโฃ styles.css <!-- main css file. do not change name. -->
โโโ #๏ธโฃ jquery.fancybox.min.css <!-- fancybox css file -->
Be sure to call it in your ๐งhead.htm
partial as well.
...
<link rel="stylesheet" href="{{ 'assets/css/jquery.fancybox.min.css'| theme }}>
...
The ๐js
folder should contain one main javascript file for the entire theme. This file name is called ๐script.js
. If this file does not exist, you will need to create it.
!>The name of this file will not be changed and we will not add any other ๐.js
files here unless they are modules or extensions.
If you need to add other modules on the site that require a ๐.js
file, add them here.
For example, if you would like to add jquery.fancybox, add this ๐.js
file in this folder.
โโโ ๐ js
โโโ ๐ script.js <!-- main js file. do not change name. -->
โโโ ๐ jquery.fancybox.min.js <!-- fancybox js file -->
Be sure to call it in your ๐งfoot.htm
partial as well.
...
<script src="{{ 'assets/js/jquery.fancybox.min.js'|theme }}>
...
The ๐img
folder should contain all of the images associated with the theme.
?> This should not contain images that can be dynamically generated. More specifically, this folder should contain images that need to be rendered in each partial, and page directly.
Example of the image file structure
โโโ ๐ img
โโโ ๐ผ๏ธ logo.png
โโโ ๐ผ๏ธ hero.jpg
๐งcontent
files are chunks of HTML code that are used to display static content across the site. They do not use twig
and are not dynamic. When creating content files, make sure they are in a folder relative to the page name on which they will be displayed. Example below:
โโโ ๐ content
โโโ ๐ home
| โโโ ๐งhero-title.htm
| โโโ ๐งhero-description.htm
โโโ ๐ about
โโโ ๐งabout-title.htm
โโโ ๐งabout-description.htm
!> Note: ๐ง content
files will not contain any HTML classes, ids, divs, special html tags (e.g. <article>
, <section>
, etc), or attributes. The only tags that these files are allowed to have are as follows:
<p>
<ul>
<li>
<span>
<blockquote>
<strong>
To render those files, you will need to use the {% content %}
tag like so:
<div class="hero">
<div class="container hero-container">
{% content 'home/hero-title' %}
{% content 'home/hero-description' %}
</div>
</div>
?> Note, when using plugins associated with ๐งcontent
files, make sure you maintain this structure. This makes it easy for clients to go and make edits and easy for us to find files. If you would like to know more on how content files work, read the OctoberCMS Documentation :fas fa-external-link-alt:
Layouts define the page scaffold, that is everything that repeats on a page, such as a header and footer. Layouts will contain the <html>
tag as well as the <head>
and <body>
tags.
We create layouts when we need to create a general structure on how the code should be rendered. Here's an example of how the ๐งdefault.htm
layout will look like:
<!DOCTYPE html>
<html>
<head>
{% partial 'head' %}
</head>
<body>
{% partial 'header' %}
{# Where page ๐งcontent will be rendered #}
{% page %}
{% partial 'footer' %}
{% partial 'foot' %}
</body>
</html>
?> Note: Use this a base on rendering layouts. Add ๐งpartials
where needed. Do not add direct code here.
In order to render the layout, you'll need to assign the layout to the page you're working with. Example below:
title = "Home"
url = "/"
{# setting the layout here #}
layout = "default"
!> Note: You should only need to create a new layout if the entire structure of the the site will change, or a layout requires the use of a plugin (like the Pages Plugin :fas fa-external-link-alt: for example)
All websites have ๐งpages
. In OctoberCMS, ๐งpages
are represented with page templates.
Each page has an ID which is associated with the filename. For example, if you create a page named ๐งhome.htm
in the ๐pages
folder, the ID of the page will be home
.
๐งpages
require layouts to be styled accordingly. They also accept ๐งcomponents
can be used to display ๐งpartials
& ๐งcontent
as well.
To setup a page, create a .htm
file in the ๐pages
folder and use the following markup as a base:
title = "Home" {# title of the page. Displayed in the backend #}
url = "/" {# Where the page will be accessible in the browser #}
layout = "default" {# Layout the page is using #}
== {# Marks the beginning of HTML #}
<div class="hero">
<div class="hero-container">
<h3>
{# renders the page title onto the page #}
{{ this.page.title }}
</h3>
<p>A Cool Hero</p>
{# Displaying a partial #}
{% partial 'homePageAlert' %}
{# displaying a content file #}
{% content 'home/hero-content.htm' %}
</div>
</div>
?>Note: Please name your pages according to the page's function. (e.g the Homepage should be named ๐งhome.htm
)
To render page content, you need to use the {% page %}
tag in a ๐งlayout
. Simple example below:
<html>
<body>
{% page %}
</body>
</html>
๐งpartials
are chunks of global, reusable code that is used throughout the theme and are rendered with the {% partial %}
tag.
The ๐partials
folder should contain four main files that will be used across the theme. Those files are ๐งhead.htm
, ๐งheader.htm
, ๐งfoot.htm
and ๐งfooter.htm
. If they do not exist, you will need to create them.
Here's an example of the folder structure below.
โโโ ๐ partials
โโโ ๐ง head.htm <!-- head code for pages. do not change name. -->
โโโ ๐ง header.htm <!-- navigation code for pages. do not change name. -->
โโโ ๐ง foot.htm <!-- foot code for pages (before closing </body> tag). do not change name. -->
โโโ ๐ง footer.htm <!-- footer code for pages. do not change name. -->
!>The name of these files will not be changed and we will not add any other partials in the root of the folder unless they meet the following requirements:
The partial
is going to be a global component (e.g. custom alerts.)
The partial
will be used across the entire website.
If the partial does not meet any of these requirements, they need to be implemented per page and must be included in a folder. The folder name will be related to the function of the partial.
This partial will contain all the code that goes in the <head>
tag. This partial will not contain the <head>
tag itself. Example below:
{# Bootstrap & FancyBox Stuff #}
<link rel="stylesheet" href="{{ 'assets/bootstrap/css/bootstrap.min.css'|theme }}">
<link rel="stylesheet" href="{{ 'assets/css/jquery.fancybox.min.css'|theme }}">
{# main css file. Do not change #}
<link rel="stylesheet" href="{{ 'assets/css/styles.css'|theme }}">
{# where styles will be injected for plugins #}
{% styles %}
{# viewport stuff for mobile #}
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0">
{# favicon stuff #}
<link rel="apple-touch-icon" sizes="180x180" href="{{ 'assets/img/apple-touch-icon.png'|theme }}">
<link rel="icon" type="image/png" sizes="32x32" href="{{ 'assets/img/favicon-32x32.png'|theme }}">
<link rel="icon" type="image/png" sizes="16x16" href="{{ 'assets/img/favicon-16x16.png'|theme }}">
?> Theme files can combined together. More info here:fas fa-external-link-alt:
This partial will contain the navigation of the site, typically right after the opening <body>
tag depending on the theme. Example below:
{# Using Bootstrap 4 in this example #}
<nav class="navbar navbar-light navbar-expand-md align-items-center">
<div class="container">
<a class="navbar-brand" href="{{ 'home'|page }}">
<img class="img-fluid" src="{{ 'assets/img/logo.png'|theme }}">
</a>
<button data-toggle="collapse" class="navbar-toggler" data-target="#navcol-1">
<span class="sr-only">Toggle navigation</span><i class="fas fa-bars"></i>
</button>
<div class="collapse navbar-collapse" id="navcol-1">
<ul class="navbar-nav">
<li class="nav-item active">
<a class="nav-link" href="{{ 'home'|page }}">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{{ 'features'|page }}">Features</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{{ 'pricing'|page }}">Pricing</a>
</li>
</ul>
</div>
</div>
</nav>
You may notice that this template contains twig
code referencing to a page. This code will render links to the pages in the ๐pages
folder.
The navigation style will vary from theme to theme, so change this code accordingly.
This partial will contain all of the code needed before the closing <body>
tag. Usually javascript. Example below:
{# reference to jquery #}
<script src="{{ ['@jquery']|theme }}"></script>
{# Bootstrap Stuff #}
<script src="{{ 'assets/bootstrap/js/bootstrap.min.js'|theme }}"></script>
{# main script file. Do not change #}
<script src="{{ 'assets/js/script.js'|theme }}"></script>
{# reference to the OctoberCMS Framework. #}
{# Should be only included ONCE and after #}
{# jquery has been called. #}
{% framework extras %}
{# where scripts will be injected for plugins #}
{% scripts %}
This partial will contain the footer code for the site. This code will be presented at the bottom of the page after all the content but before the ๐งfoot.htm
partial. Example below
{# Using Bootstrap 4 in this example #}
<div class="section footer">
<div class="container">
<div class="row">
<div class="col-12 col-lg-3">
<h5 class="footer-header">Navigation</h5>
<ul class="nav flex-column">
<li class="nav-item">
<a class="nav-link" href="{{ 'home'|page }}">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{{ 'about'|page }}">Link</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{{ 'contact'|page }}">Link</a>
</li>
</ul>
</div>
</div>
</div>
<p class="small text-muted text-center">
Copyright ยฉ Acme Inc. All Rights Reserved
</p>
</div>
In order to render a partial, use the following code in a layout:
{# change the name to whatever partial you are referencing #}
{% partial 'footer' %}
Now that you have a general idea on how our themes will be structured, lets move on to the Code of Conduct.