Modules

Extend any part of YOOtheme Pro with custom functionalities. For example, add setting sections and panels to the YOOtheme Pro customizer, elements or content sources to the page builder or load needed assets files into the site.

YOOtheme Pro comes with a modular and extensible application architecture. The code is structured into modules. They are packages of code that extend the core functionality of YOOtheme Pro.

Custom modules can be added by using a child-theme or a Joomla plugin. Using a child theme is the easiest way to quickly add functionality and is typically used for client projects. A Joomla plugin should be used when developing a 3rd party extension for YOOtheme Pro. Take a look at the extensions page to see what is available from the developer community.


Joomla Plugin

Joomla provides a developer guide which explains the basics of creating a plugin. Apart from listening to Joomla events, functionality of YOOtheme Pro can be extended and modified. Use the onAfterInitialise event to run the code after the application is initialized and use the YOOtheme\Application::load method to load a custom module.

<?php

defined('_JEXEC') or die;

use Joomla\CMS\Plugin\CMSPlugin;
use YOOtheme\Application;

class plgSystemMyPlugin extends CMSPlugin
{
    public function onAfterInitialise()
    {
        // Check if YOOtheme Pro is loaded
        if (!class_exists(Application::class, false)) {
            return;
        }

        // Load a single module from the same directory
        $app = Application::getInstance();
        $app->load(__DIR__ . '/bootstrap.php');
   }
}

The YOOtheme\Application::load method can also load multiple modules using a glob pattern. In the following example all modules are located in the modules directory and have their own directory with an entry bootstrap.php file.

$app->load(__DIR__ . '/modules/*/bootstrap.php');

Create a Module

At its simplest, a YOOtheme Pro module is a PHP file, typically named bootstrap.php, which returns an array with a module definition. The module definition is used to provide bootstrapping, routing and other configuration options. Here you can listen to events, add custom classes and your own controllers. In the child theme the equivalent file is the config.php file.

<?php

return [

    // Set theme configuration values
    'theme' => [

    ],

    // Register event handlers
    'events' => [

    ]

];

The following property keys can be used in the module definition array.

Options Description
events Register event handlers
theme Set theme configuration values
routes Register routes
actions Register Joomla event handlers or WordPress action handlers
filters Register WordPress filter handlers
config Set application configuration values
extend Extend service definitions
services Register services
aliases Register service aliases

The example module on Github demonstrates how to add asset files, builder elements and setting panels. Simply download and unzip the example module.

The core modules of YOOtheme Pro are a useful resource to get started when creating a custom module. They can be found in the vendor/yootheme directory in YOOtheme Pro.


Events

Register event handlers and listen to various events that are triggered during the execution of the theme application.

Event Description
theme.init Fires after the theme is initialized
theme.head Fires before the head is rendered
customizer.init Fires before customizer is initialized
source.init Fires before the source schema is initialized

The event handler order is defined by their priority. The default priority is set to 0. Higher priorities are executed earlier.

include_once __DIR__ . '/src/MyListener.php';

return [

    'events' => [

        'theme.head' => [
            MyListener::class => 'initHead'
        ],

        'theme.init' => [
            MyListener::class => ['initTheme', 10]
        ],

        'customizer.init' => [
            MyListener::class => ['initCustomizer', -10]
        ]

    ]

];

Event handlers are defined in their own listener class.

class MyListener
{
    function initHead() {}

    function initTheme() {}

    function initCustomizer() {}
}

Add Builder Elements

To add custom elements to the page builder, extend the YOOtheme\Builder services by adding new elements. The YOOtheme\Builder::addTypePath method adds multiple elements using a glob pattern. In the following example all elements are located in the elements directory and have their own directory with its element.json configuration file.

use YOOtheme\Builder;
use YOOtheme\Path;

return [

    'extend' => [

        Builder::class => function (Builder $builder) {
            $builder->addTypePath(Path::get('./elements/*/element.json'));
        }

    ]

];

Custom Elements in the Element Library


Add Asset Files

To add custom asset files to the head of the HTML document, register an event handler MyListener::initHead to the theme.head event.

include_once __DIR__ . '/src/MyListener.php';

return [

    'events' => [

        'theme.head' => [
            MyListener::class => 'initHead'
        ]

    ]

];

Use the YOOtheme\Metadata service and its YOOtheme\Metadata::set() method to add metadata elements like in this case the assets files. The first argument defines the meta data type and after the : a unique identifier is given. The second argument is either an array of attributes or the content of the HTML element.

use YOOtheme\Metadata;

