Академический Документы
Профессиональный Документы
Культура Документы
El lenguaje Jinja 2.
Flask es únicamente un framework para ofrecer servicios basados en HTTP. Para poder
publicar contenidos dinámicos en HTML es necesario utilizar Jinja2.
Jinja es un lenguaje de plantillas (templates) escrito en Python, el cual permite insertar datos
procesados y texto predeterminado dentro de un documento de texto.
Jinja no sólo es utilizado por Flask. Algunos otros proyectos como Ansible lo utilizan para
crear playbooks en YAML.
Expresiones.
Las expresiones deben estar encerradas entre llaves nuevamente "{ }".
Sintaxis:
{{ <expresión> }}
Declaraciones.
Las declaraciones deben estar encerradas entre signos de porcentajes "%".
Sintaxis:
{% <declaración> %}
...
...
{% endof<tipo de declaración> %}
Comentarios.
Las declaraciones deben estar encerradas entre signos de gato "#".
Sintaxis:
{# <comentario> #}
La clase jinja2.Template.
Esta clase crea objetos a partir del texto que se ingresa como parámetro que corresponden a
la plantilla sobre la que se van a ejecutar el código de sustitución.
Ejemplo:
In [2]:
plantilla = jinja2.Template("Hola, {{nombre}}.")
El método render().
Este método, al ser ejecutado desde un objeto instanciado de la clase jinja2.Template da por
resultado el texto procesado por la sintaxis de Jinja. Los argumentos que se ingresen en
formato <identificador> = <objeto> de forma susesiva y separados por comas serán
sustituidos cuando se les haga referencia.
Ejemplo:
In [3]:
plantilla = jinja2.Template("Hola,{{nombre}}.")
In [4]:
plantilla.render(nombre="Juan")
Out[4]:
'Hola,Juan.'
Expresiones.
Ejemplos:
In [5]:
texto = "Hola, {{persona['nombre'].upper()}}."
In [6]:
plantilla = jinja2.Template(texto)
In [7]:
plantilla.render(persona={'nombre':'Jose', 'apellido': 'Pérez'})
Out[7]:
'Hola, JOSE.'
Filtros.
Un filtro en Jinja 2 es una especie de función que modifica al objeto resultante de una
expresión. Es posible consultar lo diversos filtros que ofrece Jinja en esta
liga: http://jinja.pocoo.org/docs/2.9/templates/#builtin-filters
Jinja 2 puede aplicar diversos filtros al texto que se ingresa mediante pipes usando la
siguiente sintaxis:
Ejemplos:
En estos ejemplos se utilizarán los filtros center y reverse de forma separada y posteriormente
combinada.
In [8]:
texto = "Hola, {{persona['nombre'].upper() | center(40)}}."
plantilla = jinja2.Template(texto)
plantilla.render(persona={'nombre':'Jose', 'apellido': 'Pérez'})
Out[8]:
'Hola, JOSE .'
In [9]:
texto = "Hola, {{persona['nombre'].upper() | reverse}}."
plantilla = jinja2.Template(texto)
plantilla.render(persona={'nombre':'Jose', 'apellido': 'Pérez'})
Out[9]:
'Hola, ESOJ.'
In [10]:
texto = "Hola, {{persona['nombre'].upper()| center(40)| reverse}}."
plantilla = jinja2.Template(texto)
plantilla.render(persona={'nombre':'Jose', 'apellido': 'Pérez'})
Out[10]:
'Hola, ESOJ .'
Declaraciones.
Una declaración corresponde a un bloque de código que se ejecuta y que incluye varias
expresiones con la siguiente sintaxis.
{% <declaración> %}
...
<texto y expresiones>
...
Condicionales con if .
Jinja 2 permite el uso del condicionales if con la siguiente sintaxis:
<Texto y código>
{% endif %}
Cabe hacer notar que los operadores lógicos de Python son los mismos que se utilizan para
las expresiones lógicas de este condicional.
Ejemplo:
In [11]:
texto = "Hola {{persona['nombre']}}.\
{% if persona['socio'] %}\
\nUsted es socio distinguido.\
{% endif %}"
In [12]:
print(texto)
Hola Juan.
<Texto y código>
<Texto y código>
...
...
<Texto y código>
{% _else %}
<Texto y código>
{% endif %}
Ejemplo:
In [15]:
texto = "Hola {{persona['nombre']}}.\n\
{% if persona['status'] == 'socio' %}\
Usted es socio distinguido.\
{% elif persona['status'] == 'cliente' %}\
Usted tiene una cuenta de cliente.\
{% else %}\
Por favor indique si es socio o cliente.\
{% endif %}"
In [16]:
plantilla = jinja2.Template(texto)
resultado = plantilla.render(persona={'nombre':'Jose', 'status': 'socio'}
)
print(resultado)
Hola Jose.
Usted es socio distinguido.
In [17]:
plantilla = jinja2.Template(texto)
resultado = plantilla.render(persona={'nombre':'Juan', 'status': 'cliente
'})
print(resultado)
Hola Juan.
Usted tiene una cuenta de cliente.
In [18]:
plantilla = jinja2.Template(texto)
resultado = plantilla.render(persona={'nombre':'Juan'})
print(resultado)
Hola Juan.
Por favor indique si es socio o cliente.
Validaciones adicionales.
Aemás de los operadores lógicos de Python, Jinja 2 cuenta con algunas otras validaciones
que pueden ser consultadas en esta liga: http://jinja.pocoo.org/docs/2.9/templates/#builtin-tests
Ejemplo:
{{ <elemento> }}
{% endfor %}
Ejemplo: Se utilizará el ciclo for para una lista que a su vez contiene listas de dos elementos.
In [21]:
texto = "Enlaces recomendados:\n\
{%for nombre, liga in dato %}\
\n{{ nombre }}: {{ liga }} \
{% endfor %}"
In [22]:
ligas = [['slashdot', 'https://slashdot.org'],
['pythonista', 'https://pythonista.mx'],
['cloudevel', 'https://cloudevel.com']]
In [23]:
plantilla = jinja2.Template(texto)
resultado = plantilla.render(dato=ligas)
print(resultado)
Enlaces recomendados:
slashdot: https://slashdot.org
pythonista: https://pythonista.mx
cloudevel: https://cloudevel.com
Macros.
Lo macros se comportan de forma similar a una función de Python y se definen con la
siguiente sintaxis:
<texto y código>
{% endmacro %}
{{ <nombre>(<parámetros>) }}
Ejemplo:
In [24]:
texto = '{% macro suma (a, b=2) %}\
La suma es {{a + b}}.\n\
{% endmacro %}\
{{ suma(2)}}\
{{ suma(2, 3) }}'
In [25]:
plantilla = jinja2.Template(texto)
resultado = plantilla.render()
print(resultado)
La suma es 4.
La suma es 5.
La clase jinja2.FileSystemLoader.
La clase jinja2.FileSystemLoader permite definir los parámetros necesarios para acceder a un
sistema de archivos, definiendo una o varias rutas en las que se encontrarán las plantillas.
Sintaxis:
jinja2.FileSystemLoader('<ruta>')
Ejemplo:*
In [26]:
%pwd
Out[26]:
'/home/oi/py201_Desarrollo_web_con_Flask'
La clase jinja2.Environment.
La clase jinja2.Environment permite definir la configuración de diversas propiedades de Jinja2,
incluyendo el parámetro loader el cual debe corresponder a un objeto instanciado de la
clase jinja2.FileSystemLoader.
Sintaxis:
El objeto resultante contiene al método get_template(), el cual permite acceder a una archivo
cuyo nombre o ruta relativa se ingresa como parámetro.
Sintaxis:
<!DOCTYPE html>
<html>
<head>
<title>Bienvenidos </title>
</head>
<body>
<h1>Listado de referencias</h1>
<ul>
<ul>
{% endfor %}
</body>
In [28]:
ligas = [['slashdot', 'https://slashdot.org'],
['pythonista', 'https://pythonista.mx'],
['cloudevel', 'https://cloudevel.com']]
In [29]:
%pwd
Out[29]:
'/home/oi/py201_Desarrollo_web_con_Flask'
<Template 'plantilla.html'>
In [32]:
print(plantilla.render(lista=ligas))
<!DOCTYPE html>
<html>
<head>
<title>Bienvenidos </title>
</head>
<body>
<h1>Listado de referencias</h1>
<ul>
Importación de macros.
Es posible importar un macro desde una plantilla mediante la siguiente sintaxis:
Ejemplo:
{% endmacro %}
{{ suma(3, 4) }}
In [33]:
%pwd
Out[33]:
'/home/oi/py201_Desarrollo_web_con_Flask'
La suma es 7.
Herencia de plantillas.
Jinja 2 tiene la capacidad de aprovechar plantillas que pueden ser modificadas utilizando el
concepto de bloques.
Bloques.
Los bloques son elementos que delimitan una porción de texto y alos que se les asigna un
nombre. Utilizan la siguiente sintaxis:
{% block <nombre> %}
...
...
{% endblock% }
La porción de texto delimitada por los bloques pueden ser insertada en cualquier otra parte
invocándolos de la siguiente manera:
{% block <nombre> %}
Esto traerá consigo el contenido completo de la plantilla de origen y es posible sobrescribir los
bloques simpremente redefiniéndolos.
<!DOCTYPE html>
<html>
<head>
{% block head %}
</head>
<body>
<div id="footer">
{% block footer %}
{% endblock %}
</div>
</body>
In [36]:
%pwd
Out[36]:
'/home/oi/py201_Desarrollo_web_con_Flask'
Nota: Verificar que la ruta actual corresponde a la que se indica en la celda de de abajo.
In [37]:
entorno = jinja2.Environment(loader=jinja2.FileSystemLoader('/home/oi/py2
01_Desarrollo_web_con_Flask/codigo'))
plantilla = entorno.get_template("plantilla_base.html")
print(plantilla.render())
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div id="content">Hola, Bienvenidos.</div>
<div id="footer">
{% extends "plantilla_base.html" %}
{% block footer %}
{% endblock %}
Nota: Verificar que la ruta actual corresponde a la que se indica en la celda de de abajo.
In [38]:
entorno = jinja2.Environment(loader=jinja2.FileSystemLoader('/home/oi/py2
01_Desarrollo_web_con_Flask/codigo'))
plantilla = entorno.get_template("plantilla_hija.html")
resultado = plantilla.render()
print(resultado)
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div id="content">Hola, Bienvenidos.</div>
<div id="footer">
</div>
</body>
Flask y Jinja 2.
Flask utiliza por defecto las plantillas de Jinja 2 mediante el módulo flask.render_template().
Del mismo modo, está configurado para buscar los archivos de plantilla en el
subdirectorio templates localizado en el directorio desde el que se está corriendo flask.
<!DOCTYPE html>
<html>
<head>
<title>Bienvenidos </title>
</head>
<body>
<h1>Listado de referencias</h1>
<ul>
{% endfor %}
<ul>
</body>
In [39]:
%ls templates
Advertencia: Una vez ejecutada la siguente celda, es necesario reiniciar el kernel de Jupyter
para poder ejecutar el resto de las celdas de la notebook.
In [ ]:
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/')
def inicio():
#Si no se define el parámetro host, flask sólo será visible desde localho
st
app.run(host='0.0.0.0')