Using custom functions with Timber

岁酱吖の 提交于 2020-04-10 06:10:29

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!