Developing Extensions

It is recommended to disable caching during development!

Introduction

The extension interface provides a convenient way of extending Automad's core functionality while still offering Automad's template syntax. Extensions can be used like normal Toolbox methods, but using the @x() placeholder:

@x(Extension{ Options })

Structure

Each extension has its own subdirectory in /extensions. All files of an extension are bundled within that directory. The file containing the actual PHP code must have the same name as the subdirectory. All PHP file and directory names must be lowercase! An extension requires only that PHP file, but can have other files as well.

extensions/
└── my_extension/
    └── my_extension.php

Namespace, Classname & Method

Extensions have their own namespace to avoid conflicts with Automad's core classes.

namespace Extensions;

The classname as well as the main method must both have the same name like the extension's directory, but can be capitalized for better readibility, since PHP is case insensitive. /extensions/my_extension/my_extension.php's content could be for example:

<?php namespace Extensions;

class My_Extension {
    public function My_Extension(...) {
        // PHP code here ...
    }
}

?>

That extension can now be used in templates like this:

@x(My_Extension{ Options })

Parameters & Options

When the main extension method gets called from a template (here My_Extension()), two parameters always get passed to that method by the template engine automatically:

  1. An associative array of $options
  2. the $Automad object

A typical method declaration looks like this:

public function My_Extension($options, $Automad) {
    // PHP code here ...
}

Return Values

The main job of an extensions is to generate HTML markup. The template parser will insert the extension's return value into the template's HTML markup. Therefore all extensions should generally end with a return statement.

Javasript & CSS Files

In case your extension requires Javascript or CSS files to be loaded, Automad takes care of that. All .js and .css files within an extension's directory - no subdirectory - get automatically appended to your template's <head> section when needed.
To prevent loading these files automatically, you can place your .css and .js files in a subdirectory.

Minified Files

In case you as well have compressed versions of your files ending with .min.js and .min.css stored along with the uncompressed files, Automad will only load the compressed one and skip the uncompressed file to avoid double loading.


Example

A good example to start with is the Gallery extension. Its directory structure is quite simple:

extensions/
└── gallery/
    ├── gallery.css
    ├── gallery.js
    ├── gallery.min.css
    ├── gallery.min.js
    └── gallery.php

On any page, the Gallery gets used, Automad will also load gallery.min.js and gallery.min.css automatically (while skipping its uncompressed versions).

The gallery's class file demonstrates, how $options and $Automad should be used.

<?php

namespace Extensions;

class Gallery {

    public function Gallery($options, $Automad) {

        // It is always to provide a set of defaults for all possible options.
        $defaults =     array(
                            'files' => '*.jpg',
                            'width' => 200,
                            'height' => 200,
                            'order' => false, 
                            'class' => ''
                        );

        // Merge defaults array with options array.
        $options = array_merge($defaults, $options);

        // Get file list.
        $files = \Automad\Core\Parse::fileDeclaration($options['files'], $Automad->getCurrentPage());

        // Sort images.
        if ($options['order'] == 'asc') {
            sort($files, SORT_NATURAL);
        }

        if ($options['order'] == 'desc') {
            rsort($files, SORT_NATURAL);
        }

        // Generate HTML        
        $html = '<div class="gallery">';    
        $html .= \Automad\Core\Html::generateImageSet(  
                                                $files, 
                                                $options['width'], 
                                                $options['height'], 
                                                true, 
                                                $options['class']
                                            );

        $html .= '</div>';

        // Return the generated HTML markup to the template parser. 
        return $html;

    }

}

?>
See also