class MyListener
{
    function initHead(Metadata $metadata)
    {
        // Style file
        $metadata->set('style:my-css', ['href' => 'assets/css/custom.css']);

        // Inline style
        $metadata->set('style:my-inline-css', '* { text-shadow: 0 0 1px blue !important; }');

        // Script file
        $metadata->set('script:my-js', ['src' => 'assets/js/custom.js', 'defer' => true]);

        // Inline script
        $metadata->set('script:my-inline-js', 'var inline = 123;');
    }
}

Asset Files in the Dev Tools


Add Settings

Sections are top-level entry points which have their own menu item in the YOOtheme Pro customizer, for example the Layout and Settings sections. Typically, a section contains a setting panel with a group of fields but it can also have a navigation to deeper nested panels.

To add a section or a panel to the customizer, register an event handler MyListener::initCustomizer to the customizer.init event.

include_once __DIR__ . '/src/MyListener.php';

return [

    'events' => [

        'customizer.init' => [
            MyListener::class => 'initCustomizer'
        ]

    ]

];

Use the YOOtheme\Config service and its YOOtheme\Config::addFile() method to add a JSON configuration file to the global configuration of YOOtheme Pro. In this example it's added to the customizer configuration. The Path::get() helper method resolves the path relative to the file the method is called from.

use YOOtheme\Config;
use YOOtheme\Path;

class SettingsListener
{
    public static function initCustomizer(Config $config)
    {
        $config->addFile('customizer', Path::get('./customizer.json'));
    }
}

JSON Configuration

The JSON configuration defines the sections and panels and how the editing interface should look like inside the customizer. Make sure to use unique keys for sections, panels and fields.

Property Description
title Label in the customizer.
width Width of the customizer sidebar when editing the element.
priority Defines where the section is shown in the customizer navigation.
fields Defines the fields of the section.

The following example adds a My Section menu item to YOOtheme Pro which opens a simple section configuration with a field.

{
    "sections": {
        "my-section": {
            "title": "My Section",
            "width": 400,
            "priority": 100,
            "fields": {
                "option_a": {
                    "label": "Option A",
                    "description": "A description text."
                }
            }
        }
    }
}

Section in the Customizer

The following example adds a My Panel menu item to the Settings section in the customizer which opens a simple panel configuration with a field.

 {
    "sections": {
        "settings": {
            "fields": {
                "settings": {
                    "items": {
                        "my-panel": "My Panel"
                    }
                }
            }
        }
    },
    "panels": {
        "my-panel": {
            "title": "My Panel",
            "width": 400,
            "fields": {
                "option_b": {
                    "label": "Option B",
                    "description": "A description text."
                }
            }
        }
    }
}

Panel in the Customizer

The configuration of the Layout section and all its panels is a useful resource to get started when creating new sections and panels. It can be found in the respective module directory under vendor/yootheme/theme/config/customizer.json in YOOtheme Pro. Learn also more about fields and their types in the custom element documentation.

PHP Configuration

If a dynamic configuration is needed, use the YOOtheme\Config service to directly modify the configuration instead of using a JSON file.

The following example adds a My Section menu item to YOOtheme Pro which opens a simple section configuration with a field.

use YOOtheme\Config;

class SettingsListener
{
    public static function initCustomizer(Config $config)
    {
        $config->set('customizer.sections.my-section', [
            'title'  => 'My Section',
            'width'  => 400,
            'priority'  => 100,
            'fields' => [
                'option_a' => [
                    'label' => 'Option A',
                    'description' => 'A description text.'
                ]
            ]
        ]);
    }
}

The following example adds a My Panel menu item to the Settings section in the customizer which opens a simple panel configuration with a field.

use YOOtheme\Config;

class SettingsListener
{
    public static function initCustomizer(Config $config)
    {
        $config->set('customizer.panels.my-panel', [
            'title'  => 'My Panel',
            'width'  => 400,
            'fields' => [
                'option_a' => [
                    'label' => 'Option A',
                    'description' => 'A description text.'
                ]
            ]
        ]);

        $config->set('customizer.sections.settings.fields.settings.items.my-panel', 'My Panel');
    }
}

Template Files

All fields added to the customizer are stored under the ~theme namespace and can be accessed in the template files.

echo $config('~theme.option_a');

If the $config variable is not already available, the YOOtheme\Config service can be accessed using the global \YOOtheme\app() function.

namespace YOOtheme;

$config = app(Config::class);

echo $config('~theme.option_a');

Mind, that field names have to be unique. Therefor it's recommended to add a namespace to the field names using the dot notation.

"fields": {
    "my_namespace.option_a": {
        "label": "Option A"
    },
    "my_namespace.option_b": {
        "label": "Option B"
    }
}

Use the YOOtheme\Config::addAlias() method to define an alias and shorten the call to access the field value.

$config->addAlias('~my_namespace', '~theme.my_namespace');

echo $config('~my_namespace.option_a');
echo $config('~my_namespace.option_b');
YOOtheme Pro Documentation