Question

Actuellement, je place ma fonction dans une classe et passer une instance de cette classe en modèle et appeler ma fonction requise en tant que méthode de classe.

{{ unneededclass.blah() }}

Je dois faire comme ci-dessous

{{ blah() }}

Est-il possible?

Était-ce utile?

La solution

Mise à jour 14/05/2015

Commenters dire que je suis la plupart du temps mal. Si vous avez vraiment besoin d'une fonction, et non un filtre ou une macro, vous pouvez le faire comme suggéré dans les docs Brindille :

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

Et l'utilisation comme

{{ blah() }}

En bref, non, cela est impossible.

Cependant, l'espoir est pas perdu!

Filtres

Si cette fonction blah() de la vôtre est destiné à modifier une variable existante, alors il est un Filtre .

Exemple Un:

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

(Le premier argument est la variable que vous filtration, le deuxième est alimentée par des moyens normaux)

macros

Si, comme vous l'avez indiqué ci-dessus, votre fonction simplement sorties HTML, il est un bon candidat pour un macro .

Exemple Un:

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

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

Ou avec des paramètres:

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

Pourquoi?

La chose à retenir est que les modèles Brindille représentent une vue , en termes de MVC. Cela signifie qu'ils sont isolés en fonction de leur environnement, et ne peuvent représenter les contexte vous les passer via le tableau de données que vous passez dans la méthode $template->render().

Ceci est une bonne chose, car il découple votre présentation de votre logique et des données. Si vous pouvez appeler des fonctions arbitrairement, alors vous augmentez soudainement que le couplage, qui est un mauvais chose.

L'autre raison est la façon dont les callbacks poignées PHP. Pensez à la façon dont vous devez passer cette fonction dans votre modèle ... Probablement quelque chose comme ceci:

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

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

Dans votre modèle, la blah variable de contexte est maintenant juste une chaîne contenant 'blah'.

Dans la vanille PHP, lorsque vous utilisez les fonctions variables comme celui-ci (essayez d'utiliser une variable de chaîne comme une fonction), il (plus ou moins) effectue une recherche pour cette fonction, il appelle. Vous êtes pas passer la fonction, juste le nom de lui.

La chose est, vous ne pouvez pas peut-être passer une fonction dans un modèle, car seul mécanisme de PHP pour le faire est par le nom chaîne, et une fois à l'intérieur d'un modèle, ce nom n'est plus un nom de fonction et à seulement string.

Un peu longue haleine, mais j'espère que ça aide!

Si vous voulez plus de documents, les documents officiels sont .

Autres conseils

J'étais aussi perdu que tu étais, mon ami, mais après recherche sur le Web pour une réponse et rien trouvé, j'ai décidé de voir si je pouvais le faire moi-même. Par conséquent, je voulais poster ici ma solution (même si je sais que ce poste est vieux), parce que c'est le premier coup sur google si vous recherchez ce problème.

Ici, il va, il est assez simple en fait:

J'ai fait une classe qui contient mes fonctions et variables, par exemple:

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

Nous avons donc maintenant $ valeurs comme un tableau, qui contient cet objet avec une fonction « getRandomNumber () ».

Lors du rendu du fichier modèle, inclure cette classe comme valeur:

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

De cette façon, à l'intérieur du fichier modèle, vous pouvez simplement appeler cette méthode pour appeler la fonction et obtenir votre résultat:

{{ functions.getRandomNumber }}

Bien que vous ne pouvez pas PHP appelable directement, brindille est extensible. Vous pouvez ajouter un filtre appelable, de sorte que vous pouvez appliquer aux fonctions PHP passées à modèle.

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

}

Maintenant, si vous passez my_func à un template, vous pouvez le faire my_func|call(arg1, arg2). Vous pouvez même faire des fonctions d'ordre supérieur "array_filter"|call(my_array, my_func) et vous pouvez toujours faire plus de choses dans le filtre comme tableau d'accepter en tant que paramètres et ainsi de suite.

réponse complète: http://twig.sensiolabs.org/doc/advanced.html#id2

Je préfère utiliser Brindille Extension comme ceci:

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

modèle:

{{ sidebar_menu('some text') }}

Utilisation Anonyme classe

Créer une classe anonyme gestionnaire / contrôleur / services ..

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

Coller le paramètre dans la vue

$params=[
            'functions' => $functions

        ];



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

Utilisez la fonction en vue

 {% set rowUrl = functions.rowUrl(entity) %}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top