Usar plantillas con Google App Egine (Python)



Ya hemos hablado anteriormente sobre Google App Engine del que hicimos una introducción y aprendimos además a hacer una aplicación sencilla.

Aunque es posible generar todo nuestro código HTML desde cadenas en Python, esto no es ni muy óptimo, ni muy ordenado, ni muy Pythónico. Si no usamos algún mecanismo para estructurar nuestra salida HTML, nos veremos obligados a escarbar por el código cada vez que pretendamos hacer un cambio (por muy trivial que éste sea) a nuestro código para localizarlo y después modificarlo.

Este método no es ni eficaz, ni atractivo ni mantenible, creo que todos nos las hemos tenido que medir con el tipo de aplicaciones web que siguen esa “filosofía” por llamarlo de alguna forma y sabemos el horror que es modificarlas o mantenerlas, y no miro a nadie osCommerce, “coff”, “coff”, moodle, “coff”, “coff”, ay que tos que me ha dado. Como en el anuncio del Mediamarkt, nosotros no somos tontos, así que vamos a utilizar plantillas en nuestras aplicaciones para generar nuestro código HTML.

Nuestra aplicación web sigue necesitando que algunas partes del HTML sean generadas de forma dinámica, por lo que crear archivos HTML a parte a modo de vista, no nos sirve. La manera de solventar ambos problemas es usar plantillas. El App Engine utiliza el sistema de plantillas del proyecto Django por defecto, pero puedes utilizar cualquier otro tipo de plantillas, hoy voy a hablaros del de Django ya que es el que viene incluido en el App Engine de facto.

Sintaxis de las plantillas

La sintaxis de las plantillas de Django consiste en código HTML normal potenciado por elementos entre llaves ({{...}}) donde se definen comandos o variables usados por el motor de plantillas. Si seguimos con el ejemplo del artículo anterior podemos generar nuestro HTML a través de la plantilla index.html:

<p>{{ resp }}</p>
<form method="post" action="/">
    <p>Introduce un número entre 1 y 100: <input type="text" name="resp" /></p>
    <p><input type="submit" /></p>
</form>
Las plantillas disponen de áreas especiales donde el texto Python puede ser substituido dentro de la salida HTML que genera la plantilla. Dichas áreas se delimitan utilizando llaves dobles, en nuestro ejemplo anterior {{ resp }}.

Vamos a usar una plantilla diferente después de que el usuario haya elegido una cifra, vamos a mostrar ambos valores, el que ha seleccionado el usuario y el resultado en la plantilla estimacion.html:

<p>Tu estimación fue: {{ estimacion }}</p>
<p>{{ real }}</p>
<form method="post" action="/">
    <p>Introduce un número entre 1 y 100: <input type="text" name="resp" /></p>
    <p><input type="submit" /></p>
</form>
La plantilla anterior dispone de dos áreas a ser reemplazadas con datos servidos desde Python.

Por convención alojaremos las plantillas dentro de un directorio llamado templates, de esta manera conseguiremos separar nuestro código HTML del código Python de la aplicación. Llamar al directorio templates no es una regla, es una convención como ya he dicho, pero siempre es buena idea seguir las convenciones para facilitar el desarrollo en equipo.

Usar las plantillas desde Python

Las plantillas por si solas no sirven de mucho, obviamente, tenemos que hacer que nuestro código Python devuelva el contenido de las mismas una vez han sido procesadas y las palabras clave hayan sido modificadas, proceso que se conoce como renderizado de la plantilla.

Siguiendo el ejemplo del artículo anterior, vamos a hacer las modificaciones necesarias al archivo index.py para que utilice el sistema de plantillas de Django existente en el core del App Engine:

# -- encoding: utf-8 --
import os
import random
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
from google.appengine.ext.webapp import template
class MainHandler(webapp.RequestHandler):
    def get(self):
        temp = os.path.join(os.path.dirname(__file__),
                    'templates/index.html')
        outstr = template.render(
            temp,
            {'resp': '¡Buena Suerte!'})
        self.response.headers['Content-Type'] = 'text/html'
        self.response.out.write(outstr)
    def post(self):
        estimacion = self.request.get('resp')
        msg = ''
        resp = -1
        try:
            resp = int(estimacion)
        except:
            resp = -1
        answer = random.randint(1, 100)
        if resp < answer:
            msg = 'Tu número es demasiado bajo'
        if resp is answer:
            msg = 'Has acertado campeón, toma un pin!'
        if resp > answer:
            msg = 'Tu número es demasiado alto'
        temp = os.path.join(os.path.dirname(__file__),
                    'templates/estimacion.html')
        outstr = template.render(
            temp,
            {'real': msg, 'estimacion': estimacion})
        self.response.out.write(outstr)
def main():
    application = webapp.WSGIApplication(
                                         [('/.*', MainHandler)],
                                         debug=True)
    run_wsgi_app(application)
if __name__ is '__main__':
    main()
Podemos probar la aplicación para comprobar que las plantillas funcionan como se espera:


Plantilla para el índice.


Plantilla una vez se ha añadido un valor.

Explicación

Los cambios realizados a nuestro anterior ejemplo son mínimos. Hemos introducido el módulo de Python os para poder acceder a los archivos del directorio y poder cargar de esa manera los archivos que contienen el código de nuestras plantillas. Además hemos cargado el módulo template del webapp.

Hemos eliminado toda referencia a código HTML de nuestro código Python. El trabajo duro de las plantillas lo realiza el método template.render() que toma dos parámetros. El primero es la localización del archivo de la plantilla y el segundo un diccionario de Python que contiene el par de claves valor con los parámetros a reemplazar en la plantilla.

Los datos del diccionario de Python sustituyen a las palabras Python en la plantilla ( {{ resp }} por ejemplo ). El proceso es muy simple, cuando el motor de renderizado encuentra un área con una palabra en la plantilla, busca en el diccionario una clave que coincida para reemplazar el valor de la palabra en el HTML generado.

Conclusión

Como podéis ver, el uso básico de plantillas de Django es realmente simple, las plantillas pueden contener condicionales y bucles, pero de eso ya hablaremos más adelante. En la próxima entrega de la serie veremos como se implementa el patrón de diseño MVC en Google App Engine y como utilizar archivos estáticos como hojas de estilo en cascada y archivos JavaScript.



Más en Genbeta Dev | Google App Engine Series

Portada de Genbeta