web-dev-qa-db-fra.com

Comment obtenir la liste de toutes les variables dans les modèles Jinja 2

J'essaie d'obtenir une liste de toutes les variables et des blocs dans un modèle. Je ne veux pas créer mon propre analyseur pour trouver des variables. J'ai essayé d'utiliser l'extrait de suite.

from jinja2 import Environment, PackageLoader
env = Environment(loader=PackageLoader('gummi', 'templates'))
template = env.get_template('chat.html')

template.blocks est dict où les clés sont des blocs, comment puis-je obtenir toutes les variables à l'intérieur des blocs?

31
Kracekumar

Puisque personne n'a répondu à la question et j'ai trouvé la réponse

from jinja2 import Environment, PackageLoader, meta
env = Environment(loader=PackageLoader('gummi', 'templates'))
template_source = env.loader.get_source(env,   'page_content.html')[0]
parsed_content = env.parse(template_source)
meta.find_undeclared_variables(parsed_content)

Cela produira une liste de variables non déclarés car cela n'est pas exécuté au moment de l'exécution, il produira une liste de toutes les variables.

Remarque: cela produira des fichiers HTML inclus à l'aide de include et extends.

49
Kracekumar

J'ai eu le même besoin et j'ai écrit un outil appelé Jinja2schema . Il fournit un algorithme heuristique pour inférer des types de modèles Jinja2 et peut également être utilisé pour obtenir une liste de toutes les variables de modèle, y compris les imbriquées.

Voici un court exemple de faire ça:

>>> import jinja2
>>> import jinja2schema
>>>
>>> template = '''
... {{ x }}
... {% for y in ys %}
...     {{ y.nested_field_1 }}
...     {{ y.nested_field_2 }}
... {% endfor %}
... '''
>>> variables = jinja2schema.infer(template)
>>>
>>> variables
{'x': <scalar>,
 'ys': [{'nested_field_1': <scalar>, 'nested_field_2': <scalar>}]}
>>>
>>> variables.keys()
['x', 'ys']
>>> variables['ys'].item.keys()
['nested_field_2', 'nested_field_1']
9
aromanovich

Pour mon thème pélican, j'ai créé un outil d'analyse de toutes les variables de Jinja dans mes fichiers de modèles.

Je partage mon code

Ce script génère une configuration d'échantillon à partir de toutes les variables existant dans les fichiers de modèle et obtenez une variables de mon pelicanconf.py officiel

La fonction qui extrait toutes les variables du fichier de modèle

def get_variables(filename):
    env = Environment(loader=FileSystemLoader('templates'))
    template_source = env.loader.get_source(env, filename)[0]
    parsed_content = env.parse(template_source)

Le script complet

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# use:
# generate_pelicanconf-sample.py my_official_blog/pelicanconf.py

import sys
import imp
import os

from jinja2 import Environment, FileSystemLoader, meta


# Search all template files
def list_html_templates():
    dirList = os.listdir('templates')

    return dirList


# get all variable in template file
def get_variables(filename):
    env = Environment(loader=FileSystemLoader('templates'))
    template_source = env.loader.get_source(env, filename)[0]
    parsed_content = env.parse(template_source)

    return meta.find_undeclared_variables(parsed_content)


# Check if the pelicanconf.py is in param
if len(sys.argv) != 2:
    print("Please indicate the pelicanconf.py file")
    sys.exit()

# Get all vars from templates files
all_vars = set()
files = list_html_templates()
for fname in files:
    variables = get_variables(fname)
    for var in variables:
        if var.isupper():
            all_vars.add(var)

m = imp.load_source('pelicanconf', sys.argv[1])

# Show pelicanconf.py vars content
for var in all_vars:
    varname = 'm.%s' % var
    if var in m.__dict__:
        print ("%s = %s" % (var, repr(m.__dict__[var])))


    return meta.find_undeclared_variables(parsed_content)

Le résultat de ce programme

LINKS = ((u'Home', u'/'), (u'archives', u'/archives.html'), (u'tags', u'/tags.html'), (u'A propos', u'http://bruno.adele.im'))
SITESUBTITLE = u'Une famille compl\xe8tement 633<'
DEFAULT_LANG = u'fr'
SITEURL = u'http://blog.jesuislibre.org'
AUTHOR = u'Bruno Adel\xe9'
SITENAME = u'Famille de geeks'
SOCIAL = ((u'adele', u'http://adele.im'), (u'feed', u'http://feeds.feedburner.com/FamilleDeGeek'), (u'Twitter', u'http://Twitter.com/jesuislibre.org'), (u'google+', u'https://plus.google.com/100723270029692582967'), (u'blog', u'http://blog.jesuislibre.org'), (u'facebook', u'http://www.facebook.com/bruno.adele'), (u'flickr', u'http://www.flickr.com/photos/b_adele'), (u'linkedin', u'http://fr.linkedin.com/in/brunoadele'))
FEED_DOMAIN = u'http://blog.jesuislibre.org'
FEED_ALL_ATOM = u'feed.atom'
DISQUS_SITENAME = u'blogdejesuislibreorg'
DEFAULT_PAGINATION = 10
GITHUB_BLOG_SITE = u'https://github.com/badele/blog.jesuislibre.org'

Pour plus de déstail de ce script, voir https://github.com/badele/pelican-theme-jesuislibre

5
Bruno Adelé

Voir Documentation Jinja2 Meta API pour plus de détails

3
Sarath

Solution: https://gist.github.com/sxslex/822bd2405885294747B86AAC187F1AA8

def template(html, **params):
    import jinja2
    env = jinja2.Environment(loader=FileSystemLoader(''))

    def tojson(s):                                       
        import json
        return json.dumps(s)
    env.filters['tojson'] = tojson
    template = env.from_string(html)
    return template.render(context=params, **params)

print(template('{{ context|tojson }}', name='slex', value=39 ))
1
SleX