Flask, Templates (II)

Seguimos !

Una de las características de Flask, es que “hereda” casi todo de Django, pero sin tanto jaleo. A veces no queremos matar moscas a cañonazos🙂 Una de esas cositas que tiene de Django son las templates o plantillas: Jinja2.

Si bien Jinja2 tiene muchas cosas que incorporar para hacernos la vida más simple, aquí vamos a ver las más básicas… así como para soltarnos😀

Usando la estructura básica de una página en Bootstrap, tendríamos algo así (Base.html):

<!DOCTYPE html>
<html lang="es">
    <head>
        {% block meta %}
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <meta name="description" content="Aplicación para ver las notas y progreso">
        <meta name="author" content="Mario Cares">
        {% endblock meta %}
        <title>Visor Notas</title>
        {% block css %}
            <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/bootstrap.min.css') }}">
        {% endblock css %}
    </head>
    <body>
        <div class="container">
        {% block contenido %}{% endblock contenido %}
        </div>
        {% block js %}
            <script src="{{ url_for('static', filename='js/jquery-1.11.0.min.js') }}"></script>
            <script src="{{ url_for('static', filename='js/bootstrap.min.js') }}"></script>
        {% endblock js %}
    </body>
</html>

Notar que no utilizamos nada complicado, simplemente el esqueleto básico con los css y js que siempre usamos.

Desde arriba, tenemos el primer block. Cada block debe tener un nombre único. En mi caso, el primero se llama meta y encierra todas las etiquetas meta que tiene la página. Y para terminar el block, simplemente un endblock y el nombre correspondiente

Y así hasta el último que es js.

También tenemos un url_for que nos sirve para buscar un archivo en la carpeta static y obtener su ruta relativa sin tener que lidiar con los ../../ de las carpetas.

Ahora, para usar las templates, las llamamos desde nuestro archivo de rutas. Primero tenemos el import desde flask y luego lo llamamos:

from flask import Flask, render_template

app = Flask(__name__)


@app.route('/')
def index():
    if True:
        return render_template('Generales/Login.html')


if __name__ == '__main__':
    app.debug = True
    app.run()

Si se fijan, estoy llamando a otra template Login.html y no a Base.html que definimos arriba. Y es aquí donde entra la magia de esto. La estructura de Login.html es así:

{% extends "Generales/Base.html" %}
{% block css %}
    {{ super() }}
    <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/singin.css') }}">
{% endblock css %}
{% block contenido %}
    <form class="form-signin" role="form" method="post">
        <h2 class="form-signin-heading">Iniciar Sesión</h2>
        <input type="text" name="txt_rut_alumno" class="form-control" placeholder="Rut Alumno" required autofocus>
        <input type="password" name="txt_password" class="form-control" placeholder="Contraseña" required>
        <button class="btn btn-lg btn-primary btn-block" type="submit">Ingresar</button>
    </form>
{% endblock contenido %}

Lo primero que tenemos es un extends, que funciona de la misma manera … estamos diciendo que nuestra plantilla base será … Base.html, y por lo tanto tendremos su estructura y podremos usar los blocks que ella tiene definida.

Es por eso que tenemos un {% block css %}, siendo que dijimos que el nombre era único. Esto significa que podríamos sobreescribir (un @override) el block css de la plantilla madre… Pero, el {{ super() }} nos permite obtener todo lo que el block original tiene, y después agregar todo lo que tengamos nosotros como plantilla hija. En nuestro ejemplo, al block original que tiene 2 css y le vamos a agregar un 3º . Esto será válido únicamente en el archivo Login.html.

Nuestra plantilla Base.html tenía definido el block contenido sin nada dentro. En Login.html sobreescribimos nuestro dicho block con lo que nosotros como plantilla tenemos.

También podemos realizar includes en el caso que queramos agregar el contenido de una plantilla en otra (plantilla Administrador.html):

{% extends "Generales/Base.html" %}
{% block contenido %}
<!-- Nav tabs -->
<ul class="nav nav-tabs">
    <li class="active"><a href="#home" data-toggle="tab">Home</a></li>
    <li><a href="#ramos" data-toggle="tab">Ramos</a></li>
    <li><a href="#alumnos" data-toggle="tab">Alumnos</a></li>
    <li><a href="#settings" data-toggle="tab">Settings</a></li>
</ul>

<!-- Tab panes -->
<div class="tab-content">
    <div class="tab-pane fade in active" id="home">...</div>
    <div class="tab-pane" id="ramos">
        {% include "Admin/AdminRamo.html" %}
    </div>
    <div class="tab-pane fade" id="alumnos">
        {% include "Admin/AdminAlumno.html" %}
    </div>
    <div class="tab-pane" id="settings">...</div>
</div>
{% endblock contenido %}

Por último, podemos enviar variables a nuestras plantillas de la siguiente manera:

@app.route('/')
def index():
    if True:
        return render_template('Generales/Login.html', Mensaje = "Error", OtroMensaje = u"Algo no funcionó")

Donde Mensaje y OtroMensaje son las variables a enviar con el contenido de cada una. OtroMensaje tiene una u antes del string para poder jugar con tildes y caracteres especiales, por lo que además deben agregar # -*- coding: utf-8 -*- al principio del archivo.

Para poder ocupar dichas variables, en nuestra template escribimos:

<h1>{{ Mensaje }}</h1>
<h2>{{ OtroMensaje }}</h2>

Y eso sería todo😀

Acerca de MaritoCares

Ingeniero Informático. Con tendencias a la programación en [C#, VB].NET, Java(Web principalmente...), PHP, JavaScript, algo mínimo de [ruby, python], y el clásico C.
Esta entrada fue publicada en Python y etiquetada , . Guarda el enlace permanente.

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s