Flask comes packaged with the powerful Jinja templating language.

For those who accept non been exposed to a templating language before, such languages essentially contain variables too 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 case, 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 lot have Jinja installed earlier running these examples (pip install jinja2):

>>>

                                            >>>                                from                jinja2                import                Template                >>>                                t                =                Template                (                "Hello {{ something }}!"                )                >>>                                t                .                return                (                something                =                "World"                )                u'Hello World!'                >>>                                t                =                Template                (                "My favorite numbers: {                % f                or northward in range(ane,10) %}{{n}} "                "{                % e                ndfor %}"                )                >>>                                t                .                render                ()                u'My favorite numbers: 1 2 three 4 five 6 7 8 nine '                          

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

Flask Examples

The code can be found here.

Create the following project structure:

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

Activate a virtualenv, then install flask:

Add the post-obit code to run.py:

                                            from                flask                import                Flask                ,                render_template                app                =                Flask                (                __name__                )                @app                .                route                (                "/"                )                def                template_test                ():                return                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 have a template name. Optionally, you can pass in keyword arguments to the template, like in the example with my_string and my_list.

Add the template:

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

Save this as template.html in the templates directory. Notice the template tags. Can you judge the output earlier you run the app?

Run the following:

Yous should meet the following:

Basic Flask + Jinja templating example screenshot

Template Inheritance

Templates usually take advantage of inheritance, which includes a single base template that defines the basic construction of all subsequent child templates. Yous utilize the tags {% extends %} and {% block %} to implement inheritance.

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

Let's add inheritance to our example.

Create the base (or parent) template:

                                            <!DOCTYPE html>                <                html                >                <                head                >                <                title                >Flask Template Instance</                title                >                <                meta                proper noun                =                "viewport"                content                =                "width=device-width, initial-scale=i.0"                >                <                link                href                =                "http://netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css"                rel                =                "stylesheet"                media                =                "screen"                >                <                style                type                =                "text/css"                >                .                container                {                max-width                :                500                px                ;                padding-height                :                100                px                ;                }                h2                {                color                :                cherry                ;}                </                style                >                </                head                >                <                body                >                <                div                class                =                "container"                >                <                h2                >This is part of my base template</                h2                >                <                br                >                {% cake content %}{% endblock %}                <                br                >                <                h2                >This is part of my base template</                h2                >                </                div                >                <                script                src                =                "http://code.jquery.com/jquery-ane.10.2.min.js"                ></                script                >                <                script                src                =                "http://netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"                ></                script                >                </                torso                >                </                html                >                          

Save this every bit layout.html.

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

Let's do that.

Update template.html:

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

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

Run information technology. You should see this:

Flask + Jinja templating example showing inheritance

One mutual use case is to add a navigation bar.

Add together the following code to the base template, just after the opening <body> tag:

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

Now, every single child template that extends from the base will have the same navigation bar. To steal a line from Java philosophy: "Write once, utilise anywhere."

Flask + Jinja templating example showing a reusable navigation bar

Super Blocks

If you need to render a block from the base template, employ a super block:

Add a footer to the base of operations template:

                                            <                div                class                =                "footer"                >                {% cake footer %}     Lookout! This volition be added to my base of operations and kid templates using the super powerful super block!                <                br                >                <                br                >                {% endblock %}                </                div                >                          

Here's the updated code:

                                            <!DOCTYPE html>                <                head                >                <                title                >Flask Template Example</                championship                >                <                meta                name                =                "viewport"                content                =                "width=device-width, initial-scale=one.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                ;}                </                fashion                >                </                caput                >                <                trunk                >                <                div                class                =                "container"                >                <                h2                >This is part of my base of operations template</                h2                >                <                br                >                {% block content %}{% endblock %}                <                br                >                <                h2                >This is function of my base template</                h2                >                <                br                >                <                div                form                =                "footer"                >                {% block footer %}           Lookout! This will exist added to my base and child 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/3.0.0/js/bootstrap.min.js"                ></                script                >                </                body                >                </                html                >                          

Run the app. You should run into that the footer is merely role of the base:

Jinja templating example defining a footer block

At present, add the super block to template.html:

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

Check information technology 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 every bit the <championship>, where both templates share part of the title. Then, yous would just need to pass in the other part. It could besides be used for a heading.

Here's an instance:

Parent

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

Kid

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

Let's see that in action:

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

See what happens when y'all remove {% block folio %}Domicile{% endblock %} from the child template.

Instead of hard coding the proper name of the template, let'due south brand it dynamic.

Update the ii code snippets in template.html:

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

Now, we demand to laissez passer in a championship 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                ,                two                ,                3                ,                4                ,                5                ],                title                =                "Habitation"                )                          

Examination this out.

Macros

In Jinja, we can employ macros to abstruse usually used code snippets that are used over and over to not repeat ourselves. For instance, information technology'southward common to highlight the link of the current folio on the navigation bar (active link). Otherwise, we'd have to use if/elif/else statements to make up one's mind the active link. Using macros, we can abstract out such code into a carve up file.

Add a macros.html file to the templates directory:

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

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

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

                                            <                ul                class                =                "nav navbar-nav"                >                {{ nav_link('dwelling', 'Home') }}   {{ nav_link('about', 'About') }}   {{ nav_link('contact', 'Contact Us') }}                </                ul                >                          

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

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

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

                                            @app                .                road                (                "/home"                )                def                home                ():                return                render_template                (                'template.html'                ,                my_string                =                "Wheeeee!"                ,                my_list                =                [                0                ,                1                ,                2                ,                3                ,                iv                ,                five                ],                title                =                "Habitation"                )                @app                .                route                (                "/about"                )                def                virtually                ():                return                render_template                (                'template.html'                ,                my_string                =                "Wheeeee!"                ,                my_list                =                [                0                ,                1                ,                2                ,                3                ,                four                ,                5                ],                title                =                "Almost"                )                @app                .                route                (                "/contact"                )                def                contact                ():                render                render_template                (                'template.html'                ,                my_string                =                "Wheeeee!"                ,                my_list                =                [                0                ,                i                ,                two                ,                three                ,                4                ,                5                ],                championship                =                "Contact Us"                )                          

Refresh the folio. Exam out the links at the meridian. Does the current page get highlighted? It should.

Jinja templating example showing macros

Custom Filters

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

Here's an example:

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

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

Hither's an example:

This will join a list by the comma delimiter.

Test this out. Add the following line to template.html

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

At present, besides the built-in filters, we can create our own.

Let's add together i of our own. 1 mutual example is a custom datetime filter.

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

                                            @app                .                template_filter                ()                def                datetimefilter                (                value                ,                format                =                '%Y/%m/                %d                                  %H:%M'                ):                """Convert a datetime to a different format."""                return                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 accessible. At present it'southward gear up for use.

Add the following code to our child template:

                                            <                h4                >Electric current engagement/time: {{ current_time | datetimefilter }}</                h4                >                          

Finally, merely laissez passer in the datetime to our template:

                                            current_time                =                datetime                .                datetime                .                now                ()                          

Exam it.

Jinja templating "filter" example

Conclusion

That'south it. Grab the sample lawmaking here. Did I miss anything? Leave a comment beneath.