Modules

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

YOOtheme Pro has a modular and extensible application architecture. Its code is structured into modules. A module is a package of code that extends functionality of YOOtheme Pro.

Custom modules can be added by using a child-theme or a Joomla plugin. The easiest way to quickly add functionality is by using a child theme. This is typically used for client projects. A Joomla plugin should be used when developing a third-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, you can extend and modify the YOOtheme Pro functionality. 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');

Getting Started

The easiest way to get started is to try out the example module or take a look at the included YOOtheme Pro modules.

Example Module

The example module on Github demonstrates how to add asset files, builder elements and settings panels. Simply download and unzip the module. The quickest way to try it out is using a child-theme.

Download View on Github

Included Modules

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


Module Definition

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' => [

    ]

];

Use the following property keys 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.

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 order of event handlers 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 their element.json configuration file.

use YOOtheme\Builder;
use YOOtheme\Path;

return [

    'extend' => [

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

    ]

];

Added builder elements


Add Asset Files

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

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

return [

    'events' => [

        'theme.head' => [
            AssetsListener::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 AssetsListener
{
    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;');
    }
}

Added asset files


Add Settings

Sections are top-level entry points which have their own menu items in the YOOtheme Pro customizer, for example the Layout and Settings sections. They are defined in the global configuration of YOOtheme Pro. Typically, a section contains a settings 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 SettingsListener::initCustomizer to the customizer.init event.

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

return [

    'events' => [

        'customizer.init' => [
            SettingsListener::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 builder. 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 Define where the section is shown in the customizer navigation.
fields Define 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 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 static 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 available already, 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. Therefore, 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