Reputation: 312
I have a Flask app that looks as follows:
@app.route('/')
def index():
headline = render_template('headline.html', headline = 'xyz') #-> return <h1>xyz</h1>
return render_template('page.html', headline = headline) # insert headline html into a page
headline.html
is a template which imports a jinja macro from a macro file (macros.html
). The macro generates the headline.
headline.html
:
{% import 'macros.html' as macros %}
{{ macros.get_headline(headline) }}
macros.html
:
{% macro get_headline(headline) %}
<h1>{{ healine }}</h1>
{% endmacro %}
My question is - is it possible to call the macro to get headline
without the need to call the template headline.html
?
Ideally, I'd like to see
@app.route('/')
def index():
headline = # somehow call get_headline('xyz') from macros.html
return render_template('page.html', headline = headline) # insert headline html into a page
Upvotes: 2
Views: 1823
Reputation: 3576
My question is - is it possible to call the macro to get
headline
without the need to call the templateheadline.html
?
I hope you figured out your situation. My bet is you'll eventually settle on a better way to do this than what you're proposing, which seems a bit backwards to me, but hey, that's part of the learning process!
Especially for simple text transformation functions that only take a single argument, you may get better mileage from a Python function that you register as a Jinja filter with Environment.filters
as described here. It's less syntax all around, and you can use the same function from Python and your Jinja templates in a standard way, without hacks.
That said, I blundered into the .module
property on Jinja templates just today. It allows you to call macros from a template as regular Python functions:
macros.html
:
{% macro get_headline(headline) -%}
<h1>{{ headline }}</h1>
{%- endmacro %}
test.py
:
# these imports not needed for a Flask app
from jinja2 import Environment, FileSystemLoader
# just use `app.jinja_env` for a Flask app
e = Environment(loader=FileSystemLoader('.'))
t = e.get_template('macros.html')
t.module.get_headline('Headline')
# >>> '<h1>Headline</h1>'
I believe (?) this does what you were originally asking, with the app.jinja_env
environment that you already have with Flask, and no extra imports.
Upvotes: 2
Reputation: 3116
Instead of rendering the template from a file, you can render a template from a string. So you can call your macro from a string.
from flask.templating import render_template_string
@app.route('/')
def index():
headline = render_template_string(
"{% import 'macros.html' as macros %}"
"{{ macros.get_headline(headline) }}",
headline='xyz'
)
return render_template('page.html', headline=headline)
(ignoring the typo healine
instead of headline
in macros.html)
Upvotes: 1