I'm migrating an old theme to a new Class-based setup with Timber. There is a Custom Post Type called "collection". In a loop, I output all collections on an overview page. Each count indicates how many posts are in that particular collection. The title of each collection is used to get the related term with the same name, and then I count the number of posts that have the corresponding tag. Like this:
$term_slug = get_the_title($post->ID, 'title');
$term = get_term_by('name', $term_slug, 'post_tag');
echo $term->count
This is working just great with the old PHP-based templates. Now in the new Timber setup, I tried to call the get_term_by
function directly in my Twig template like this:
{{function('get_term_by', 'name', post.title, 'post_tag', post.id)}}
But this breaks the whole site with an Error 500.
I also tried to use Timbers built-in functions like terms
post.terms( {query:{taxonomy:'post_tag'}}
or get_term
{{function('get_term', 'post_tag')}}
Both just output nothing. I then tried to add it as a custom function like it's suggested in this answer.. I have a Theme.php
file which does all the handling and loading:
// Theme.php
<?php
namespace Mytheme\Theme;
use Timber\Timber;
class Theme {
public function __construct() {
$this->theme = wp_get_theme();
Timber::$dirname = array( 'templates', 'source/views' );
}
public function run() {
// all the other loading stuff and then...
if(class_exists('Timber')) {
add_filter( 'timber/twig', function( \Twig_Environment $twig ) {
$twig->addFunction( new \Timber\Twig_Function( 'myFunction', 'myFunction' ) );
});
}
}
public function myFunction($term_slug, $taxonomy) {
$term = get_term_by('name', $term_slug, $taxonomy);
return $term->count;
}
}
And in my functions.php
i'm instantiating and running it like this:
<?php
require_once( __DIR__ . '/vendor/autoload.php' );
$timber = new Timber\Timber();
// autoload stuff Packages and then...
if (!function_exists('sbx_theme')) {
function sbx_theme()
{
return Swissbeatbox\Theme\Theme::getInstance();
}
}
sbx_theme();
sbx_theme()->run();
This setup is running smoothly but as soon a add myFunction
it fails with the error:
Call to a member function addFunction() on null in ...timber/timber/lib/FunctionWrapper.php on line 75
So even before i even try to call it in Twig. It fails. Also if i put it in the __construct
function the same error remains.
My goal is to either use the built-in Timber functions or call a custom one like:
{ {myFunction(post.title, 'post_tag', post.id) }}
or
{{ function('myFunction', post.title, 'post_tag', post.id) }}
If anyone is running into the same issue, i found a solution. As mentioned here i missed that I'm dealing with a method of the class and that it has to be static. Another detail was, that i needed to pass the instance to the callback.
My Theme.php
looks like this now:
namespace Mytheme\Theme;
use Timber\Timber;
class Theme {
public function __construct() {
$this->theme = wp_get_theme();
Timber::$dirname = array( 'templates', 'source/views' );
add_filter( 'timber/twig', array( $this, 'add_to_twig' ) );
}
public function add_to_twig( $twig ) {
$twig->addFunction(new \Timber\Twig_Function('count_entries', [$this, 'count_entries']));
return $twig;
}
public static function count_entries($term_slug, $taxonomy) {
$term = get_term_by('name', $term_slug, $taxonomy);
return $term->count;
}
}
And in my Twig files, i can now do:
{{ count_entries(post.title, 'post_tag' }}