YouTip LogoYouTip

Flask Templates

Concatenating HTML strings in Python code is both cumbersome and dangerous (prone to XSS vulnerabilities). Flask integrates the Jinja2 template engine to solve this problem. Templates allow you to separate business logic from page presentation, enabling you to write safer and more maintainable code. * * * ## render_template Basics render_template() is the most commonly used template rendering function in Flask. Its first parameter is the template filename, and the keyword arguments that follow will be passed as variables to the template. ## Example # File path: app.py from flask import Flask, render_template app = Flask( __name__ ) @app.route("/") def index(): # Render the templates/index.html template, passing title and name variables return render_template("index.html", title="TUTORIAL Homepage", name="World") @app.route("/user/") def profile(username): # Pass the username from the URL to the template return render_template("user.html", username=username, posts=[ {"title": "Flask Getting Started","date": "2026-05-01"}, {"title": "Jinja2 Templates","date": "2026-05-10"}, ]) Template files are placed in the templates/ folder under the project directory: tutorial-flask-test/β”œβ”€β”€ app.py └── templates/ β”œβ”€β”€ index.html └── user.html The content of index.html: ## Example ( index.html )

{{ title }}

Hello {{ name }}.

Visit http://127.0.0.1:5000/ , the output is: !(#) * * * ## Jinja2 Basic Syntax Three core syntaxes in Jinja2 templates: | Syntax | Usage | Example | | --- | --- | --- | | {{ ... }} | Output variable value, auto-escape HTML | {{ username }} | | {% ... %} | Control statements (if, for, block, etc.) | {% if user %} | | {# ... #} | Comments, won't appear in rendered output | {# This is a comment #} | ### Template Example ## Example ( user.html )

{{ username }}'s Profile

{% if posts %}

Recent Posts:

    {% for post in posts %}
  • {{ loop.index }}. {{ post.title }} ({{ post.date }})
  • {% endfor %}
{% else %}

No posts yet

{% endif %}

Username uppercase: {{ username|upper }}

* * * ## Common Filters Filters are used to modify the output format of variables, called using the pipe symbol |. | Filter | Function | Example | Output | | --- | --- | --- | --- | | upper | Convert to uppercase | {{ "hello"|upper }} | HELLO | | lower | Convert to lowercase | {{ "HELLO"|lower }} | hello | | title | Capitalize first letter | {{ "hello world"|title }} | Hello World | | length | Get length | {{ [1,2,3]|length }} | 3 | | default | Set default value | {{ name|default("Anonymous") }} | Anonymous (when name is empty) | | safe | Mark as safe HTML (no escaping) | {{ "**bold**"|safe }} | Rendered as bold text | | join | Join list | {{ ["a","b"]|join(",") }} | a,b | > Security Warning: The safe filter disables auto-escaping. Only use it when you absolutely trust the data source. Never use safe for user input. * * * ## Auto-Escaping β€” XSS Protection Jinja2 automatically escapes all variable outputs by default, which is a key defense in web security. For example, if a user submits a username like alert("xss"), the template rendering will automatically convert it to safe text:

{{ username }}

<p>&lt;script&gt;alert(&quot;xss&quot;)&lt;/script&gt;</p> Escaping applies to template files ending in .html, .htm, .xml, .xhtml, .svg. * * * ## Template Inheritance β€” Eliminating Duplicate Code Template inheritance is one of Jinja2's most powerful features. It allows you to define a "base layout" and then fill in content through child templates. This avoids repeating common parts like headers, navigation, and footers on every page. ### Base Template (Parent Template) ## Example

TUTORIAL Flask Tutorial

{% block content %}{% endblock %}

© 2026

### Child Template (Inheriting from Parent Template) ## Example {% extends "base.html" %} {% block title %}Online Tutorial - Home{% endblock %} {% block content %}

Welcome to TUTORIAL

{{ greeting }}

{% if user %}

Current user: {{ user }}

{% else %}

Please login first

{% endif %} {% endblock %} | Tag | Function | | --- | --- | | {% extends "base.html" %} | Declare that current template inherits from base.html (must be on the first line) | | {% block name %}...{% endblock %} | Define an area that can be overridden by child templates | | {{ super() }} | Call the parent template's same-named block content from within a child template block | > After using template inheritance, you only need to modify base.html in one place, and all pages' common parts (like navigation, footer) will automatically update. * * * ## Built-in Objects in Templates The following Flask objects can be used directly in templates without passing through render_template(): | Object | Description | Example in Template | | --- | --- | --- | | request | Current request object | {{ request.path }} | | session | Current session data | {{ session.get("username") }} | | g | Request-level global variable | {{ g.user }} | | config | Application configuration | {{ config }} | | url_for() | URL generation function | {{ url_for("index") }} | | get_flashed_messages() | Get flash messages | {% for msg in get_flashed_messages() %}... | * * * ## Including Other Templates β€” include Using {% include %} allows you to embed another template within a template: ## Example ## Example Page {% include "_navbar.html" %}

Page Content

This is the main content of the page.</

← Flask OrmFlask Router β†’