Create the Empty Theme

Now that we’ve created our container package, let’s create the first component of this website that we’re going to need -- our custom theme. In Concrete CMS, a front-end website must always have a theme. A theme may either reside in the application/themes/ directory (for custom themes in a site), or within the themes/ directory found inside any active package. That’s how we’re going to operate: we’re going to create a Dreamrs Theme inside of our Dreams package.

First, let’s create the directory that’s going to hold out theme. Within the packages/dreamrs directory, run

mkdir themes  
cd themes  
mkdir theme_dreamrs

We don’t need to give the theme the directory theme_dreamrs -- dreamrs by itself would be just fine. But for the purposes of this tutorial it’s helpful to have the theme named something just a little bit different than the package.

Next, let’s add a thumbnail for our theme. Just like packages, themes need a thumbnail to differentiate themselves from other installed themes in the Dashboard > Pages & Themes list. Unlike, the package’s icon.png file, this file isn’t square. it’s the aspect ratio 4x3, and the name is thumbnail.png. That means if it’s 120 pixels wide, it’s 90 pixels tall. I’m going to create one based off of the home page, and make it 240 x 180.

Next, we need to create a page_theme.php file for our theme. A page_theme.php is kind of like a controller for a theme -- it registers what CSS and JavaScript assets the theme provides, registers what grid framework the theme supports, and much more. This isn’t strictly required, and we’re not going to put much into it to start with, but if we don’t create this file now, it’ll be hard to get Concrete to recognize that it exists after we install the theme. So let’s make it now.

First, create a file named page_theme.php at the root of the theme.

cd theme_dreamrs  
touch page_theme.php

Edit this file, and first give it the required namespace.

<?php  
namespace Concrete\Package\Dreamrs\Theme\ThemeDreamrs

This should make more sense, now that you’ve worked with derived namespaces within your Concrete package. The namespace of the PageTheme class starts with the package namespace we used before, and then adds Theme and the PascalCase’d version of the theme’s handle.

Next, let’s add this line, which we should be adding to the top of any PHP file run by Concrete:

defined('C5_EXECUTE') or die('Access Denied.');

Now let’s import the base theme class that our PageTheme class must extend.

use Concrete\Core\Page\Theme\Theme;

We’ll be extending this class. Now we will create the first version of our class:

class PageTheme extends Theme
{

    public function getThemeName()
    {
        return t('Dreamrs');
    }

    public function getThemeDescription()
    {
        return t('Theme based off the Dreamrs Bootstrap 4 HTML theme.');
    }
}

PageTheme is the required name for this file. It extends the Theme class mentioned earlier, which all custom PageTheme classes must do. The only methods we’re defining in our class return the name and the description of the theme. That’s ok -- we just need to have the class in place; we’ll add more to it later.