Custom Functions

Custom functions provide a quick and easy way to add your own functionality to a theme using plain PHP. In contrast to extensions, custom functions are not meant to be distributed as separate packages. Instead, they live right inside your theme and can be defined in a single statement without the need for any class files or autoloading setup. Once defined, a custom function is used in templates just like any other function.

<@ myFunction { key: 'value' } @>

Defining Functions

Custom functions are registered using the global func() helper. It expects the name of the function as the first argument and a callable as the second one. The callable receives the options that are passed in the template as an array as well as the Automad instance, which provides access to all content and core features. Whatever string is returned by the callable is rendered in place of the statement. The following example is taken from the Starter Kit and returns the markup of an SVG icon that is stored in the icons directory of the theme:

<?php

use Automad\Core\Automad;

func('icon', function (array $options, Automad $Automad): string {
  $icon = file_get_contents(__DIR__ . '/../icons/' . $options['name'] . '.svg');

  return $icon;
});

A good practice is to collect all custom functions of a theme in one file, for example lib/functions.php as it is done in the Starter Kit. That file can then simply be included at the top of your base template. Using the ~ modifier prevents unwanted whitespace in the output:

<@~ lib/functions.php ~@>

Using Functions

After registering a function, it can be called in any template. Options are passed in the same relaxed JSON format as for all other functions and can of course also contain variables and filters.

<@ icon { name: 'arrow-left' } @>
<@ icon { name: @{ selectIcon | def ('menu') } } @>

Note that custom functions share their names with snippets, built-in functions and extensions. Since snippets and built-in functions take precedence over custom functions, choose names that don't conflict with existing ones.

Accessing Content

The Automad instance that is passed as second argument can be used to access the current context page as well as any other page of the site:

<?php

use Automad\Core\Automad;

func('parentTitle', function (array $options, Automad $Automad): string {
  $Page = $Automad->Context->get();
  $Parent = $Automad->getPage($Page->parentUrl);

  return $Parent ? $Parent->get('title') : '';
});

Rendering Templates

In combination with the global inc() helper, custom functions can also be used to dynamically choose and render template files. The inc() function loads a template file, renders it within the current context and returns the generated output. The following example is taken from the Standard Lite theme, where it is used to render a pagelist using a layout that can be selected in the dashboard:

<?php

use Automad\Core\Automad;

func('pagelistLayout', function (array $options, Automad $Automad): string {
  $layout = __DIR__ . '/../blocks/pagelist/' . $options['layout'] . '.php';

  return inc($layout, $Automad);
});
<@ pagelistLayout { layout: @{ selectPagelistLayout | def ('masonry') } } @>

Custom Functions vs. Extensions

Custom functions are the perfect choice for small helpers that are specific to a single theme. In case you want to share your functionality across multiple themes or sites, publish it as a separate package or include CSS and JavaScript assets automatically, consider developing a generic extension instead.

set Collections