В настоящее время я помещаю свою функцию в класс и передаю экземпляр этого класса в шаблон и вызываю свою требуемую функцию как метод класса.
{{ unneededclass.blah() }}
Мне нужно сделать, как показано ниже
{{ blah() }}
Возможно ли это?
В настоящее время я помещаю свою функцию в класс и передаю экземпляр этого класса в шаблон и вызываю свою требуемую функцию как метод класса.
{{ unneededclass.blah() }}
Мне нужно сделать, как показано ниже
{{ blah() }}
Возможно ли это?
Комментирующие отмечают, что я в основном ошибаюсь. Если вам действительно нужна функция, а не фильтр или макрос, вы можете сделать это, как было предложено в документах Twig:
$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') }}
(Первый аргумент - это переменная, которую вы фильтруете, вторая - обычным способом)
Если, как вы указали выше, ваша функция просто выводит 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()
.
Это хорошо, поскольку он отделяет вашу презентацию от вашей логики и данных. Если вы можете произвольно называть функции, то вы внезапно увеличиваете эту связь, что плохо.
Другая причина в том, как 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, это имя-строка и один раз внутри шаблона, это имя больше не является именем функции и просто строка.забастовкa >
Немного длинный, но я надеюсь, что это поможет!
Если вам нужна дополнительная документация, официальные документы здесь.
Я был так же потерян, как и ты, мой друг, но после поиска в Интернете ответа и не нашел его, я решил посмотреть, смогу ли я сделать это сам. Поэтому я хотел опубликовать свое решение здесь (хотя я знаю, что этот пост старый), потому что это первый хит в 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 exnteds \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') }}