Go con Gin, el mega tutorial (II)

Nómadas ya estamos de vuelta con la siguiente entrega de Go con Gin. En esta segunda entrega vamos a profundizar en las plantillas. Si aún no has visto el primer capítulo te recomendamos le des un vistazo.

Índice de la serie

 

** Nota importante **

ACTUALIZACIÓN: Hemos visto la necesidad de actualizar la librería de plantillado que se explica al final del post. La actualización se añade al final del post, y a pesar que vamos a cambiar la librería, esto no invalida lo ya explicado. Simplemente conviene le uso de la nueva librería de plantillado.

¿Qué son las plantillas?

Las plantillas no es algo que dependa del framework Gin, sino de Go. Go incorpora la librería text/template que nos proporciona una interfaz para generar texto de forma automatizada. Pero nosotros no queremos producir texto plano, sino HTML, y por eso la gente de Go pensaron que lo mejor sería tener una librería para poder generar HTML de forma segura. La librería que usaremos es html/template.

Empecemos definiendo las plantillas, qué son y como nos pueden beneficiar.

Como podemos estar imaginando la plantilla es algo con cierta información prefijada y otra cierta información variable, de modo que aun reemplazando la parte variable el resultado final sigue tienen sentido y validez.

Las plantillas nos serán muy útiles para cuando tengamos que definir por ejemplo el nombre de usuario que está autenticado en goblog.

Primeros ejemplos

Para mostrar un ejemplo rápido nos vamos a inventar un nombre de usuario y haremos una simulación de como quedaría una plantilla con un saludo.

Hemos ajustado la función holaMundo que teníamos en el primer capítulo para que devuelva una plantilla.

Como se puede ver la plantilla es reutilizable, solo hay que cambiar el nombre de la variable user y todo funciona correctamente.

Plantilla vista en el navegador

Como entenderéis la forma que hemos elegido para enviar el código HTML al usuario no es nada óptimo. Así que vamos a crear la primera plantilla.

Te puede interesar  Go con Gin, el mega tutorial (VIII)

