I have following jinja template in variable code:
code = """{% set p1 = 'hello world' %}
<p>{{p1}}</p>"""
I am getting parsed template using parse method,
from jinja2 import Environment
env = Environment()
template = env.parse(code)
now, how to get the original code back from the parsed template?
Related
I don't understand how to extend a jinja2 template with a super block that is a string in the same Python script
Sample code
from jinja2 import Template
hello = """
hello
"""
world = """
{% extends 'hello' %}
world
"""
j2_template = Template(world)
print(j2_template.render())
I want to print "hello world", obviously, but I get an error
TypeError: no loader for this environment specified
I checked the Jinja2 loader doc, but cannot find how to ref a string as a super block.
Any help solving this would be greatly appreciated.
Jinja doesn't know where hello template is. You need to remove {% extends 'hello' %} and render hello first and insert it as a variable in the string template.
world = Template("""{} world""".format(Template(hello).render()))
print(world.render())
from jinja2 import Environment, BaseLoader, DictLoader
loader = DictLoader({'hello': '<div>hello html</div>'})
# Need environment dictLoader object to loader
template_env = Environment(loader=loader, cache_size=1000)
template = template_env.from_string("<div>ss {{name}} {% include 'hello' %} </div>")
dictt = {"name": "sumit"}
parsed_html = template.render(dictt)
# Parsed output in html string
https://jinja.palletsprojects.com/en/3.0.x/api/
link of documentation
worked for me
I would like to update template several times and then render it. From Jinja2 documentation, I have found that:
generate()
For very large templates it can be useful to not
render the whole template at once but evaluate each statement after
another and yield piece for piece. This method basically does exactly
that and returns a generator that yields one item after another as
unicode strings.
It accepts the same arguments as render().
This is my code and I don't know how to output/render template.
template_render.py
from jinja2 import Environment, Template, FileSystemLoader
file_loader = FileSystemLoader('templates')
env = Environment(loader=file_loader)
template = env.get_template('template_file.html')
template.generate(title='Lorem ipsum')
template.generate(subtitle='Dolor sit amet')
#How to render it now?
template_file.html
{{ title }} {{ subtitle }}
I want to call a python function from a jinja template. At the doucmentation (http://jinja.pocoo.org/docs/2.10/templates/ see Assignments) the following example is offered:
{% set key, value = call_something() %}
But the following source does not work.
import jinja2
#jinja2.contextfunction
def hw():
return "World"
template = jinja2.Template('{% set test = hw() %} Hello {{ test }}!')
template.render(name='John Doe')
Error: ... UndefinedError: 'hw' is undefined
Does any one knows how to solve the problem?!
Thank's to all!
You may simply supply it as a key=value pair in the template.render function, just as you have supplied the name variable.
import jinja2
def hw():
return "World"
template = jinja2.Template('{% set test = hw() %} Hello {{ test }}!')
print(template.render(name='John Doe', hw=hw))
Alternatively, if and when you plan to use a Jinja environment, you may add it to the globals dictionary before any templates are created, should you want the function to be accessible from every template within said environment.
import jinja2
def hw():
return "World"
template = """
{% set test = hw() %} Hello {{ test }}!
"""
env = jinja2.Environment()
env.globals['hw'] = hw
template = env.from_string(template)
print(template.render(name='John Doe'))
I've used the from_string method here to load your template, but there is a whole loaders system for environments which you may want to investigate.
All my JavaScript is run through Django's compiler, allowing me to inject HTML strings Underscore templates in the following manner:
var htmlStr = '{% filter convert_js_template %}{% include "my_file.html" %}{% endfilter %}'
This code runs the output from the included HTML file through the convert_js_template filter, which simply removes line breaks and escapes single quotation marks so that the final JS string is valid. To make it more readable, however, I'd like to be able to simply write something like the following:
var htmlStr = '{% convert_js_template "my_file.html" %}'
How can I create a convert_js_template function that will accomplish this? My sense is that it needs to start out by doing the following:
Grab the contents of the desired file
Parse the contents for any Django template tags
I tried the following:
#register.filter('convert_js_template')
def convert_js_template(path):
value = include(path)
return value.replace('\n', '').replace('\r', '').replace("'", "\\'")
I initially received the error NameError: global name 'include' is not defined, so then I added from django.conf.urls import include to the file and am now receiving a different error: ImportError: Import by filename is not supported.
And this is where I'm stuck :)
My solution doesn't involve a custom "include" function exactly. Instead, it manually loads and renders the desired template file:
from django.template import Library, loader, Context
...
register = Library()
...
#register.filter('js_template')
def js_template(template_path):
tpl = loader.get_template(template_path)
return tpl.render(Context({})).replace('\n', '').replace('\r', '').replace("'", "\\'")
js_template.is_safe = True
Note that template_path should be relative to the directory you have set for Django to look in for templates.
Usage:
var htmlString = '{{ "path/to/my_template.html" | js_template }}';
For example, I attached Jinja2 to my pythonic project with the next code (Jinja2 docs):
from jinja2 import Template
template = Template(text_of_the_template)
template.render(**kwargs)
The example of using a custom template tag (from here):
from jinja2 import contextfunction
#contextfunction
def widget(context, template_name, **extra_context):
t = jinja_env.get_template('widgets/' + template_name)
ctx = dict(context.items())
ctx.update(extra_context)
return t.render(ctx)
jinja_env.globals['widget'] = widget
# And then in the template:
{{ widget('last_tweets.html') }}
How to bind Jinja2 environment and the code above (the Template class)?
Instead of using jinja2.Template() to get your template you should get it through the environment.
So you will get something like this instead:
template = jinja_env.from_string(text_of_the_template)
template.render(**kwargs)
Here's the dos: http://jinja.pocoo.org/docs/api/#jinja2.Environment.from_string