Plantillas con jinja2 en matraz avanzado

En la primera parte de esta serie de tutoriales de tres partes, vimos cómo diseñar la estructura de la plantilla en una aplicación basada en matraz utilizando Jinja2. También vimos cómo se pueden usar los bloques para aprovechar la herencia en las plantillas. En esta parte, cubriremos cómo escribir un filtro personalizado, un procesador de contexto personalizado y una macro.

Empezando

Me basaré en la aplicación de catálogo que creamos en la primera parte de esta serie. Primero agregaré un procesador de contexto Jinja2 personalizado para mostrar un nombre descriptivo para cada producto. Luego, crearé un filtro Jinja2 personalizado para hacer el mismo trabajo que el procesador de contexto personalizado. Luego demostraré cómo crear una macro Jinja2 personalizada para campos de formulario regulares.

Creando un procesador de contexto Jinja2 personalizado

A veces, podríamos querer calcular o procesar un valor directamente en las plantillas. Jinja2 mantiene la noción de que el procesamiento de la lógica debe manejarse en vistas y no en plantillas, y por lo tanto, mantiene las plantillas limpias. Un procesador de contexto se convierte en una herramienta útil en este caso. Podemos pasar nuestros valores a un método; esto luego se procesará en un método de Python, y nuestro valor resultante será devuelto. Por lo tanto, básicamente solo estamos agregando una función al contexto de la plantilla (gracias a Python por permitirnos pasar las funciones como cualquier otro objeto).

Entonces, digamos que queremos agregar un nombre descriptivo para cada producto en el formato Categoría / Nombre del producto. Para ello, es necesario agregar un método, que debe ser decorado con @ app.context_processor.

@ app.context_processor def some_processor (): def full_name (product): return '0 / 1'. format (product ['category'], product ['name']) return 'full_name': full_name

Técnicamente, un contexto es solo un diccionario de Python que se puede modificar para agregar y eliminar valores. Cualquier método con el decorador especificado debe devolver un diccionario que actualice el contexto de la aplicación actual.

Para usar este procesador de contexto, solo agregue la siguiente etiqueta Jinja2 en la plantilla.

full_name (producto)

Si a esto le sumamos flask_app / templates / product.html De nuestra aplicación, se vería como:

% extiende 'home.html'% % block container% 

full_name (producto)

nombre del producto'] categoria de producto']

$ producto ['precio']

% endblock%

La página del producto resultante ahora se vería como:

Creando un filtro Jinja2 personalizado

Después de observar el ejemplo anterior, los desarrolladores experimentados podrían pensar que era estúpido usar un procesador de contexto para este propósito. Uno puede simplemente escribir un filtro para obtener el mismo resultado; Esto hará las cosas mucho más limpias. Se puede escribir un filtro para mostrar el nombre descriptivo del producto como se muestra a continuación.

@ app.template_filter ('full_name') def full_name_filter (producto): devolver '0 / 1'. formato (producto ['categoría'], producto ['nombre'])

Este filtro se puede utilizar como un filtro normal, es decir, al agregar un | (tubo) símbolo y luego el nombre del filtro.

producto | nombre completo

El filtro anterior produciría el mismo resultado que el procesador de contexto demostró hace un tiempo..

Para llevar las cosas a un nivel superior, creemos un filtro que formatee la moneda en función del idioma local del navegador actual. Para esto, primero necesitamos instalar un paquete de Python llamado ccy.

$ pip install ccy

Ahora necesitamos agregar un método para el filtro de moneda..

importar ccy desde el matraz importar solicitud @ app.template_filter ('format_currency') def format_currency_filter (cantidad): currency_code = ccy.countryccy (request.accept_languages.best [-2:]) devolver '0 1'. currency_code, monto)

Para usar este filtro, necesitamos agregar lo siguiente en nuestra plantilla:

producto ['precio'] | format_currency

Ahora la página del producto se vería así:

Creando una macro Jinja2 personalizada para formularios

Las macros nos permiten escribir piezas reutilizables de bloques HTML. Son análogos a las funciones en los lenguajes de programación regulares. Podemos pasar argumentos a las macros como lo hacemos a las funciones en Python y luego usarlas para procesar el bloque HTML. Se puede llamar a las macros cualquier cantidad de veces, y la salida variará según la lógica dentro de ellas. Trabajar con macros en Jinja2 es un tema muy común y tiene muchos casos de uso. Aquí, solo veremos cómo se puede crear una macro y luego utilizarla después de la importación.

Una de las piezas de código más redundantes en HTML es la definición de campos de entrada en formularios. La mayoría de los campos tienen un código similar con algunas modificaciones de estilo, etc. La siguiente es una macro que crea campos de entrada cuando se llama. La mejor práctica es crear la macro en un archivo separado para una mejor reutilización, por ejemplo, _helpers.html:

% macro render_field (name, type = "text") -%  % - endmacro%

Ahora, esta macro se debe importar en el archivo que se utilizará:

% from '_helpers.jinja' import render_field%

Entonces, puede simplemente llamarse usando lo siguiente:

render_field ('username', 'icon-user') render_field ('password', 'icon-key', type = "password") 

Siempre es una buena práctica definir macros en un archivo diferente para mantener el código limpio y aumentar la legibilidad del código. Si se necesita una macro privada a la que no se pueda acceder desde el archivo actual, nombre la macro con un subrayado que precede al nombre.

Conclusión

En este tutorial, hemos visto cómo escribir un filtro personalizado, un procesador de contexto personalizado y una macro personalizada para formularios. En la siguiente parte de esta serie, veremos cómo implementar el formato avanzado de fecha y hora a nivel de plantilla en Jinja2 usando moment.js.