J'utilise jinja2, et je veux appeler une fonction python comme aide, en utilisant une syntaxe similaire comme si j'appelais une macro. jinja2 semble vouloir m'empêcher de faire un appel de fonction, et insiste pour que je me répète en copiant la fonction dans un modèle sous forme de macro.
Existe-t-il un moyen simple de le faire? Et, y a-t-il un moyen d'importer tout un ensemble de fonctions python et de les rendre accessibles à partir de jinja2, sans passer par beaucoup de rigamarole (comme l'écriture d'une extension)?
from jinja2 import Template ##newline## def clever_function(): ##newline## return "Hello" ##newline## template = Template("{{ clever_function() }}") ##newline## print(template.render(clever_function=clever_function))
Remarque: ceci est spécifique à Flask!
Je sais que cet article est assez ancien, mais il existe de meilleures méthodes pour le faire dans les nouvelles versions de Flask utilisant des processeurs de contexte.
Les variables peuvent être facilement créées:
Ce qui précède peut être utilisé dans un modèle Jinja2 avec Flask comme ceci:
(Quelles sorties
This is an example
)Ainsi que des fonctions à part entière:
Ce qui précède lorsqu'il est utilisé comme ceci:
(Qui sort le prix d'entrée avec le symbole monétaire)
Vous pouvez également utiliser des filtres jinja , cuits dans Flask. Par exemple en utilisant des décorateurs:
Ou, sans décorateurs, et en enregistrant manuellement la fonction:
Les filtres appliqués avec les deux méthodes ci-dessus peuvent être utilisés comme ceci:
la source
__init__.py
en supposant que vousflask.Flask(__name__)
y ayez déclaré .Je pense que jinja rend délibérément difficile l'exécution de python «arbitraire» dans un modèle. Il essaie de renforcer l'opinion selon laquelle moins de logique dans les modèles est une bonne chose.
Vous pouvez manipuler l'espace de noms global dans une
Environment
instance pour ajouter des références à vos fonctions. Cela doit être fait avant de charger des modèles. Par exemple:la source
import utils.helpers env.globals['helpers'] = utils.helpers
{{ clever_function('a', 'b') }}
Vous pouvez également donner la fonction dans les champs selon la réponse de Matroskin
Sortira:
Fonctionne avec Jinja2 version 2.7.3
Et si vous voulez qu'un décorateur facilite la définition des fonctions,
template.globals
consultez la réponse de Bruno Bronoskyla source
J'aime la réponse de @ AJP . Je l'ai utilisé textuellement jusqu'à ce que je me retrouve avec beaucoup de fonctions. Ensuite, je suis passé à un décorateur de fonctions Python .
Les bonnes fonctions ont un
__name__
!la source
Jamais vu un moyen aussi simple dans les documents officiels ou au débordement de pile, mais j'ai été étonné quand j'ai trouvé ceci:
la source
Utilisez un lambda pour connecter le modèle à votre code principal
Ensuite, vous pouvez appeler la fonction de manière transparente dans le modèle
la source
Pour appeler une fonction python depuis Jinja2, vous pouvez utiliser des filtres personnalisés qui fonctionnent de la même manière que les globals: http://jinja.pocoo.org/docs/dev/api/#writing-filters
C'est assez simple et utile. Dans un fichier myTemplate.txt, j'ai écrit:
Et dans un script python:
la source
existe-t-il un moyen d'importer tout un ensemble de fonctions python et de les rendre accessibles à partir de jinja2?
Oui, en plus des autres réponses ci-dessus, cela fonctionne pour moi.
Créez une classe et remplissez-la avec les méthodes associées, par exemple
Ensuite, créez une instance de votre classe dans votre fonction de vue et transmettez l'objet résultant à votre modèle en tant que paramètre de la fonction render_template
Maintenant, dans votre modèle, vous pouvez appeler les méthodes de classe dans jinja comme ceci
la source
Pour importer toutes les fonctions intégrées, vous pouvez utiliser:
Ajoutez
.__dict__
après__builtins__
si cela ne fonctionne pas.Basé sur la réponse de John32323 .
la source
Si vous le faites avec Django, vous pouvez simplement passer la fonction avec le contexte:
Vous pourrez maintenant utiliser la
str
fonction dans le modèle jinja2la source
Il y a une décision beaucoup plus simple.
Ensuite, dans test.html :
la source