Translate

sábado, 16 de noviembre de 2013

Web en Apache con Python y WSGI (II) - las plantillas (templates)

Buscando la solución perfecta...

Cada uno tenemos una percepción de lo que sería una solución perfecta, hace poco escuchaba a un compañero que para él, la solución perfecta, era disponer de módulos prefabricados siguiendo el ejemplo de los muebles que comercializa una gran multinacional sueca, donde te proporcionan el despiece desmontado y embalado, además de las pequeñas herramientas y tú montas el mueble, en su caso se escusaba en sus nulas dotes como carpintero o ebanista.

Este aspecto llevado a la programación, consistiria en obtener diferentes librerías que se adaptaran a nuestro proyecto y desde esta base, crear nuestro programa. Con el tiempo, las versiones de las librerías pueden evolucionar y esto nos lleva, como poco, a comprobar si todo sigue funcionando o a modificar nuestro proyecto.  Esta falta de control sobre los elementos que componen nuestros proyectos, deberían hacernos pensar y preguntarnos : ¿Es necesario obtener librerias externas para dar solución a todos nuestros proyectos o podríamos crear alguna que esté al alcance de nuestros conocimientos en programación ?  De la respuesta que demos veremos el grado de dependencia del trabajo de otros.

Los templates o plantillas

Si no has leido la primera entrega, es muy recomendable que comiences por el principio 'Web en Apache con Python y WSGI (I)'.

Siguiendo con nuestra serie de artículos para ser autosuficientes en la creación de un miniframework o entorno de programación de aplicaciones WEB para PYTHON, hoy escribiré sobre cómo funciona un sencillo y potente lector de plantillas.

Partimos de que ya existen otras librerías para plantillas web como JINJA, GENSHI, MAKO, sin olvidar DJANGO TEMPLATE SYSTEM, y muchas otras. A menudo otras librerías funcionan como generadores de HTML con muy pocas líneas de código. A partir de esta información, he dividido la lectura de plantillas en varios módulos independientes por su funcionalidad :

a) Comentarios : Quien no escribe comentarios en su código para facilitar su lectura a otros y a si mismo ?
b) Bloques :  En toda plantilla pueden existir bloques <html></html> o <head></head>o <body></body> o <footer></footer>
c) Importar plantillas externas : Siempre es posible que una parte de nuestro código no sufra modificación entre una plantilla y otras, como puede ser una cabecera o un pie de páginas html, este tipo de código se puede escribir una sola vez y luego se importará desde la plantilla que solicite su importación. También nos ofrece la posibilidad de crear plantillas dinámicas o personalizables.
d) Importar ficheros externos : Es posible que deseemos importar ficheros externos que no necesiten ser procesados como plantillas, por ejemplo los artículos de un blog, podrían importarse como texto o bien ya estarían codificados como html.
e) Condicional IF  : A veces necesitamos que una parte de la plantilla se pueda ver o no si se cumplen unas condiciones.
f) Literales o información que no debe ser procesada : Cualquier información literal que deseemos poner en una plantilla y que esté perfectamente estructurada sin necesidad de realizar ningún proceso. Por ejemplo, código html o javascript o css o un texto.
g) Variables : Imagina una página html donde saludamos a todos los que nos visitan y dependiendo de la hora del día indicamos 'buenos días...', 'buenas tardes...' o 'buenas noches...' sería sencillo incluir una variable que posteriormente podamos sustituir por el saludo correcto.

Aunque la siguiente funcionalidad está fuera de un lector de plantillas, en la nuestra incluiremos un generador de formularios para HTML5, muy util, si tenemos en cuenta que los formularios que se crean habitualmente en una página HTML son estáticos y no permiten nada más que ocultar campos o mostrar otros a través de javascript. Nuestro generador debería permitir crear cualquier tipo de formulario con muy poca codificación, pero esto formará parte de una tercera entrega.

Basándome en la codificación empleada en otras plantillas y para no inventar la rueda, emplearemos una notación para envolver la codificación que entenderá el lector de plantillas, siguiendo la misma clasificación anterior por actividad :

