Twig-機能をテンプレートに渡します
-
02-10-2019 - |
質問
現在、私は自分の関数をクラスに配置し、このクラスのインスタンスをテンプレートに渡し、必要な関数をクラスメソッドとして呼び出します。
{{ unneededclass.blah() }}
以下のようにする必要があります
{{ blah() }}
出来ますか?
解決
更新5/14/2015
コメンターは、私がほとんど間違っていると指摘しています。フィルターやマクロではなく機能が本当に必要な場合は、 Twig Docsで提案されています:
$twig = new Twig_Environment($loader);
$function = new Twig_SimpleFunction('blah', function () {
// ...
});
$twig->addFunction($function);
のように使用します
{{ blah() }}
要するに、いいえ、これは不可能です。
しかし、希望は失われません!
フィルター
この機能の場合 blah()
あなたのものは既存の変数を変更することを目的としています、そしてそれは フィルター.
例:
//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に関して。これは、それらが環境の観点から隔離されていることを意味し、 コンテクスト あなたが渡すデータアレイを介してそれらを渡します $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'
.
Vanilla PHPでは、このような変数関数を使用する場合(関数のような文字列変数を使用してみてください)、(多かれ少なかれ)その関数の検索を実行してから呼び出します。あなたは いいえ 関数を渡すと、名前だけです。
問題は、これを行うためのPHPの唯一のメカニズムは名前のストリングによるものであり、テンプレート内にあると、その名前は関数名ではなく、文字列だけであるため、機能をテンプレートに渡すことはできません。
少し長く巻き込まれましたが、それが役立つことを願っています!
もっとドキュメントが必要な場合は、公式のドキュメントは ここ.
他のヒント
私はあなたと同じように迷子になりましたが、私の友人でしたが、答えを求めてウェブを検索して、何も見つけなかったので、自分でできるかどうかを確認することにしました。したがって、この問題を検索するとGoogleで最初のヒットだからです。
ここに行くと、実際には非常に簡単です:
たとえば、機能と変数を含むクラスを作成しました。
class functionContainer{
function getRandomNumber()
{
return rand();
}
}
$values = array(
'functions'=> new functionContainer()
);
したがって、このオブジェクトが関数「getRandomNumber()」を含むこのオブジェクトを含む配列として$値があります。
テンプレートファイルをレンダリングするときは、このクラスを値として含めます。
$twig->render('random.html', $values);
これにより、テンプレートファイル内で、このメソッドを呼び出して関数を呼び出して結果を得ることができます。
{{ functions.getRandomNumber }}
PHPを直接呼び出すことはできませんが、小枝は拡張可能です。呼び出し可能なフィルターを追加できるため、テンプレートに渡された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
私はこのような小枝拡張機能を使用することを好みます:
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') }}
使用 匿名クラス
マネージャー/コントローラー/サービスで匿名クラスを作成します。
$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) %}