現在、関数をクラスに配置し、このクラスのインスタンスをテンプレートに渡して、必要な関数をクラスメソッドとして呼び出しています。
{{ unneededclass.blah() }}
私は以下のようにする必要があります
{{ blah() }}
出来ますか?
コメント提供者は、私がほとんど間違っていると指摘しています。フィルターやマクロではなく関数が本当に必要な場合は、 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') }}
_
覚えておくべきことは、TwigテンプレートはMVCの観点からビューを表すということです。これは、それらがで分離されていることを意味します。それらの環境の用語であり、$template->render()
メソッドで渡すデータ配列を介して渡すcontextのみを表すことができます。
これは、プレゼンテーションをロジックやデータから切り離すので、良いことです。関数を任意に呼び出すことができる場合は、その結合を突然増やします。これは悪いことです。
これの他の理由は、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の唯一のメカニズムは名前文字列によるものであり、テンプレート内に入ると、その名前は関数名ではなく単なる文字列であるため、関数をテンプレートに渡すことはできません。
少し長めですが、お役に立てば幸いです。
より多くのドキュメントが必要な場合、公式ドキュメントは ここ です。
友達、あなたと同じように迷子になりましたが、ウェブで答えを探しても何も見つからなかったので、自分でできるかどうかを確認することにしました。したがって、この問題を検索した場合、これがグーグルでの最初のヒットであるため、私はここに私の解決策を投稿したいと思いました(この投稿は古いことを知っていますが)。
これで、実際には非常に簡単です。
私は自分の関数と変数を含むクラスを作りました、例えば:
class functionContainer{
function getRandomNumber()
{
return Rand();
}
}
$values = array(
'functions'=> new functionContainer()
);
これで、配列として$ valuesがあり、このオブジェクトには関数「getRandomNumber()」が含まれています。
テンプレートファイルをレンダリングするときは、このクラスを値として含めます。
$twig->render('random.html', $values);
このように、テンプレートファイル内で、このメソッドを呼び出して関数を呼び出し、結果を取得できます。
{{ functions.getRandomNumber }}
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)
を実行することもでき、配列をパラメーターとして受け入れるなど、フィルターで常により多くのことを実行できます。
完全な答え: http://twig.sensiolabs.org/doc/advanced.html#id2
私はTwig次のような拡張機能を使用することを好みます:
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') }}
使用 匿名クラス
Manager/controller/serviceに匿名クラスを作成します。
$functions = new class($router)
{
public function __construct($router)
{
$this->router = $router;
}
public function getRowUrl(FileManager $fileManager)
{
if ($fileManager->isNode()) {
return $this->router->generate('...', ['parent' => ...]);
}
return $this->router->generate('...', ['entity' => ...]);
}
};
パラメータをビューに貼り付けます
$params=[
'functions' => $functions
];
return new Response($this->twig->render('...:index.html.twig', $params));
ビューで関数を使用
{% set rowUrl = functions.rowUrl(entity) %}