Generic Extensions

In case you are missing an advanced feature while developing themes using the template language, you can implement that functionality as a generic extension written in plain PHP. Generic extensions have full access to all content and core features and can be used in any template of any theme.

<@ Vendor/Extension { key: 'value' } @>

Package Structure

Like themes, generic extensions are added to an Automad installation in form of a package. There are two types of extension packages: local packages and Composer packages. The main difference between them is the way PHP classes are loaded.

Local Packages

The minimal structure of a local extension package is a directory for your namespace inside the packages directory, containing a directory for your extension that shares the same name as the PHP file inside. Note that all file and directory names must be lowercase.

packages/
  vendor/
    extension/
      extension.php

According to the directory structure above, the PHP file of the extension looks like this:

<?php

// The namespace corresponds to the directory structure.
namespace Vendor;

use Automad\Core\Automad;

// Prevent direct access.
defined('AUTOMAD') or die('Direct access not permitted!');

// The class name corresponds to the extension directory and file name.
class Extension {
  // The main method must have the same name as the class.
  public function Extension(array $options, Automad $Automad): string {
    // Your extension code goes here.
    return '';
  }
}

Now the extension can be used in templates as follows:

<@ Vendor/Extension { key: 'value' } @>

When an extension is called, Automad converts the given name into a class name, in this case \Vendor\Extension. In case that class is not loaded yet, Automad looks for the file packages/vendor/extension/extension.php, which is the lowercase version of the full name followed by the class name.

Composer Packages

In Composer packages, classes are loaded by the autoloader of Composer. Therefore you are more flexible regarding the file structure of your package. The only important convention is that the main method has the same name as the class. Extensions that are loaded by Composer are called in templates by the combination of their namespace and their class name.

To make sure that your extension is loaded correctly by Composer, add a composer.json file with the following content to the root of your package:

{
  "name": "vendor/extension",
  "description": "The extension description ...",
  "type": "automad-package",
  "keywords": ["extension"],
  "license": "MIT",
  "require": {
    "automad/package-installer": "^1.1"
  },
  "autoload": {
    "classmap": [""]
  }
}

Find more information about publishing extensions on the packages page.

Options

When an extension is called in a template, two arguments are always passed to the main method:

  1. An associative array of $options that are defined in the template. Variables and filters in the options are already resolved.
  2. The $Automad object that provides access to all pages and data, as described on the inline PHP page.

It is good practice to merge the given options with a set of defaults:

public function Extension(array $options, Automad $Automad): string {
  $options = array_merge(
    array(
      'class' => 'extension',
      'limit' => 5
    ),
    $options
  );

  $Page = $Automad->Context->get();

  return '<div class="' . $options['class'] . '">' . $Page->get('title') . '</div>';
}

Return Values

The main job of an extension is to generate some kind of markup. The template engine inserts the value that is returned by the main method into the rendered template. Therefore all extensions should end with a return statement that returns a string.

Loading Assets

In case your extension requires JavaScript or CSS files, Automad takes care of loading them. All .js and .css files that are located in the same directory as the extension's class file, not in subdirectories, are automatically added to the <head> of a page as soon as the extension is used. In order to prevent files from being loaded automatically, you can place them in a subdirectory instead.

Minified Files

In case minified versions of your files ending with .min.js or .min.css are stored alongside the uncompressed ones, Automad only loads the minified files and skips the uncompressed ones in order to avoid loading assets twice.

Extensions Custom Filters