Usando plantillas Jinja2 en GAE

Posted by in HTML5, Python

Seguimos trabajando con Google App Engine y Python, donde hoy vamos a mejorar bastante nuestra aplicación ampliando sobre cómo trabajar con plantillas. El código lo teneis disponible en GitHub.

Modifcaciones en la plantilla

He modificado la plantilla para incluir un menú, y así poder seguir usando la plantilla de forma que el contenido del menú sea visualizado siempre en la zona central. La base de la aplicación diseñada cuenta con una zona central que es donde queremos centrar el contenido, y así lo haremos en la plantilla

Modificación de la plantilla

Modificación de la plantilla

Ahora jugaremos con las plantillas. Cuando pulsemos en «Saludo«, se mostrará una nueva plantilla, y cuando se pinche en «Lista«, utilizaremos otra plantilla que será mostrada en el mismo sitio, y mostraremos la lista.

Preparando la plantilla para el saludo

Para mostrar el saludo, vamos a extender la plantilla base creando saludo.html, cuyo código es:


{% extends '/base.html' %}
{% block contenido %}
<h1>Un saludo desde ManejandoDatos.es</h1>
<p class=alert alert-danger">
Estamos probando <strong>Google App Engine </strong>, y trabajar con plantillas!!
</p>
{% endblock %}

La primera línea indica que se trata de una extensión de la plantilla base (o sea, de base.html) y además indicamos que el contenido sea ubicado en el bloque contenido.

Preparando Listas.html

De igual forma, preparamos listas.html como una extensión de base.html, pero esta vez queremos procesar una lista, así que usamos instrucciones for. El código es el siguiente:

</pre>
<pre>{% extends '/base.html' %}
{% block contenido %}
<h1>Un saludo desde ManejandoDatos.es</h1>

<ul class="list-group">
    {% for post in posts %}
          <li class="list-group-item"> <strong>{{ post.title}}</strong> - {{ post.content}} </li>
    {% endfor %}
</ul>
{% endblock %}</pre>
<pre>

Al igual que con saludo.html, incluimos la extensión de base.html, y preparamos el código para recibir los datos en la variable posts, y con un bucle for los mostramos.

Modificando la aplicación .py

Ya tenemos las plantillas preparadas, y es hora de modificar el fichero ejemplo_plantilla.py, que es el que se encarga de que todo funcione, y que hemos rediseñado por completo. Así, hemos creado una clase nueva llamada Para ello, vamos a incluir una clase Handler que recibe webapp2.RequestHandler y que tiene 2 métodos:

  • render para «generar» el código HTML que será mostrado por el navegador
  • write muestra el texto que pasamos como parámetro en el navegador

Ahora vamos a crear 3 clases que heredan de Handler, y que como propiedad template tienen el nombre de la plantilla con la que trabajar. El método get es el que se encarga en cada caso de mostrar la información.

El segundo de los puntos críticos de la aplicación es la llamada a las distintas clases, que se hace con tuplas (‘/’, Principal), (‘/saludo’, Saludo), (‘/lista’, Listas), y que se hace en la variable app (casi al final del código).

Y el código queda así:


import webapp2
import jinja2
import os

JINJA_ENVIRONMENT = jinja2.Environment(loader=jinja2.FileSystemLoader(os.path.dirname(__file__) + '/templates' ), extensions=['jinja2.ext.autoescape'], autoescape=True)

def render_str(template, **params):
t = JINJA_ENVIRONMENT.get_template(template)
return t.render(params)

class Handler(webapp2.RequestHandler):
""" Clase que maneja todo el render y response """
def render(self, template, **kw):
self.response.out.write(render_str(template, **kw))
def write(self, *a, **kw):
self.response.out.write(*a, **kw)

class Principal(Handler):
template = 'base.html'
def get(self):
self.render(self.template)

class Saludo(Handler):
template = 'saludo.html'
def get(self):
self.render(self.template)

class Listas(Handler):
template = 'listas.html'
def get(self):
posts = [
{"title":"Titulo 1", "content":"Habia una vez ..."},
{"title":"Titulo 2", "content":"Que bueno que llegaste ..."},
{"title":"Titulo 4", "content":"Y ahora ..."},
{"title":"a title4", "content":"Vuelvo ..."}
]
self.render(self.template, posts= posts)

app = webapp2.WSGIApplication([ ('/', Principal),
('/saludo', Saludo),
('/lista', Listas)], debug=True)

Y ahora vemos el resultado.

Probando GAE con plantillas

Probando GAEProbando GAE con plantillas

Y al pulsar en Listas:

Probando GAE con plantillas

Probando GAE con plantillas

Unicode

Para reducir los problemas con unicode en Python 2, una buena opción es poner al inicio del código lo siguiente:

</pre>
<pre class="lang-py prettyprint prettyprinted"><code><span class="kwd">import</span><span class="pln"> sys
reload</span><span class="pun">(</span><span class="pln">sys</span><span class="pun">)</span><span class="pln">
sys</span><span class="pun">.</span><span class="pln">setdefaultencoding</span><span class="pun">(</span><span class="str">'utf-8'</span><span class="pun">)</span></code></pre>
<pre>

La solución la leí aquí.

Espero que os sea de mucho interés el contenido de esta entrada!