Custom Integrations
The new Integrations API (available from Timber 2.0) provides a generalized way to integrate with third-party plugins.
It’s how, for example, the built-in Advanced Custom Fields integration is implemented: There is nothing in the Timber core (i.e. Timber\Timber
) that "knows" about ACF. All the convenient meta
mapping and stuff gets hooked in by a single class (Timber\Integration\AcfIntegration
).
To achieve this, that class implements an interface: Timber\Integrations\IntegrationInterface
:
namespace Timber\Integration;
interface IntegrationInterface
{
public function should_init(): bool;
public function init(): void;
}
A simple example #
There are two main steps to a custom Timber integration:
- Define a class that implements
Timber\Integration\IntegrationInterface
. - Add your class’s name to the list of integrations using the
timber/integrations
filter.
This is the simplest way to run your integration code when the plugin is activated and provide a safe fallback to core Timber behavior when it’s not.
Implementing IntegrationInterface #
Here’s a simplified example of the ACF integration. Timber defines and adds an AcfIntegration
automatically, but for illustration purposes, let’s rename it MyAcfIntegration
.
namespace MyProject;
use ACF;
/**
* Class used to handle integration with Advanced Custom Fields
*/
class MyAcfIntegration implements IntegrationInterface
{
public function should_init(): bool
{
return class_exists(ACF::class);
}
public function init(): void
{
// Hook into Timber’s post meta logic.
add_filter('timber/post/pre_meta', [$this, 'post_get_meta_field'], 10, 5);
}
public static function post_get_meta_field($value, $post_id, $field_name, $post, $args)
{
$args = wp_parse_args($args, [
// Apply formatting logic (defined when configuring the field).
'format_value' => true,
]);
// NOTE: get_field() is defined by ACF itself. We’re simply delegating.
return get_field($field_name, $post_id, $args['format_value']);
}
}
This tells Timber two important things:
First, the should_init()
method tells Timber to initialize this integration (i.e. call init()
) if Advanced Custom Fields is activated (in which case the ACF
class will exist). In your own integration, this should return true
if and only if the plugin of choice is activated. Choosing a reasonable check to make is up to you, and will of course depend on the plugin.
Second, init()
extends Timber’s core logic, in this case the timber/post/pre_meta
hook, which is called internally in Timber\Post
before the core WordPress function get_post_meta()
is called. This ensures that Timber will always prefer ACF’s behavior over the normal WP way.
There are many actions and filters to hook into: For your integration, find the ones you need to override and call them from your init()
method.
Note this is the simplified version, favoring brevity over completeness. The actual ACF integration has to handle more than this.
Adding your integration #
The hard part’s over. Now you need to tell Timber about your class:
functions.php
use MyProject\MyAcfIntegration;
add_filter('timber/integrations', function (array $integrations): array {
$integrations[] = new MyAcfIntegration();
return $integrations;
});
Timber will call the method(s) you defined and initialize your integration if applicable.