В настоящее время я помещаю свою функцию в класс и передаю экземпляр этого класса в шаблон и вызываю свою нужную функцию как метод класса.
{{ 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 для этого – по имени-строке, а один раз внутри шаблона это имя больше не является именем функции и просто строкой.
Немного длинный, но я надеюсь, что это поможет!
Если вам нужна дополнительная документация, официальные документы здесь .
Я был так же потерян, как и ты, мой друг, но, после поиска в Интернете ответа и не нашел его, я решил посмотреть, смогу ли я сам это сделать. Поэтому я хотел опубликовать свое решение здесь (хотя я знаю, что этот пост старый), потому что это первый хит в google, если вы ищете эту проблему.
Вот так, на самом деле это довольно просто:
Я создал класс, который содержит мои функции и переменные, например:
class functionContainer{ function getRandomNumber() { return rand(); } } $values = array( 'functions'=> new functionContainer() );
Итак, теперь мы имеем $ values как массив, который содержит этот объект с функцией «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') }}