23

現在、関数をクラスに配置し、このクラスのインスタンスをテンプレートに渡し、必要な関数をクラス メソッドとして呼び出します。

{{ unneededclass.blah() }}

私は以下のようにする必要があります

{{ blah() }}

出来ますか?

4

5 に答える 5

33

2015 年 5 月 14 日更新

コメント投稿者は、私がほとんど間違っていると指摘しています。フィルターやマクロではなく、本当に関数が必要な場合は、Twig docs で提案されているように実行できます。

$twig = new Twig_Environment($loader);
$function = new Twig_SimpleFunction('blah', function () {
   // ...
});
$twig->addFunction($function);

そして、のように使用します

{{ blah() }}

要するに、いいえ、これは不可能です。

しかし、希望は失われません!

フィルター

あなたのこの関数blah()が既存の変数を変更することを意図している場合、それはfilterです。

例:

//in your PHP
function format_date($date_string,$format_string) {
    return date($format_string,strtotime($date_string));
}
$twig_env->addFilter('format_date',new Twig_Filter_Function('format_date'));

{# in your template #}
{{ some_date|format_date('n/j/Y') }}

(最初の引数はフィルタリングする変数で、2 番目の引数は通常の方法で提供されます)

マクロ

上で示したように、関数が単純に HTML を出力する場合、それはマクロの良い候補です。

例:

{# in your template #}
{% macro say_hello() %}
<p>Oh! Hello, world!</p>
{% endmacro %}

{# ... later on ... #}
{{ _self.say_hello() }}

またはパラメータ付き:

{% macro input(name,value,type) %}
<input type="{{ type|default('text') }}" name="{{ name }}" value="{{ value }}">
{% endmacro %}

{{ _self.input('phone_number','867-5309') }}
{{ _self.input('subscribe','yes','checkbox') }}

なんで?

覚えておくべきことは、MVC に関して、 Twig テンプレートはビューを表すということです。これは、それらが環境の観点から分離されていることを意味し、メソッドで渡すデータ配列を介して渡すコンテキスト$template->render()のみを表すことができます。

これは、プレゼンテーションをロジックやデータから分離するため、良いことです。関数を任意に呼び出すことができる場合、その結合が突然増加しますが、これは悪いことです。

これのもう 1 つの理由は、PHP がコールバックを処理する方法です。その関数をテンプレートに渡す方法を考えてみてください...おそらく次のようなものです:

function blah() {
    return "<p>Oh! Hello, world!</p>";
}

$template = $twig_env->loadTemplate('template.html');
echo $template->render(array('blah'=>'blah'));

テンプレートでは、コンテキスト変数blahは、'blah'.

通常の PHP では、このような変数関数を使用すると (関数のような文字列変数を使用してみてください)、(多かれ少なかれ) その関数のルックアップを実行してから呼び出します。関数を渡しているのではなく、名前だけです。

問題は、関数をテンプレートに渡すことができないということです。これを行うための PHP の唯一のメカニズムは名前文字列によるものであり、テンプレート内に入ると、その名前は関数名ではなく単なる文字列になります。

少し長くなりましたが、お役に立てば幸いです!

さらにドキュメントが必要な場合は、公式ドキュメントがここにあります。

于 2010-08-29T18:06:55.783 に答える
7

PHP を直接呼び出し可能にすることはできませんが、twig は拡張可能です。呼び出し可能なフィルターを追加できるため、テンプレートに渡された PHP 関数に適用できます。

namespace My\Twig\Extension;

class LambdaFilter extends \Twig_Extension {

    public function getName() {
        return 'lambda_filter';
    }

    public function getFilters() {
        return array(
            new \Twig_SimpleFilter('call', array($this, 'doCall'))
        );
    }

    public function doCall() {
        $arguments = func_get_args();
        $callable = array_shift($arguments);
        if(!is_callable($callable)) {
            throw new InvalidArgumentException();
        }
        return call_user_func_array($callable, $arguments);
    }

}

テンプレートに変数my_funcを渡すと、次のことができますmy_func|call(arg1, arg2)。高次関数"array_filter"|call(my_array, my_func)を実行することもできます。また、配列をパラメーターとして受け入れるなど、常にフィルターでより多くのことを実行できます。

于 2014-03-25T15:03:59.150 に答える
6

友達のあなたと同じように迷子になりましたが、ウェブで答えを探しても何も見つからなかったので、自分でできるかどうかを確認することにしました。したがって、この問題を検索した場合、これがグーグルでの最初のヒットであるため、私はここに私の解決策を投稿したいと思いました(この投稿は古いことを知っていますが)。

これで、実際には非常に簡単です。

関数と変数を含むクラスを作成しました。次に例を示します。

class functionContainer{
        function getRandomNumber()
        {
                return rand();
        }
}
$values = array(
'functions'=> new functionContainer()
);

これで、$ valuesが配列として作成されました。このオブジェクトには、関数「getRandomNumber()」を持つこのオブジェクトが含まれています。

テンプレートファイルをレンダリングするときは、このクラスを値として含めます。

$twig->render('random.html', $values);

このように、テンプレートファイル内で、このメソッドを呼び出すだけで関数を呼び出し、結果を取得できます。

{{ functions.getRandomNumber }}
于 2012-08-15T14:12:41.210 に答える
2

完全な回答: http://twig.sensiolabs.org/doc/advanced.html#id2

私は次のようにTwig Extensionを使用することを好みます:

namespace Some\Twig\Extensions;

class MenuExtensions extends \Twig_Extension
{
    public function getFunctions()
    {
        return array(
            new \Twig_SimpleFunction('sidebar_menu', [$this, 'generate_sidebar_menu']),
        );
    }

    public function generate_sidebar_menu($menu){
        return $menu;
    }

    public function getName()
    {
        return 'menu';
    }
}

テンプレート内:

{{ sidebar_menu('some text') }}
于 2013-09-30T14:08:40.663 に答える