Flask comes packaged with the powerful Jinja templating language.

For those who take non been exposed to a templating language before, such languages essentially comprise variables equally well every bit some programming logic, which when evaluated (or rendered into HTML) are replaced with actual values.

The variables and/or logic are placed between tags or delimiters. For instance, Jinja templates use {% ... %} for expressions or logic (like for loops), while {{ ... }} is used for outputting the results of an expression or a variable to the end user. The latter tag, when rendered, is replaced with a value or values, and is seen by the end user.

Quick Examples

Make sure you take Jinja installed before running these examples (pip install jinja2):

>>>

                                            >>>                                from                jinja2                import                Template                >>>                                t                =                Template                (                "Hello {{ something }}!"                )                >>>                                t                .                render                (                something                =                "World"                )                u'Hello Earth!'                >>>                                t                =                Template                (                "My favorite numbers: {                % f                or n in range(ane,10) %}{{northward}} "                "{                % e                ndfor %}"                )                >>>                                t                .                render                ()                u'My favorite numbers: ane two 3 4 5 6 7 viii nine '                          

Discover how the actual output rendered to the user falls within the tags.

Flask Examples

The code can be establish here.

Create the following project structure:

                            ├── requirements.txt ├── run.py └── templates                          

Activate a virtualenv, then install flask:

Add the following code to run.py:

                                            from                flask                import                Flask                ,                render_template                app                =                Flask                (                __name__                )                @app                .                route                (                "/"                )                def                template_test                ():                render                render_template                (                'template.html'                ,                my_string                =                "Wheeeee!"                ,                my_list                =                [                0                ,                1                ,                two                ,                3                ,                4                ,                5                ])                if                __name__                ==                '__main__'                :                app                .                run                (                debug                =                True                )                          

Here, we are establishing the route /, which renders the template template.html via the part render_template(). This function must take a template name. Optionally, you tin pass in keyword arguments to the template, like in the example with my_string and my_list.

Add together the template:

                                            <!DOCTYPE html>                <                html                >                <                head                >                <                title                >Flask Template Example</                title                >                <                meta                name                =                "viewport"                content                =                "width=device-width, initial-scale=one.0"                >                <                link                href                =                "http://netdna.bootstrapcdn.com/bootstrap/iii.0.0/css/bootstrap.min.css"                rel                =                "stylesheet"                media                =                "screen"                >                <                fashion                type                =                "text/css"                >                .                container                {                max-width                :                500                px                ;                padding-top                :                100                px                ;                }                </                style                >                </                caput                >                <                body                >                <                div                grade                =                "container"                >                <                p                >My string: {{my_string}}</                p                >                <                p                >Value from the list: {{my_list[3]}}</                p                >                <                p                >Loop through the list:</                p                >                <                ul                >                {% for n in my_list %}                <                li                >{{northward}}</                li                >                {% endfor %}                </                ul                >                </                div                >                <                script                src                =                "http://code.jquery.com/jquery-1.10.ii.min.js"                ></                script                >                <                script                src                =                "http://netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"                ></                script                >                </                body                >                </                html                >                          

Salvage this as template.html in the templates directory. Observe the template tags. Can you estimate the output before yous run the app?

Run the following:

You should see the following:

Basic Flask + Jinja templating example screenshot

Template Inheritance

Templates commonly accept advantage of inheritance, which includes a unmarried base template that defines the bones construction of all subsequent child templates. Yous use the tags {% extends %} and {% cake %} to implement inheritance.

The use case for this is simple: as your application grows, and you continue adding new templates, you volition demand to keep common code (like an HTML navigation bar, Javascript libraries, CSS stylesheets, and so forth) in sync, which tin can be a lot of piece of work. Using inheritance, we can move those common pieces to a parent/base template so that we tin can create or edit such lawmaking once, and all child templates will inherent that lawmaking.

Let'southward add inheritance to our example.

