Pregunta

Actualmente pongo mi función en una clase y pasar una instancia de esta clase en la plantilla y llamar a mi función requerida como un método de clase.

{{ unneededclass.blah() }}

tengo que hacer, como a continuación

{{ blah() }}

¿Es posible?

¿Fue útil?

Solución

Actualización del 05/14/2015

Los comentaristas señalan que estoy sobre todo mal. Si realmente necesita una función, y no un filtro o macro, puede hacerlo como sugerido en la documentación de Twig :

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

Y el uso como

{{ blah() }}

En resumen, no, esto no es posible.

Sin embargo, la esperanza no se pierde!

Filtros

Si esta función blah() tuya está destinado a modificar una variable existente, entonces es un filtro .

Un ejemplo:

//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') }}

(El primer argumento es la variable que está filtrando, el segundo se suministra por medios normales)

Macros

Si, como se ha indicado anteriormente, su función simplemente salidas HTML, entonces es un candidato bueno para un macro .

Un ejemplo:

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

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

O con los parámetros:

{% 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') }}

¿Por qué?

Lo que hay que recordar es que las plantillas Twig representan una vista , en términos de la MVC. Esto significa que están aislados en función de su entorno, y sólo pueden representar el Contexto que ellos pasan a través de la matriz de datos que se pasa en el método $template->render().

Esto es una cosa buena, ya que desacopla la presentación de su lógica y datos. Si se puede llamar de forma arbitraria funciones, a continuación, se aumenta de repente que el acoplamiento, que es un mal cosa.

La otra razón de esto es la forma en que maneja el PHP devoluciones de llamada. Piense en cómo se tendría que pasar esa función en su plantilla ... Probablemente algo como esto:

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

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

En su plantilla, la variable de contexto blah es ahora sólo un 'blah' que contiene cadena.

En la vainilla PHP, cuando se utiliza funciones variables como esto (trate de usar una variable de cadena como una función), que (más o menos) realiza una búsqueda para esa función, y luego lo llama. Estás no que pasa a la función, simplemente su nombre.

La cosa es, no es posible que pase una función en una plantilla, ya que solo mecanismo de PHP para hacer esto es por su nombre cuerdas, y una vez dentro de una plantilla, ese nombre ya no es un nombre de función y sólo una cadena.

bit de largo aliento Un poco, pero espero que ayude!

Si desea obtener más documentación, los documentos oficiales son aquí .

Otros consejos

Me estaba tan perdido como estabas, mi amigo, pero después de buscar en la web para una respuesta y no encontró ninguno, decidí ver si podía hacerlo yo mismo. Por lo tanto, quería publicar mi solución aquí (aunque sé que este post es viejo), porque este es el primer éxito en Google si se busca para este problema.

A continuación se vaya, es bastante simple en realidad:

Me hizo una clase que contiene mis funciones y variables, por ejemplo:

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

Así que ahora tenemos $ valores como una matriz, que contiene este objeto con una función de "GetRandomNumber ()".

Al procesar el archivo de plantilla, incluye esta clase como un valor:

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

De esta manera, dentro del archivo de plantilla, sólo puede llamar a este método para llamar a la función y obtener su resultado:

{{ functions.getRandomNumber }}

A pesar de que no se puede PHP ejecutable directamente, ramita es extensible. Puede añadir un filtro exigible, por lo que puede aplicarse a las funciones de PHP se pasan a la plantilla.

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);
    }

}

Ahora bien, si se pasa my_func variable para plantilla, se puede hacer my_func|call(arg1, arg2). Incluso se puede hacer funciones de orden superior "array_filter"|call(my_array, my_func) y siempre se puede hacer más cosas en el filtro como aceptar matriz como parámetros y así sucesivamente.

Respuesta completa: http://twig.sensiolabs.org/doc/advanced.html#id2

Yo prefiero usar la ramita de extensión de esta manera:

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';
    }
}

En la plantilla:

{{ sidebar_menu('some text') }}

Uso de la clase Anónimo

Crear clase anónima en el gestor / controlador / servicio ..

     $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' => ...]);
    }
};

Pegar parámetro a la vista

$params=[
            'functions' => $functions

        ];



    return new Response($this->twig->render('...:index.html.twig', $params));

Usar función en la vista

 {% set rowUrl = functions.rowUrl(entity) %}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top