a)       p.e.:
b)  {%block ....%}   ...    {%endblock ....%}     p.e.:  {%block head%} y  {%endblock head%}
c)  {%include  ...  %}   p.e.:  {%include  nombre_de_plantilla.tpl %}
d)  {%merge ... %}      p.e.:   {%merge mi_articulo.txt %}
e)  {%if       {%else   {%endif}
     {%for      {%endfor}
f)  {%literal%}  ...   {%endliteral%}
g)  {{  ...  }}     envolverán el nombre de una variable a sustituir
     <%  ...  %>  encierran comandos
    <  >...</  >    encierran código html que no necesita ser procesado.

Además, es importante identificar los ficheros de plantillas con una extensión, en mi caso he decidido usar .tpl .

Un fichero de plantilla que luego procesaremos para ver el resultado (login.tpl):

login.tpl


{%include head.tpl%}
{%block body%}
{%literal%}<form>
<div>
<div>
</div>
<div>
<i><label for="email">Email</label></i>
<i><input id="email" placeholder="Email" type="email" />
</i></div>
<div>
</div>
</div>
<div>
<div>
</div>
<div>
<i><label for="password">Contraseña</label></i>
<i><input class="form-control" id="password" placeholder="Contraseña" type="password" />
</i></div>
<div>
</div>
</div>
<div>
<div>
</div>
<div>
<div>
<i><label>
<input type="checkbox" /> No cerrar sesión
</label></i></div>
<div>
</div>
</div>
</div>
<div class="form-group">
<div >
</div>
<div >
<i><button type="submit">Entrar</button></i></div>
<div>
</div>
</form>
{%endliteral%}
{%include footer.tpl%}
{%endblock body%}


Observe que no existen lineas en blanco entre el código de login.tpl, esto es importante porque nuestro lector será más rápido si no tenemos que emplear controles adicionales para las líneas sin información.  Pero deberíamos implementar algún tipo de control para avisar de que existen líneas sin información y subsanar el error.

También comprobará que existe {%include head.tpl%} y {%include footer.tpl%}. Pongamos el código de la plantilla de cabecera y pie :

head.tpl


{%block html|lang="es"%}
{%block head%}
<%title| ecommerce framework from python%>
<%author| Yo mismo%>
<%description|ecommerce %>
<!--Esto es un comentario-->
{%literal%}
<style type="text/css">
body {
padding-top: 40px;
padding-bottom: 40px;
background-color: #f5f5f5;
}
.form-signin {
max-width: 300px;
padding: 19px 29px 29px;
margin: 0 auto 20px;
background-color: #fff;
border: 1px solid #e5e5e5;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
border-radius: 5px;
-webkit-box-shadow: 0 1px 2px rgba(0,0,0,.05);
-moz-box-shadow: 0 1px 2px rgba(0,0,0,.05);
box-shadow: 0 1px 2px rgba(0,0,0,.05);
}
.form-signin .form-signin-heading,
.form-signin .checkbox {
margin-bottom: 10px;
}
.form-signin input[type="text"],
.form-signin input[type="password"] {
font-size: 16px;
height: auto;
margin-bottom: 15px;
padding: 7px 9px;
}
.form-search .input-append .search-query {
border-top-left-radius: 14px;
border-bottom-left-radius: 14px;
margin-top: 5px;
}
.form-search .input-append button:last-child{
border-top-right-radius: 14px;
border-bottom-right-radius: 14px;
margin-top: 5px;
}
/* Footer-------------------------------------------------- */
.footer {
text-align: center;
padding: 30px 0;
margin-top: 70px;
border-top: 1px solid #e5e5e5;
background-color: #f5f5f5;
}
.footer p {
margin-bottom: 0;
color: #777;
}
.footer-links {
margin: 10px 0;
}
.footer-links li {
display: inline;
padding: 0 2px;
}
.footer-links li:first-child {
padding-left: 0;
}
</style>
<!-- librerías opcionales que activan el soporte de HTML5 para IE8 -->
<!--[if lt IE 9]>
<script src="js/html5shiv.js"></script>
<script src="js/respond.min.js"></script>
<![endif]-->
{%endliteral%}</i></span>


y footer.tpl


{%block footer%}
      <!-- /container -->
      </i></span>
</i></span></code>
<div>
<code><span style="font-size: small;"><i><span style="font-size: small;"><i>
</i></span> <span style="font-size: small;"><i>          <!--Sidebar content--></i></span></i></span></code>
<code><span style="font-size: small;"><i><span style="font-size: small;"><i>      </i></span></i></span></code></div>
<code><span style="font-size: small;"><i><span style="font-size: small;"><i>
      </i></span></i></span></code>
<div>
<code><span style="font-size: small;"><i><span style="font-size: small;"><i>
</i></span></i></span></code> <code><span style="font-size: small;"><i><span style="font-size: small;"><i>          </i></span></i></span></code>
<div class="pull-right">
<code><span style="font-size: small;"><i><span style="font-size: small;"><i><a href="http://www.blogger.com/blogger.g?blogID=3486515094464098746#">Inicio</a></i></span></i></span></code></div>
<code><span style="font-size: small;"><i><span style="font-size: small;"><i>
</i></span></i></span></code> <code><span style="font-size: small;"><i><span style="font-size: small;"><i>      </i></span></i></span></code></div>
<code><span style="font-size: small;"><i><span style="font-size: small;"><i>
      <div>
          <!--Sidebar content-->
      </div>
      <div>
          © 2013 BTKS ·
<a href="http://creativecommons.org/licenses/by-nc-sa/3.0/deed.es_ES" rel="license"><img alt="Licencia de Creative Commons" src="http://i.creativecommons.org/l/by-nc-sa/3.0/88x31.png" style="border-width: 0;" /></a>
<span href="http://purl.org/dc/dcmitype/Dataset" property="dct:title" rel="dct:type" xmlns:dct="http://purl.org/dc/terms/">ΡΥΜΣΤrick</span> by <a href="http://www.blogger.com/www.betaksistemas.es" property="cc:attributionName" rel="cc:attributionURL" xmlns:cc="http://creativecommons.org/ns#">Yo mismo</a> is licensed under a <a href="http://creativecommons.org/licenses/by-nc-sa/3.0/deed.es_ES" rel="license">Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 Unported License</a>.
</div>
  {%endblock footer%}
   <!-- Placed at the end of the document so the pages load faster -->
  <!-- Librería jQuery requerida por los plugins de JavaScript -->
  <script src="js/jquery.min.js"></script>



Verá que al final no he cerrado el bloque, no es necesario, el lector de plantillas cerrará la etiqueta correctamente al generar el código html.

En el siguiente artículo veremos otro elemento esencial, el enrutado de solicitudes web o simplificando 'ENRUTADOR'.

8/6/2014
En estas fechas ya he liberado la primera versión en desarrollo de PYMETRICK donde podrá encontrar un módulo TEMPLATE.py, además de otros muchos de los que hablaremos.

No hay comentarios:

Publicar un comentario