Functions
My theme/plugin has some functions I need! Do I really have to re-write all of them?
No, you don’t.
function() #
You can call all PHP functions through function()
in Twig. For example, if you need to call wp_head()
and wp_footer()
, you’d do it like this:
{# single.twig #}
<html>
<head>
<!-- Add whatever you need in the head, and then...-->
{{ function('wp_head') }}
</head>
<!-- etc... -->
<footer>
Copyright © {{ "now"|date('Y') }}
</footer>
{{ function('wp_footer') }}
</body>
</html>
You can also use fn('my_function')
as an alias for function('my_function')
.
function() with arguments #
What if you need to pass arguments to a function? Easy, add them as additional arguments (the first argument will always be the name of the function to call):
{# single.twig #}
<div class="admin-tools">
{{ function('edit_post_link', 'Edit', '<span class="edit-link">', '</span>') }}
</div>
Nice! Any gotchas? Unfortunately yes. While the above example will totally work in a single.twig file it will not in The Loop. Why? Single.twig/single.php retain the context of the current post. A function like edit_post_link
will try to guess the ID of the post you want to edit from the current post in The Loop. the same function requires some modification in a file like archive.twig
or index.twig
. There, you will need to explicitly pass the post ID:
{# index.twig #}
<div class="admin-tools">
{{ function('edit_post_link', 'Edit', '<span class="edit-link">', '</span>', post.ID) }}
</div>
Make functions available in Twig #
If you have functions that you use a lot and want to improve readability of your code, you can make a function available in Twig by using Timber\Twig_Function
inside the timber/twig
filter.
add_filter( 'timber/twig', 'add_to_twig' );
/**
* My custom Twig functionality.
*
* @param \Twig\Environment $twig
* @return \Twig\Environment
*/
function add_to_twig( $twig ) {
// Adding a function.
$twig->addFunction( new Timber\Twig_Function( 'edit_post_link', 'edit_post_link' ) );
return $twig;
} );
Now you can use it like a "normal" function:
{# single.twig #}
<div class="admin-tools">
{{ edit_post_link() }}
</div>
{# Calls edit_post_link using default arguments #}
{# single-my-post-type.twig #}
<div class="admin-tools">
{{ edit_post_link(null, '<span class="edit-my-post-type-link">') }}
</div>
{# Calls edit_post_link with all defaults, except for second argument #}
function_wrapper #
In Timber versions lower than 1.3, you could use function_wrapper
to make functions available in Twig. This method is now deprecated. Instead, use one of the methods above.
Functions that echo output #
The concept of Timber (and templating engines like Twig in general) is to prepare all the data before you pass it to a template. Some functions in WordPress echo their output directly. We don’t want this, because the output of this function would be echoed before we call Timber:render()
and appear before every else on your website. There are two ways to work around this:
- If you have a function where you want to bypass the output and instead save it as a string, so that you can add it to your context, use
Helper::ob_function
. - If you have a function that needs to be called exactly where you use it in your template (e.g. because it depends on certain global values) you can use
FunctionWrapper
:
$context['my_custom_function'] = new FunctionWrapper( 'my_custom_function', $array_of_arguments );