Introducci贸n a Flask
驴Qu茅 es Flask?
Creando tu primer "Hello, World" en Flask
Rutas y Plantillas con Jinja
Rutas y vistas en Flask
Plantillas con Jinja en Flask
Manejo de Formularios y Datos
Manejo de formularios en Flask
Bases de datos: SQLite y SQLAlchemy
CRUD: Crear y leer datos en Flask
CRUD: Actualizar datos en Flask
CRUD: Eliminar datos en Flask
Organizaci贸n del Proyecto y Mejoras
Estructura de proyectos en Flask
Blueprints en Flask
Notificaciones con Flash Messages
Integraci贸n de TailwindCSS en Flask
Seguridad y Testing
Gesti贸n de sesiones en Flask
Manejo de cierre de sesi贸n en Flask
Validaci贸n de formularios en Flask
Pruebas unitarias en Flask
Pr贸ximos pasos en Flask
You don't have access to this class
Keep learning! Join and start boosting your career
The implementation of attractive and functional interfaces is a fundamental aspect of modern web development. While the backend provides the logic and functionality, the frontend is the visible face of our application and largely determines the user experience. In this content, we will explore how to improve the look and feel of our Flask application using Jinja, a powerful templating system that allows us to organize and reuse our HTML code efficiently.
Jinja is Flask's built-in template manager that offers great advantages for frontend development. Its main benefit is to avoid duplication of HTML code, allowing us to keep our code organized in different files and reuse it as needed.
To work with Jinja more efficiently, we can install the "Better Jinja" extension in our code editor, which makes it easier to write and autocomplete Jinja code.
The first step to implement Jinja in our application is to create a base template that will contain the structure common to all our pages:
base.html
in the templates folder.<!-- Select Jinja HTML as language -->{% block app_notes %}{% endblock %}
<body style="background-color: aqua;"> {% block content %}{% endblock %}</body>
Blocks({% block name %}{% endblock %}
) are areas that can be overwritten by templates extending from this base.
To use our base template in other views, we use the {% extends %}
directive:
{% extends "base.html" %}
{% block content %}<div> Lorem ipsum dolor sit amet...</div>{% endblock %}
It is important to understand that only content within the defined blocks will be visible on the final page. All content that is not within a redefined block will be ignored.
One of the advantages of using base templates is the ability to define elements that will appear on all pages of our application, such as navigation bars, footers or message systems.
To implement a message system that appears on all pages, we can place the corresponding code in the base template:
<!-- In base.html, before the content block -->{% with messages = get_flashed_messages(with_categories=true) %} {% if messages %} {% for category, message in messages %} <div class="alert alert alert-{{ category }}">{{ message }}</div> {% endfor %} {% endif %}{% endwith %}
{% block content %}{% endblock %}
This way, the flash messages will be displayed on any page that extends from our base template.
To improve the appearance of our application, we can use CSS frameworks such as Tailwind. In our enhanced base template, we include:
<!-- Example of improved base.html --><!DOCTYPE html> <html><head> <head> <title>{% block app_notes %}App Notes{% endblock %}</title> <script src="https://cdn.tailwindcss.com"></script> <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap" rel="stylesheet"></head><body class="font-roboto"> <nav class="bg-blue-600 text-white p-4"> <h1 class="text-xl font-bold">App Notes</h1> </nav>
<!-- Color-coded message system by category --> {% with messages = get_flashed_messages(with_categories=true) %} {% if messages %} {% for category, message in messages %} {% if category == 'success' %} <! div class="bg-green-100 border-l-4 border-green-500 text-green-700 p-4 mb-4">{{ message }}</div> {% elif category == 'error' %} <div class="bg-red-100 border-l-4 border-red-500 text-red-700 p-4 mb-4">{{ message }}</div> {% elif category == 'error' %}<div class="bg-red-100 border-l-4 border-red-500 text-red-700 p-4 mb-4">{{ message }}</div> {% elif category == 'warning' %} <div class="bg-yellow-100 border-l-4 border-yellow-500 text-yellow-700 p-4 mb-4">{{ message }}</div> {% endif %} {% endif %} {% endfor %} {% endif %} {% endwith %}
<00main class="container mx-auto p-4"> {% block content %}{% endblock %} </main>
<footer class="bg-gray-200 p-4 text-center text-gray-600"> © 2023 App Notes </footer></body></html> </body></html>
Once we have our base template, we can customize each specific view by extending from it and redefining the necessary blocks.
For the home page that displays the list of notes, we extend from the base template and customize the content:
{% extends "base.html" %}
{% block app_notes %}List of Notes{% endblock %}
{% block content %}<div class="flex justify-between items-center mb-4"> <h2 class="text-2xl font-bold">MyNotes</h2> <a href="{{ url_for('create') }}" class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"> Create Note</a></div></div>
{% if notes %} <div class="grid grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4"> {% for note in notes %} <div class="bg-white shadow-md rounded-lg p-4"> <h3 class="text-xl font-bold mb-2">{{ note.title }}</h3> <p class="text-gray-700 mb-4">{{ note.content }}</p> <p class="text-sm text-gray-500">Created: {{ note.created_at }}</p> <div class="flex justify-end mt-4"> <a href="{{ url_for('edit', id=note.id) }}" class="bg-yellow-500 hover:bg-yellow-700 text-white font-bold py-1 px-3 rounded mr-2"> Edit </a> <a href="{{ url_for('delete', id=note.id) }}" class="bg-red-500 hover:bg-red-700 text-white font-bold py-1 px-3 rounded"> Delete </a> </div></div> </div> {% endfor %} </div>{% else %} <div class="bg-gray-100 p-8 text-center rounded-lg"> <p class="text-xl text-gray-600">Nonotes available. Create a new one!</p> </div>{% endif %}{% endblock %}
To enhance our application, we can add a creation date field to our Note model:
class Note(db.Model): id = db.Column(db.Integer, primary_key=True) title = db.Column(db.String(100), nullable=False) content = db.Column(db.Text, nullable=False) created_at = db.Column(db.DateTime, default=db.func.now())
The default=db.func.now()
parameter ensures that each new note automatically has the current date and time as its creation date.
Implementing Jinja in our Flask application allows us to create more attractive interfaces and keep our code organized and reusable. By using base templates and blocks, we can define common elements and customize them as needed in each specific view. In addition, the integration with frameworks such as Tailwind CSS makes it easy to design modern and responsive interfaces. Have you implemented Jinja in your Flask projects? Share your experiences and how you have improved your forms with Tailwind in the comments.
Contributions 2
Questions 0
Want to see more contributions, questions and answers from the community?