Create the base (or parent) template:

                                            <!DOCTYPE html>                <                html                >                <                head                >                <                title                >Flask Template Case</                title                >                <                meta                proper noun                =                "viewport"                content                =                "width=device-width, initial-scale=ane.0"                >                <                link                href                =                "http://netdna.bootstrapcdn.com/bootstrap/three.0.0/css/bootstrap.min.css"                rel                =                "stylesheet"                media                =                "screen"                >                <                style                type                =                "text/css"                >                .                container                {                max-width                :                500                px                ;                padding-top                :                100                px                ;                }                h2                {                color                :                red                ;}                </                manner                >                </                head                >                <                body                >                <                div                class                =                "container"                >                <                h2                >This is part of my base template</                h2                >                <                br                >                {% block content %}{% endblock %}                <                br                >                <                h2                >This is function of my base template</                h2                >                </                div                >                <                script                src                =                "http://code.jquery.com/jquery-1.10.ii.min.js"                ></                script                >                <                script                src                =                "http://netdna.bootstrapcdn.com/bootstrap/iii.0.0/js/bootstrap.min.js"                ></                script                >                </                body                >                </                html                >                          

Save this as layout.html.

Did you notice the {% cake %} tags? This defines a block (or area) that kid templates tin can fill in. Further, this just informs the templating engine that a child template may override the block of the template.

Allow's do that.

Update template.html:

                            {% extends "layout.html" %} {% block content %}                <                h3                >                This is the start of my child template</                h3                >                <                br                >                <                p                >My cord: {{my_string}}</                p                >                <                p                >Value from the list: {{my_list[3]}}</                p                >                <                p                >Loop through the list:</                p                >                <                ul                >                {% for n in my_list %}                <                li                >{{northward}}</                li                >                {% endfor %}                </                ul                >                <                h3                >                This is the end of my child template</                h3                >                {% endblock %}                          

So, the {% extends %} informs the templating engine that this template "extends" another template, layout.html. This establishes the link betwixt the templates.

Run it. Yous should run into this:

Flask + Jinja templating example showing inheritance

One common use case is to add a navigation bar.

Add the post-obit code to the base template, just later on the opening <trunk> tag:

                                            <                nav                class                =                "navbar navbar-inverse"                role                =                "navigation"                >                <                div                course                =                "container-fluid"                >                <                div                grade                =                "navbar-header"                >                <                button                type                =                "push"                class                =                "navbar-toggle"                data-toggle                =                "collapse"                data-target                =                "#bs-example-navbar-plummet-1"                >                <                bridge                form                =                "sr-only"                >Toggle navigation</                span                >                <                span                class                =                "icon-bar"                ></                bridge                >                <                span                class                =                "icon-bar"                ></                span                >                <                span                class                =                "icon-bar"                ></                span                >                </                button                >                <                a                class                =                "navbar-make"                href                =                "/"                >Jinja!</                a                >                </                div                >                <                div                class                =                "plummet navbar-collapse"                id                =                "bs-example-navbar-collapse-1"                >                <                ul                form                =                "nav navbar-nav"                >                <                li                class                =                "active"                ><                a                href                =                "#"                >Link</                a                ></                li                >                <                li                ><                a                href                =                "#"                >Link</                a                ></                li                >                </                ul                >                <                form                grade                =                "navbar-form navbar-left"                role                =                "search"                >                <                div                grade                =                "course-group"                >                <                input                type                =                "text"                grade                =                "form-command"                placeholder                =                "Search"                >                </                div                >                <                button                blazon                =                "submit"                class                =                "btn btn-default"                >Submit</                button                >                </                class                >                <                ul                course                =                "nav navbar-nav navbar-correct"                >                <                li                ><                a                href                =                "#"                >Link</                a                ></                li                >                <                li                class                =                "dropdown"                >                <                a                href                =                "#"                form                =                "dropdown-toggle"                data-toggle                =                "dropdown"                >Dropdown                <                b                course                =                "caret"                ></                b                ></                a                >                <                ul                class                =                "dropdown-card"                >                <                li                ><                a                href                =                "#"                >Activeness</                a                ></                li                >                <                li                ><                a                href                =                "#"                >Another action</                a                ></                li                >                <                li                ><                a                href                =                "#"                >Something else hither</                a                ></                li                >                <                li                class                =                "divider"                ></                li                >                <                li                ><                a                href                =                "#"                >Separated link</                a                ></                li                >                </                ul                >                </                li                >                </                ul                >                </                div                >                <!-- /.navbar-plummet -->                </                div                >                <!-- /.container-fluid -->                </                nav                >                          

