jueves, 21 de octubre de 2010

Plantillas de sustitución

Últimamente he necesitado crear distintos correos electrónicos con formato HTML a partir de una serie de datos extraídos de una base de datos, incluyendo cabeceras y múltiples detalles. He realizado la tarea en C# y por razones practicas (sobre todo la fecha de entrega de la aplicación) la composición del correo se realiza dentro del ejecutable.

Ahora que la aplicación esta funcionando he decidido mejorar el sistema con una gestión del formateo del mensaje a través de plantillas. Después de investigar un poco encontré StringTemplate, un motor de plantillas de texto muy potente pero excesivamente complicado para mis limitados requerimientos.

Dado que estoy aprendiendo Python decidí implementar un pequeño script que permitiese formatear un texto en base al contenido de un objeto. El resultado es template.py, mi primer script útil en Python. Es infinitamente menos potente que StringTemplate pero también muchísimo más sencillo de utilizar.

Puede llamarse desde la linea de comando como:

python template.py sample.txt
"'{'key1': value1, 'key2': value2, ...}'"

donde sample.txt es el archivo que define la plantilla y el segundo argumento es el diccionario que proporcionará los datos para sustituir en la plantilla. También puede utilizarse desde otro script importándolo y utilizando un código similar a este:


plantilla = Template('sample.txt')
mensaje = plantilla.exec(data)
print(mensaje)

y data será el diccionario de datos. Se permiten anidar diccionarios para incluir los detalles.

Finalmente el archivo de plantilla (sample.txt) tiene un formato como el siguiente:


<html>
<body>
Nombre: [%Nombre%]
Correo: [%Email%]

<table>
<tr><td>Concepto</td><td>PVP</td></tr>

[$Linea$]
<tr><td>[%Concepto%]</td><td[%PVP%]<>/td></tr>
[#Linea#]

</table>
</body>
</html>

Muy simple y fácil de entender. Los elementos entre los símbolos [% %] son las claves del diccionario que se utilizarán para reemplazar por los valores y los símbolos [$ $] y [# #] marcan el inicio el fin, respectivamente de un detalle (un elemento del diccionario, llamado Linea en este caso, que contiene otro diccionario para los valores).

En fin, a pesar de su sencillez a mi me resulta muy útil y si alguien lo necesita puede utilizarlo sin ninguna restricción y aunque es obvio, sin ninguna garantía. Eso si, se agradece cualquier comentario para su mejora o notificación sobre errores. Y que se mantenga el nombre del autor si se utiliza de alguna forma sería de agradecer.