New plugin! Advanced Config

I have started work on a new plugin for Moodle and it is now in alpha stages.

It allows for more advanced configuration management in Moodle (that sounds really boring). Despite how boring it sounds I am very excited about! It solves a problem that I have and hopefully it will solve some other people’s problems too.

Its main feature is that settings defined with it are inheritable and can be overridden in categories and the child categories in that category then inherit that new setting.

You can find out more at the github page for it:

Here is an image of those settings in one of my development instances:

Screenshot-2017-9-1 S1 Advanced Config Callista Grade Export

As you can see there is a little menu in the Administration block at the bottom of the Category menu that says Advanced Config. This leads to category context specific configuration page for one of our grade export tools.

Here is an example of a config file that defines those settings in particular:

namespace gradeexport_callista\settings;

use local_advancedconfig\model\basic_setting_definition;
use local_advancedconfig\model\setting_definition;
use local_advancedconfig\model\settings;
use local_advancedconfig\model\setting_definition\validate\param_generic;
use local_advancedconfig\model\setting_definition\input;
use local_advancedconfig\model\tree;

class basic_settings implements settings, tree {

    /** @var basic_settings */
    private static $instance = null;

    public static function get_instance() {
        if (is_null(self::$instance)) {
            self::$instance = new basic_settings();
        return self::$instance;

     * @return setting_definition[]
    public function settings_defined() {
        return [
            'gradeexport_callista/adminnotificationemail' =&gt; new basic_setting_definition(
                'gradeexport_callista', 'adminnotificationemail',
                new param_generic(PARAM_TEXT),
                new input(input::TEXT), '',
            'gradeexport_callista/mainheader' =&gt; new basic_setting_definition(
                'gradeexport_callista', 'mainheader',
                new param_generic(PARAM_CLEANHTML),
                new input(input::HTML), '',
            'gradeexport_callista/confirmation' =&gt; new basic_setting_definition(
                'gradeexport_callista', 'confirmation',
                new param_generic(PARAM_CLEANHTML),
                new input(input::HTML), '',

     * @return string
    public function plugin_name() {
        return 'gradeexport_callista';

     * @return branch[]
    public function get_branches() {
        return [
            new tree\leaf\leaf_settings( 'gradeexports', 'gradeexportcallista',
                new \lang_string( 'pluginname', 'gradeexport_callista'),
                ['moodle/site:config', 'gradeexport/callista:categoryadmin'],[
                    new \admin_setting_configtext(
                        new \lang_string('adminnotificationemail', 'gradeexport_callista'),
                        new \lang_string( 'adminnotificationemail_help', 'gradeexport_callista'),
                    new \admin_setting_confightmleditor(
                        new \lang_string( 'mainheader', 'gradeexport_callista'),
                        new \lang_string( 'mainheader_desc', 'gradeexport_callista'),
                    new \admin_setting_confightmleditor(
                        new \lang_string( 'confirmation', 'gradeexport_callista'),
                        new \lang_string( 'confirmation_desc','gradeexport_callista'),

Moodle administration interfaces

Adding settings interfaces to Moodle is a little cryptic.

From my short foray into doing so I have determined that the settings are defined in the settings.php file in the base directory of your module/plugin.

Admin menu entries

Adding a new entry into the “Site Administration” menu is done by instantiating a new settings page object and attaching it to the tree through the global $ADMIN object.

// Instantiate new settings page with the internal name 'local_examplecom_plugin'
// and the menu display name ' Plugin'
$settings = new admin_settingpage('local_examplecom_plugin', ' Plugin');
// Add the new settings page to the settings tree under the 'localplugins' branch
// which is located in 'Site administration->Plugins->Local plugins'
$ADMIN->add('localplugins', $settings);
// Add controls here

For local plugins the tree location value is ‘localplugins’ but other values can be substituted and they are not consistent as the below snippet shows:

'appearance' -> 'Site administration->Appearance'
'themes' -> 'Site administration->Appearance->Themes'
'modsettings' -> 'Site administration->Plugins->Activity modules'
'authsettings' -> 'Site administration->Plugins->Authentication'
'enrolments' -> 'Site administration->Plugins->Enrolments'

Admin menu categories

You can also define new collapsible menu items by instantiating a new admin_category object and then use its internal name to attach items underneath it.

$ADMIN->add('localplugin', new admin_category('internal_category_name', ''));
$settings = new admin_settingpage('local_examplecom_plugin_settings1', 'Some settings');
$ADMIN->add('internal_category_name', $settings);
// Add controls here
$settings = new admin_settingpage('local_examplecom_plugin_settings2', 'Some more settings');
$ADMIN->add('internal_category_name', $settings);
// Add controls here

Settings form controls

There are a variety of different controls that can be added but they all follow a fairly common format:

new admin_setting_config*($setting_internal_name, $setting_title, $setting_description, $default_value, $validation_type);
*can be any of a variety of control types including but not limited to htmleditor, text, checkbox etc.

$setting_internal_name and $setting_title seem to be the only mandatory ones.
$setting_internal_name should be either ‘plugin_name/setting_name’ for plugin only settings and just ‘setting_name’ for global $CFG related settings.

Adding a control to the form requires that you instantiate the control and add it to the admin_settingpage by calling the add method:

// See previous examples for where this fits in.
// Add controls here
$settings->add(new admin_setting_confightmleditor('local_examplecom/setting_one',
    'Setting title', 'Setting one description', 'this is the default value'));
$settings->add(new admin_setting_confightmleditor('local_examplecom/eats_grass',
    'Grass preference', 'What type of grass does it prefer'));
$settings->add(new admin_setting_confightmleditor('a_global_setting',
    'Not plugin specific', 'This is accessed through $CFG->a_global_setting'));