At present, every single child template that extends from the base will have the same navigation bar. To steal a line from Coffee philosophy: "Write once, employ anywhere."

Flask + Jinja templating example showing a reusable navigation bar

Super Blocks

If you demand to render a block from the base template, use a super block:

Add together a footer to the base of operations template:

                                            <                div                form                =                "footer"                >                {% cake footer %}     Sentinel! This will exist added to my base and child templates using the super powerful super cake!                <                br                >                <                br                >                {% endblock %}                </                div                >                          

Here's the updated code:

                                            <!DOCTYPE html>                <                caput                >                <                title                >Flask Template Example</                title                >                <                meta                proper noun                =                "viewport"                content                =                "width=device-width, initial-scale=1.0"                >                <                link                href                =                "http://netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css"                rel                =                "stylesheet"                media                =                "screen"                >                <                mode                type                =                "text/css"                >                .                container                {                max-width                :                500                px                ;                padding-top                :                100                px                ;                }                h2                {                color                :                carmine                ;}                </                style                >                </                head                >                <                torso                >                <                div                class                =                "container"                >                <                h2                >This is function of my base template</                h2                >                <                br                >                {% block content %}{% endblock %}                <                br                >                <                h2                >This is part of my base template</                h2                >                <                br                >                <                div                grade                =                "footer"                >                {% block footer %}           Watch! This volition exist added to my base and kid templates using the super powerful super block!                <                br                >                <                br                >                <                br                >                {% endblock %}                </                div                >                </                div                >                <                script                src                =                "http://code.jquery.com/jquery-1.10.2.min.js"                ></                script                >                <                script                src                =                "http://netdna.bootstrapcdn.com/bootstrap/three.0.0/js/bootstrap.min.js"                ></                script                >                </                body                >                </                html                >                          

Run the app. You lot should see that the footer is simply part of the base:

Jinja templating example defining a footer block

Now, add the super block to template.html:

                            {% extends "layout.html" %} {% block content %}                <                h3                >                This is the start of my child template</                h3                >                <                br                >                <                p                >My string: {{my_string}}</                p                >                <                p                >Value from the list: {{my_list[3]}}</                p                >                <                p                >Loop through the list:</                p                >                <                ul                >                {% for n in my_list %}                <                li                >{{north}}</                li                >                {% endfor %}                </                ul                >                <                h3                >                This is the stop of my kid template</                h3                >                {% block footer %}   {{super()}}   {% endblock %} {% endblock %}                          

Check it out in your browser:

Jinja templating example defining a footer block – step 2

The super cake is used for common code that both the parent and child templates share, such equally the <title>, where both templates share part of the championship. Then, you would just need to laissez passer in the other part. It could also be used for a heading.

Here's an instance:

Parent

                            {% block heading %}                <                h1                >{% block page %}{% endblock %} - Flask Super Instance</                h1                >                {% endblock %}                          

Child

                            {% block page %}Home{% endblock %} {% cake heading %}   {{ super() }} {% endblock %}                          

Let's encounter that in action:

Jinja templating example showing the footer block included in the final HTML output

Run across what happens when y'all remove {% block page %}Home{% endblock %} from the child template.

Instead of difficult coding the name of the template, let's get in dynamic.

Update the two code snippets in template.html:

                            {% block title %}{{championship}}{% endblock %}                          
                            {% block page %}{{title}}{% endblock %}                          

Now, we need to pass in a title variable to our template from our controller, run.py:

                                            @app                .                route                (                "/"                )                def                template_test                ():                return                render_template                (                'template.html'                ,                my_string                =                "Wheeeee!"                ,                my_list                =                [                0                ,                1                ,                ii                ,                3                ,                iv                ,                5                ],                title                =                "Domicile"                )                          

Examination this out.

Macros