Primeros habrá que indicarle a Gin donde se encuentran nuestras plantillas. Esto se hace añadiendo srv.LoadHTMLGlob(«webapp/template/*») en la función NewServer.

Y por otra parte el handler holaMundo lo cambiaremos por el siguiente:

Como se puede observar hemos cambiado las llamadas a c.Writer por un c.HTML. Este nuevo método utiliza tres parámetros para ejecutarse. El primero representa el código de respuesta que recibirá el navegador, el segundo es la plantilla que se usará para renderizar el código HTML y por último, los datos que se presentaran en la plantilla para rellenarla.

La plantilla index.html la situaremos en el directorio webapp/template, tal como hemos indicado anteriormente. El contenido de la plantilla es nada más y nada menos que la cadena que antes usábamos en c.Writer.

Puede que para aquellos que no hayáis trabajado con plantillas todavía no apreciéis las ventajas de las plantillas. Pero en verdad una plantilla es como un código fuente más, con su lenguaje propio y esto da mucha potencia.

La definición del lenguaje está en el paquete text/template/ y html/template/.

Sintaxis de las plantillas

Las plantillas, como ya hemos visto, tienen su propio lenguaje. En él se puede acceder a datos u objetos del programa en Go que invoca a la plantilla.

Para tratar los objetos de Go en la plantilla es necesario disponer de un lenguaje mínimo. Este lenguaje nos aporta sencillez para escribir las plantillas, pero también nos ofrece una gran potencia a la hora de tratar con los objetos de Go.

Veamos pues algunos ejemplos de sentencias básicas.

Sentencias condicionales

Las sentencias condicionales se definen del siguiente modo:

{{if pipeline}} T1 {{end}}

O con la sentencia else

{{if pipeline}} T1 {{else}} T0 {{end}}

{{if pipeline}} T1 {{else if pipeline}} T0 {{end}}

Pipeline no es más que la condición a evaluar para ejecutar el then o else.

Si aplicamos las sentencias condicionales a definir textos por defecto la plantilla quedaría tal que así:

Bucles

Otra sentencia importante para casi cualquier lenguaje de programación son los bucles.

{{range pipeline}} T1 {{end}}

Sería el ejemplo del tipo de bucle más habitual en programación, pero en las plantillas de Go, existe otro tipo de bucles.

{{range pipeline}} T1 {{else}} T0 {{end}}

En este caso el operador range comprueba si el pipeline tiene valores para recorrer, si es posible iterar sobre los elementos del pipeline se ejecutan las sentencias en T1, de lo contrario, si no hay elementos a iterar se ejecutan las sentencias en T0.

Te puede interesar  Puesta en marcha de Odoo en Debian - Parte 2

En este caso modificamos el handler holaMundo para poder usar los bucles.

Resultados de los bucles

Plantillas heredadas

Lo que hemos visto es bastante similar a los lenguajes de programación. Es más, hay sentencias que no hemos visto, pero se irán viendo más adelante.

Por otra parte, y distinto a lo que se suele ver en los lenguajes de programación Go permite una herencia de plantillas.

Esto es sumamente útil pues nos ayuda a reutilizar plantillas, de modo que no tenemos que repetir código cada vez.

Como acabamos de comentar Go permite la herencia o más bien reutilización de plantillas, pero Gin por defecto no permite realizar herencia de plantillas, y por eso, debemos de instalar una librería auxiliar a Gin, que nos permita realizar la herencia de plantillas.

Añadimos la nueva librería ejecutando el comando dep ensure -add github.com/gin-contrib/multitemplate.

Después de añadir la librería debemos de hacer un par de cosas, primero será crear una plantilla base.html y index.html, realmente modificaremos esta última.

En el directorio webapp/template, creamos base.html.

También debemos ajustar la plantilla index.html.

Como se puede apreciar en la plantilla base.html se realiza una llamada a la plantilla index.html. Esto lo hacemos con el operador template, donde se proporciona como primer argumento el nombre de otra plantilla dentro del directorio webapp/template. El segundo argumento es un punto (.).

En las plantillas el punto hace referencia al objeto principal, el que se proporciona en la llamada a c.HTML como último parámetro.

Ahora, mirando la plantilla index.html se observa como se corresponde con la parte del body que antes estaba en index.html y no toda la página web.

El echo de haber proporcionado el segundo argumento, el punto, en el operando template podemos acceder a los elementos del objeto principal.

El segundo cambio que debemos hacer es decirle a Gin donde están las plantillas y cual es la herencia para las plantillas.

Para hacer tal cosa crearemos una función nueva, por claridad del código, y la usaremos en NewServer.

La nueva función es templateRender y se define como sigue:

Ahora la usaremos en NewServer, tal como indicamos antes.

Uniendo todas las piezas tenemos el siguiente resultado:

Te puede interesar  Go con Gin, el mega tutorial (VII)

Resultado de plantillas Go con plantillas

Con esto terminamos la entrada de hoy. Os recomendamos que probéis y experimentéis con las plantillas y la herencia, pues en la siguiente entrada meteremos más caña.

¡Saludos!

Actualización

Tal como se comenta en la entrada quinta del mega tutorial hemos visto la necesidad de cambiar la librería de plantillado. Esto ni es bueno ni malo, solo que la nueva librería nos permite mayor usabilidad y granularidad en las plantillas.

La nueva librería es gin-template. La forma de instalarla en nuestro Gopkg.toml es ejecutando dep ensure -add github.com/foolin/gin-template.

Ahora viene el cambio importante. Esta librería permite el uso de una plantilla maestra o base junto a plantillas parciales y finalmente la plantilla que queremos renderizar.

La nueva estructura del directorio webapp/template queda del siguiente modo:

webapp/template
├── index.tpl
├── layouts
 │  ├── base.tpl
 │  ├── footer.tpl
 │  └── header.tpl
 └─── partials
    ├── error.tpl
    └── menu.tpl

Como podéis observar tenemos la carpeta layout, donde se guardan las plantillas relacionados con la estructura de la página web. Por otro lado, está la carpeta partials, esta carpeta dispondrá partes reutilizables de la página web. Por último, están las plantillas en la raíz del directorio webapp/template, en el caso del ejemplo index.tpl.

El contenido de las plantillas lo podéis ver en el repositorio de goblog.

Para utilizar la nueva librería debemos modificar el fichero main.go de webapp/router.

Hemos cambiado la asignación a srv.HTMLRender. Para hacerlo de forma más cómoda hemos utilizado una función que devuelve un renderizador de plantillas.

Lo más importante está en la función TemplateRender, aquí se define lo siguiente:

  • Root: ruta donde se encuentran las plantillas
  • Extension: extensión de los ficheros de plantillas, puede ser cualquier cosa, hemos dejado .tpl.
  • Master: la plantilla por defecto dentro del directorio Root. Nosotros hemos elegido base.tpl dentro de webapp/template/layouts/
  • Partial: lista de plantillas parciales. Éstas deben de ser rutas relativas a Root.
  • Funcs: es un objeto template.FuncMap donde se pueden definir funciones para usarlas dentro de las plantillas.

Para que el código quede más legible y claro hemos “externalizado” los valores para Partial y Funcs en unas funciones.

Y con esto queda aplicada la actualización.

Go con Gin, el mega tutorial (II)
Etiquetado en:                 

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *