Generación de contenido dinámico con plantillas de Golang

Beginner

This tutorial is from open-source community. Access the source code

Introducción

El paquete text/template de Golang proporciona una forma de crear contenido dinámico o mostrar una salida personalizada al usuario. Este paquete permite mezclar texto estático y acciones encerradas en {{...}} para insertar contenido dinámico.

Plantillas de texto

En este laboratorio, se te pide demostrar el uso del paquete text/template para generar contenido dinámico.

  • Utiliza el paquete text/template para generar contenido dinámico.
  • Utiliza la función template.Must para generar un error en caso de que Parse devuelva un error.
  • Utiliza la acción {{.FieldName}} para acceder a los campos de un struct.
  • Utiliza la acción {{if. -}} si {{else -}} no {{end}}\n para proporcionar una ejecución condicional para las plantillas.
  • Utiliza la acción {{range.}}{{.}} {{end}}\n para recorrer slices, arrays, maps o canales.
$ go run templates.go
Valor: algún texto
Valor: 5
Valor: [Go Rust C++ C#]
Nombre: Jane Doe
Nombre: Mickey Mouse
si
no
Rango: Go Rust C++ C#

A continuación se muestra el código completo:

// Go ofrece soporte integrado para crear contenido dinámico o mostrar una
// salida personalizada al usuario con el paquete `text/template`. Un paquete
// hermano llamado `html/template` proporciona la misma API pero tiene
// características de seguridad adicionales y se debe utilizar para generar HTML.

package main

import (
    "os"
    "text/template"
)

func main() {

    // Podemos crear una nueva plantilla y analizar su cuerpo a partir de
    // una cadena.
    // Las plantillas son una mezcla de texto estático y "acciones" encerradas
    // en `{{...}}` que se utilizan para insertar dinámicamente contenido.
    t1 := template.New("t1")
    t1, err := t1.Parse("Valor es {{.}}\n")
    if err!= nil {
        panic(err)
    }

    // Alternativamente, podemos utilizar la función `template.Must` para
    // generar un error en caso de que `Parse` devuelva un error. Esto es
    // especialmente útil para las plantillas inicializadas en el ámbito global.
    t1 = template.Must(t1.Parse("Valor: {{.}}\n"))

    // Al "ejecutar" la plantilla, generamos su texto con
    // valores específicos para sus acciones. La acción `{{.}}` es
    // reemplazada por el valor pasado como parámetro a `Execute`.
    t1.Execute(os.Stdout, "algún texto")
    t1.Execute(os.Stdout, 5)
    t1.Execute(os.Stdout, []string{
        "Go",
        "Rust",
        "C++",
        "C#",
    })

    // Función auxiliar que utilizaremos más adelante.
    Create := func(name, t string) *template.Template {
        return template.Must(template.New(name).Parse(t))
    }

    // Si los datos son un struct, podemos utilizar la acción `{{.FieldName}}` para acceder
    // a sus campos. Los campos deben ser exportados para ser accesibles cuando
    // se está ejecutando una plantilla.
    t2 := Create("t2", "Nombre: {{.Nombre}}\n")

    t2.Execute(os.Stdout, struct {
        Nombre string
    }{"Jane Doe"})

    // Lo mismo se aplica a los maps; con los maps no hay restricción sobre el
    // caso de los nombres de las claves.
    t2.Execute(os.Stdout, map[string]string{
        "Nombre": "Mickey Mouse",
    })

    // if/else proporcionan una ejecución condicional para las plantillas. Un valor se considera
    // falso si es el valor predeterminado de un tipo, como 0, una cadena vacía,
    // un puntero nulo, etc.
    // Este ejemplo demuestra otra
    // característica de las plantillas: utilizar `-` en las acciones para eliminar el espacio en blanco.
    t3 := Create("t3",
        "{{if. -}} si {{else -}} no {{end}}\n")
    t3.Execute(os.Stdout, "no está vacío")
    t3.Execute(os.Stdout, "")

    // Los bloques range nos permiten recorrer slices, arrays, maps o canales. Dentro
    // del bloque range, `{{.}}` se establece en el elemento actual de la iteración.
    t4 := Create("t4",
        "Rango: {{range.}}{{.}} {{end}}\n")
    t4.Execute(os.Stdout,
        []string{
            "Go",
            "Rust",
            "C++",
            "C#",
        })
}

Resumen

En este laboratorio, aprendimos cómo utilizar el paquete text/template para generar contenido dinámico. Demostramos cómo acceder a los campos de un struct, proporcionar una ejecución condicional para las plantillas y recorrer slices, arrays, maps o canales.