In Jinja, we tin can use macros to abstract commonly used code snippets that are used over and over to not repeat ourselves. For example, it'due south common to highlight the link of the electric current page on the navigation bar (active link). Otherwise, we'd accept to use if/elif/else statements to determine the active link. Using macros, nosotros can abstract out such code into a split file.

Add a macros.html file to the templates directory:

                            {% macro nav_link(endpoint, proper noun) %} {% if request.endpoint.endswith(endpoint) %}                <                li                class                =                "agile"                ><                a                href                =                "{{ url_for(endpoint) }}"                >{{proper name}}</                a                ></                li                >                {% else %}                <                li                ><                a                href                =                "{{ url_for(endpoint) }}"                >{{proper noun}}</                a                ></                li                >                {% endif %} {% endmacro %}                          

Here, we're using Flask'southward request object, which is part of Jinja by default, to check the requested endpoint, and then assigning the active class to that endpoint.

Update the unordered listing with the nav navbar-nav grade in the base template:

                                            <                ul                form                =                "nav navbar-nav"                >                {{ nav_link('dwelling house', 'Home') }}   {{ nav_link('most', 'About') }}   {{ nav_link('contact', 'Contact United states of america') }}                </                ul                >                          

Besides, make certain to add the import at the top of the template: {% from "macros.html" import nav_link with context %}.

Detect how nosotros're calling the nav-link macro and passing it two arguments: the endpoint (which comes from our controller) and the text we want displayed.

Finally, let's add three new endpoints to the controller:

                                            @app                .                route                (                "/home"                )                def                dwelling house                ():                render                render_template                (                'template.html'                ,                my_string                =                "Wheeeee!"                ,                my_list                =                [                0                ,                i                ,                two                ,                3                ,                four                ,                5                ],                title                =                "Dwelling"                )                @app                .                road                (                "/about"                )                def                about                ():                return                render_template                (                'template.html'                ,                my_string                =                "Wheeeee!"                ,                my_list                =                [                0                ,                ane                ,                2                ,                3                ,                4                ,                five                ],                title                =                "Nigh"                )                @app                .                road                (                "/contact"                )                def                contact                ():                render                render_template                (                'template.html'                ,                my_string                =                "Wheeeee!"                ,                my_list                =                [                0                ,                1                ,                2                ,                3                ,                iv                ,                5                ],                championship                =                "Contact U.s."                )                          

Refresh the page. Test out the links at the top. Does the electric current page get highlighted? It should.

Jinja templating example showing macros

Custom Filters

Jinja uses filters to alter variables, mostly for formatting purposes.

Here'southward an example:

This will circular the num variable. And then, if we pass the argument num=46.99 into the template, then 47.0 will be outputted.

As you can tell, yous specify the variable and then a pipage (|), followed by the filter. Bank check out this link for the list of filters already included within Jinja. In some cases, you tin specify optional arguments in parentheses.

Here'due south an example:

This will join a listing by the comma delimiter.

Exam this out. Add the post-obit line to template.html

                                            <                p                >Same listing with a filter: {{ my_list|join(', ') }}</                p                >                          

Now, besides the built-in filters, we tin create our ain.

Allow's add 1 of our own. I common example is a custom datetime filter.

Add together the following lawmaking to our controller later we create the app, app = Flask(__name__):

                                            @app                .                template_filter                ()                def                datetimefilter                (                value                ,                format                =                '%Y/%m/                %d                                  %H:%M'                ):                """Catechumen a datetime to a different format."""                render                value                .                strftime                (                format                )                app                .                jinja_env                .                filters                [                'datetimefilter'                ]                =                datetimefilter                          

Using the @app.template_filter() decorator, we are registering the datetimefilter() function as a filter.

Next, we are adding the filter to the Jinja environment, making it attainable. At present information technology'due south ready for use.

Add the following lawmaking to our child template:

                                            <                h4                >Current date/fourth dimension: {{ current_time | datetimefilter }}</                h4                >                          

Finally, but pass in the datetime to our template:

                                            current_time                =                datetime                .                datetime                .                now                ()                          

Test it.

Jinja templating "filter" example

Determination

That'due south it. Grab the sample code hither. Did I miss anything? Leave a comment below.