You don't have access to this class

Keep learning! Join and start boosting your career

Aprovecha el precio especial y haz tu profesi贸n a prueba de IA

Antes: $249

Currency
$209
Suscr铆bete

Termina en:

0 D铆as
5 Hrs
27 Min
6 Seg
Curso de Flask

Curso de Flask

Luis Mart铆nez

Luis Mart铆nez

Integraci贸n de TailwindCSS en Flask

13/18
Resources

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.

What is Jinja and how does it improve our frontend development?

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.

Creating a base template with Jinja

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:

  1. We create a file called base.html in the templates folder.
  2. Define the basic HTML5 structure
  3. We add blocks that will be redefined in the child templates
<!-- 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.

Extending the base template

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.

How to implement common elements on all pages?

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.

Flash message system

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.

Improving the appearance with Tailwind CSS

To improve the appearance of our application, we can use CSS frameworks such as Tailwind. In our enhanced base template, we include:

  1. Tailwind CSS integration using a script.
  2. Custom fonts from Google Fonts
  3. A navigation bar (navbar)
  4. A system of messages with colors according to the category (success, error, warning)
  5. A main container with proper margins and padding
  6. A footer
<!-- 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"> &copy; 2023 App Notes </footer></body></html> </body></html>

How to customize the specific views of our application?

Once we have our base template, we can customize each specific view by extending from it and redefining the necessary blocks.

Customizing the home view

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 %}

Adding fields to our model

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

Sort by:

Want to see more contributions, questions and answers from the community?

Procedimiento para usar Flask Migrate: 1\. Ejecuta: pip install Flask-Migrate 2\. En app.py a帽adir: from flask\_migrate import Migrate migrate = Migrate(app, db) # <--- A帽ade esta l铆nea 3\. Ejecuta: flask db init (Inicializa una vez por proyecto) 4\. Agrega el campos al modelo created\_at = db.Column(db.DateTime, default=db.func.now(), nullable=True) # tiene que aceptar nulo pq existen registros 5\. Ejecuta el comando: flask db migrate -m "Add created\_at column to Note" 6\. Ejecuta: flask db upgrade
Al escribir created\_at = db.Column(db.DateTime, default=db.func.now()) en models.py , veo que no se agrega el campo en la base datos . sqlite> .schema CREATE TABLE note ( id INTEGER NOT NULL, title VARCHAR(100) NOT NULL, content VARCHAR(200) NOT NULL, PRIMARY KEY (id) );