Note:

If you want to create a new page for developers, you should create it on the Moodle Developer Resource site.

Moving your theme to use boost as a parent theme

From MoodleDocs
Revision as of 08:16, 15 July 2021 by David Mudrak (talk | contribs) (Text replacement - "<code (.*)>" to "<syntaxhighlight lang="$1">")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Moodle 3.6


Key differences

Bootstrap version differences

The biggest difference between themes Bootstrapbase and Boost are the included Bootstrap libraries. Bootstrapbase uses Bootstrap version 2.3.3, Boost uses Bootstrap version 4.0.0 (at the time of writing this document).

CSS extension language differences

LESS css is used in Bootstrapbase, Boost uses Sass CSS.

LESS uses a different css syntax than Sass. The most obvious difference is the way variables are defined; LESS uses @, Sass uses $. There are many other differences between LESS and Sass; css-tricks has more information on these differences. The npm package less2sass can be helpful when migrating your less files.

LESS css is compiled using a core grunt task and stored in theme/bootstrapbase/style/moodle.css. Child themes need to specify additional stylesheets using the

$THEME->sheets = []

array or use

$THEME->lessfile = ''

to use the core LESScss library

Sass css is compiled using a core scssphp Library for theme Boost and child themes if

$THEME->scss = ''

is used. The compiled css file served to the end user is stored in a Moodle cache and is regenerated each time theme caches are cleared. Using the core scssphp compiler allows for the usage of Boost Presets. For information on advanced usage of Sass css see the SCSS doc page.

Moodle templates differences

Theme Boost uses Templates to render the main layouts. For each of the layout files in theme/boost/layouts/ there is a corresponding layout file in theme/boost/templates.

The layout files found in theme Bootstrapbase are a combination of php and html.

Renderers differences

In theme Boost all overridden renderers can be found theme/boost/classes/output, in theme Bootstrapbase the overridden renderers are called in /theme/bootstrapbase/renderers.php.

Theme config differences

The theme configuration for Boost based themes do not differ much from Bootstrapbase based themes. For a full list of option is available in the Themes Overview doc page.

These configuration options only apply to theme Bootstrapbase and child themes:

$THEME->lessfile = 'moodle';
$THEME->lessvariablescallback = 'theme_more_less_variables';
$THEME->extralesscallback = 'theme_more_extra_less';
$THEME->doctype = 'html5';

These configuration options only apply to theme Boost and child themes:

$THEME->scss = function($theme) {
    return theme_boost_get_main_scss_content($theme);
};
$THEME->extrascsscallback = 'theme_boost_get_extra_scss';
$THEME->prescsscallback = 'theme_boost_get_pre_scss';
$THEME->precompiledcsscallback = 'theme_boost_get_precompiled_css';
$THEME->addblockposition = BLOCK_ADDBLOCK_POSITION_FLATNAV;


Upgrading a theme to use Boost as a parent theme.

There is no fit-for-all tutorial on upgrading your theme since themes can have lots of custom features. The steps specified here are the steps that were taken upgrading the community theme Elegance to use theme Boost as its parent and serve as an example.

Update the theme config

Most of the config file can remain the same. References to less files need to be removed, the theme scss content needs to be specified using a callback.

$THEME->scss = function($theme) {
    return theme_elegance_get_main_scss_content($theme);
};

code snippet from theme/elegance/config.php

In this example the theme was specialised in rendering custom widgets on the front page, so we only need to specify a different layout file for the front page.

$THEME->layouts['frontpage'] = [
        'file' => 'frontpage.php',
        'regions' => ['side-pre'],
        'defaultregion' => 'side-pre',
        'options' => ['nonavbar'],
    ];

code snippet from theme/elegance/config.php

Update the theme lib file

Add the get_main_scss_content callback function to your theme lib file.

The callback function will need to fetch the Sass files from your parent theme. Use this example when basing your theme of Boost

/**
 * Returns the main SCSS content.
 *
 * @param theme_config $theme The theme config object.
 * @return string
 */
function theme_elegance_get_main_scss_content($theme) {
    global $CFG;

    $scss = file_get_contents($CFG->dirroot . '/theme/elegance/scss/variables.scss');
    $scss .= file_get_contents($CFG->dirroot . '/theme/boost/scss/fontawesome.scss');
    $scss .= file_get_contents($CFG->dirroot . '/theme/boost/scss/bootstrap.scss');
    $scss .= file_get_contents($CFG->dirroot . '/theme/boost/scss/moodle.scss');
    $scss .= file_get_contents($CFG->dirroot . '/theme/elegance/scss/post.scss');

    return $scss;
}

code snippet from theme/elegance/lib.php

Make sure your create these files when using the example above:

  • theme/elegance/scss/variables.scss
  • theme/elegance/scss/post.scss

Create your template and layout files

If your theme contains custom layouts it will need a template for each layout.

For theme elegance these layout files and templates were copied

cp theme/boost/layout/columns2.php theme/elegance/layout/frontpage.php
cp theme/boost/templates/columns2.mustache theme/elegance/templates/layout_frontpage.mustache

in the new frontpage.php the reference to the template needs updating after copying these:

    echo $OUTPUT->render_from_template('theme_elegance/layout_frontpage', $templatecontext);

code snippet from theme/elegance/layout/frontpage.php

Now the layout file and the template file are in place custom widget / renderers can be added for the front page.

For theme elegance a carousel slideshow can be configured through the theme settings. The renderer for this carousel is called in theme/elegance/layout/frontpage.php:

