问题
I've been trying to get a custom function working by using the example in the Timber starter theme, and following the instructions in the Timber docs, but I can't for the life of me get this working.
My functions.php is like so:
class StarterSite extends TimberSite {
...
function my_function() {
return "Foo";
}
function add_to_twig( $twig ) {
/* this is where you can add your own functions to twig */
$twig->addExtension( new Twig_Extension_StringLoader() );
$twig->addFilter('my_function', new Twig_SimpleFilter('my_function', array($this, 'my_function')));
return $twig;
}
}
Then my Twig file:
{{ my_function }}
This returns
Twig_Error_Syntax: Unknown "my_function" function
So I've tried with my Twig being like
{{ function (my_function) }}
And that returns
Warning: call_user_func_array() expects parameter 1 to be a valid callback, no array or string given
I've also tried with my functions.php code like so:
function add_to_twig( $twig ) {
/* this is where you can add your own functions to twig */
$twig->addExtension( new Twig_Extension_StringLoader() );
$twig->addFunction( new Timber\Twig_Function( 'my_function', 'my_function' ) );
return $twig;
}
And that one returns
Error: Call to a member function addFunction() on null
Clearly I'm missing a core concept somewhere, but I don't know where to start. None of the searches I've made around this seem to apply to my situation.
Can anyone point me in the right direction?
回答1:
When adding functionality to Twig, you’ll have to use the timber/twig
filter. If you only define an add_to_twig
method in your class, nothing will happen.
So you’d need something like the following
class StarterSite extends Timber\Site {
public function __construct() {
parent::__construct();
add_filter( 'timber/twig', array( $this, 'add_to_twig' ) );
}
…
}
Make a function available in Twig
Now let’s look at your add_to_twig
method. When you want to add a function, you need to use addFunction
instead of addFilter
. So in your case, it should probably be
$twig->addFunction( new Timber\Twig_Function(
'my_function',
array( $this, 'my_function' )
) );
When you use {{ my_function }}
, Twig probably looks for a value my_function
in the context. I’d explicitly call it like a function: {{ my_function() }}
.
Call a function through function()
When you want to call the function directly through {{ function(my_function) }}
, then you need to pass the function name as a string:
{{ function('my_function') }}
However, because you defined my_function
as a method of your StarterSite
class, you need to tell Twig where it can find that function:
{{ function(['StarterSite', 'my_function']) }}
But! When you call a class method from Twig like that, then the method needs to be static. So you’d have to define my_function
like this in your class:
class StarterSite extends Timber\Site {
…
public static function my_function() {
return "Foo";
}
…
}
timber/twig
filter in the global context
If you add add_to_twig
(together with the timber/twig
filter) to your functions.php, it could work as well, but then you’d also need to call my_function
as a method of your StarterSite
class. Again, you can do that using the array notation:
function add_to_twig( $twig ) {
$twig->addFunction( new Timber\Twig_Function(
array( 'StarterSite', 'my_function' ),
array( $this, 'my_function' )
) );
return $twig;
}
I hope this clears things up. There are a lot possibilities to call functions in Twig, the easiest is always to define the function you want to call in the global context (e.g. directly in functions.php) and then call it through function('my_function').
来源:https://stackoverflow.com/questions/47467244/using-custom-functions-with-timber