$renderer = $PAGE->get_renderer('theme_elegance');
$carousel = new \theme_elegance\output\carousel();
$widgets = (object) [
    'carousel' => $renderer->render($carousel)
];

$templatecontext = [
    ..
    'widgets' => $widgets,
    ..
];

code snippet from theme/elegance/layout/frontpage.php

The carousel widget is passed on to the theme/elegance/template/layout_frontpage.mustache template

Migrating your LESS files

The Bootstrapbase theme css is written in the LESS css extention language. Some child themes of bootstrapbase use LESS to generate their stylesheets. Usually these files are stored in the less/ folder of the child theme.

The Boost theme css is written in the Sass css extention language. A child theme can extend the Boost Sass files which are usually found in the sass/ folder of the child theme.

The LESS and Sass extention languages are different and not compatible, themes using less will have to migrate their stylesheets. This can be done manually or with the less2sass tool to translate LESS files into Sass. This tool is a great start when migrating your LESS however, after running less2sass to migrate your stylesheets you will need to inspect them and fix them if needed.

/* Icon styles */
// Size of big icons.
@icon-big-width: 64px;
@icon-big-height: 64px;

img.icon {
    &.iconsize-big {
        width: @icon-big-width;
        height: @icon-big-height;
    }
}

.groupinfobox {
    .well;

}

example less from theme/bootstrapbase/less/moodle/core.less

// Size of big icons.
$icon-big-width: 64px;
$icon-big-height: 64px;
.icon {
    &.iconsize-big {
        width: $icon-big-width;
        height: $icon-big-height;
    }
}
 .groupinfobox {
    @extend .card;
 }

example sass from theme/boost/scss/moodle_core.scss

The Sass CSS extension language is not that hard to learn. Make sure you have read The Sass Basics and understand how to define and override variables and use mixins.

When you start migrating your LESS file a good starting point is your theme variables.less. Usually child themes define a number of new variables and override some of the variables defined in theme/bootstrapbase/less/bootstrap/variables.less. Your new variables will probably be okay when migrating to SASS. The overridden bootstrap variables will no longer be valid. So for each overridden variable try to find the new variables name in theme/boost/sass/bootstrap/_variables.scss.

// Scaffolding
// -------------------------
@bodyBackground:        @white;
@textColor:             @grayDark;


// Links
// -------------------------
@linkColor:             #08c;
@linkColorHover:        darken(@linkColor, 15%);

example variables from theme/bootstrapbase/less/bootstrap/variables.less

// Body
//
// Settings for the `<body>` element.

$body-bg:                   $white !default;
$body-color:                $gray-900 !default;

// Links
//
// Style anchor elements.

$link-color:                theme-color("primary") !default;
$link-decoration:           none !default;
$link-hover-color:          darken($link-color, 15%) !default;
$link-hover-decoration:     underline !default;

example variables form theme/boost/sass/bootstrap/_variables.scss

Using grunt to debug Sass compile issues

When you start creating your new Sass files debugging what happens in the Moodle core PHP Sass compiler can take a lot of time. The compiler is run using a caching mechanism and error reporting is poor, when a variable is misspelled the errors are send to your webserver logfiles.

To speed up development The Grunt Javascript taskrunner that runs on Node.js can be very helpful. If you have not tried to get Grunt running for Moodle core tasks make sure you read the Moodle Grunt docs page for more info.

You can use Grunt to compile your Sass and check your Sass syntaxs. Once you have Grunt and Node.js up and running you can create your own Gruntfile.js and package.json file.

For theme Elegance these files are found in theme/elegance/Gruntfile.js and theme/elegance/package.json.

You can copy these into your theme folder and run the Node installer to retreive all Node dependancies.

> nmp install

Make sure you update the Gruntfile.js to reflect your configuration:

    sass: {
        options: {
            style: 'expanded'
        },
        dist: {
            files: {
                'style/elegance.css': 'scss/gruntcompile.scss'
            }
        }
    },

section of the Grunfile.js you will need to change

Once all dependancies are installed you can run Grunt to watch your Sass files. Each time you make a change in any of the files the the Node compiler will run and create a new stylesheet in your theme's style/ folder

This stylesheet will not be served to the end user unless you change your theme configuration:

$THEME->sheets = ['elegance'];

// Commented out to prevent PHP Sass compiling.
//$THEME->scss = function($theme) {
//    return theme_elegance_get_main_scss_content($theme);
//};

section of theme/elegance/config.php

Migrating your renderer files

In Bootstrapbase the overriden renderers were located in theme/boost/renderers/. These renderes are stored in classes/output in the Boost.

In theme Boost the overridden core renderer is located in theme/boost/classes/output/core_renderer.php. If your theme overrides the core renderer (/lib/outputrenderers.php) make sure you override the Boost renderer (In Moodle version 3.6 and below).

<?php
// This file is part of the elegance theme for Moodle
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.

namespace theme_elegance\output;

use \theme_boost\output\core_renderer as boost_core_renderer;
use stdClass;
use theme_config;

defined('MOODLE_INTERNAL') || die;

/**
 * Renderers to align Moodle's HTML with that expected by Bootstrap
 *
 * @package    theme_elegance
 * @copyright  2019 Bas Brands
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */

class core_renderer extends boost_core_renderer {
	 /**
     * Returns the title to use on the page.
     *
     * @since Moodle 2.5.1 2.6
     * @return string
     */
    public function page_title() {
        ...
    }
}

Move your custom renderers or other overridden renderes to your themes classes/output folder too.