En este módulo, aprenderemos a trabajar con plantillas en Go, una herramienta poderosa para generar contenido dinámico en aplicaciones web. Las plantillas en Go permiten separar la lógica de la presentación, facilitando el mantenimiento y la escalabilidad de las aplicaciones.

Contenido

  1. Introducción a las Plantillas
  2. Sintaxis de Plantillas
  3. Funciones de Plantillas
  4. Ejemplo Práctico
  5. Ejercicios

  1. Introducción a las Plantillas

Las plantillas en Go se utilizan para generar HTML dinámico. Go proporciona el paquete html/template que permite definir plantillas con una sintaxis específica y luego renderizarlas con datos dinámicos.

Ventajas de Usar Plantillas

  • Separación de Concerns: Mantiene la lógica de negocio separada de la presentación.
  • Reutilización: Permite reutilizar componentes de la interfaz.
  • Mantenimiento: Facilita el mantenimiento y la actualización de la interfaz.

  1. Sintaxis de Plantillas

La sintaxis de las plantillas en Go es similar a la de otros motores de plantillas, pero con algunas particularidades. Aquí hay algunos elementos básicos:

Variables

Las variables se definen y se utilizan dentro de dobles llaves {{}}.

<p>{{.Title}}</p>

Estructuras de Control

Condicionales

{{if .Condition}}
  <p>Condition is true</p>
{{else}}
  <p>Condition is false</p>
{{end}}

Bucles

{{range .Items}}
  <p>{{.}}</p>
{{end}}

Comentarios

{{/* This is a comment */}}

  1. Funciones de Plantillas

Go permite el uso de funciones dentro de las plantillas para realizar operaciones comunes. Algunas funciones integradas incluyen len, and, or, not, etc.

Ejemplo de Función

<p>Length of the list: {{len .Items}}</p>

También puedes definir tus propias funciones y pasarlas al motor de plantillas.

  1. Ejemplo Práctico

Vamos a crear un ejemplo práctico donde definimos una plantilla y la renderizamos con datos dinámicos.

Paso 1: Definir la Plantilla

Crea un archivo template.html con el siguiente contenido:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{{.Title}}</title>
</head>
<body>
    <h1>{{.Title}}</h1>
    <p>{{.Content}}</p>
    <ul>
        {{range .Items}}
            <li>{{.}}</li>
        {{end}}
    </ul>
</body>
</html>

Paso 2: Cargar y Renderizar la Plantilla

Crea un archivo main.go con el siguiente contenido:

package main

import (
    "html/template"
    "net/http"
)

type PageData struct {
    Title   string
    Content string
    Items   []string
}

func handler(w http.ResponseWriter, r *http.Request) {
    tmpl, err := template.ParseFiles("template.html")
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }

    data := PageData{
        Title:   "My Page Title",
        Content: "This is the content of the page.",
        Items:   []string{"Item 1", "Item 2", "Item 3"},
    }

    err = tmpl.Execute(w, data)
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
    }
}

func main() {
    http.HandleFunc("/", handler)
    http.ListenAndServe(":8080", nil)
}

Explicación del Código

  1. Definición de la Estructura: PageData es una estructura que contiene los datos que queremos pasar a la plantilla.
  2. Cargar la Plantilla: template.ParseFiles("template.html") carga la plantilla desde el archivo.
  3. Renderizar la Plantilla: tmpl.Execute(w, data) renderiza la plantilla con los datos proporcionados.

  1. Ejercicios

Ejercicio 1: Crear una Plantilla con una Tabla

Crea una plantilla que muestre una tabla con datos de productos (nombre, precio, cantidad). Renderiza la plantilla con una lista de productos.

Ejercicio 2: Añadir Funciones Personalizadas

Define una función personalizada que formatee los precios de los productos y úsala en la plantilla.

Soluciones

Solución Ejercicio 1

template.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{{.Title}}</title>
</head>
<body>
    <h1>{{.Title}}</h1>
    <table>
        <tr>
            <th>Name</th>
            <th>Price</th>
            <th>Quantity</th>
        </tr>
        {{range .Products}}
        <tr>
            <td>{{.Name}}</td>
            <td>{{.Price}}</td>
            <td>{{.Quantity}}</td>
        </tr>
        {{end}}
    </table>
</body>
</html>

main.go

package main

import (
    "html/template"
    "net/http"
)

type Product struct {
    Name     string
    Price    float64
    Quantity int
}

type PageData struct {
    Title    string
    Products []Product
}

func handler(w http.ResponseWriter, r *http.Request) {
    tmpl, err := template.ParseFiles("template.html")
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }

    data := PageData{
        Title: "Product List",
        Products: []Product{
            {"Product 1", 10.0, 5},
            {"Product 2", 20.0, 3},
            {"Product 3", 30.0, 7},
        },
    }

    err = tmpl.Execute(w, data)
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
    }
}

func main() {
    http.HandleFunc("/", handler)
    http.ListenAndServe(":8080", nil)
}

Solución Ejercicio 2

main.go

package main

import (
    "fmt"
    "html/template"
    "net/http"
)

type Product struct {
    Name     string
    Price    float64
    Quantity int
}

type PageData struct {
    Title    string
    Products []Product
}

func formatPrice(price float64) string {
    return fmt.Sprintf("$%.2f", price)
}

func handler(w http.ResponseWriter, r *http.Request) {
    tmpl := template.New("template.html").Funcs(template.FuncMap{
        "formatPrice": formatPrice,
    })
    tmpl, err := tmpl.ParseFiles("template.html")
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }

    data := PageData{
        Title: "Product List",
        Products: []Product{
            {"Product 1", 10.0, 5},
            {"Product 2", 20.0, 3},
            {"Product 3", 30.0, 7},
        },
    }

    err = tmpl.Execute(w, data)
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
    }
}

func main() {
    http.HandleFunc("/", handler)
    http.ListenAndServe(":8080", nil)
}

template.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{{.Title}}</title>
</head>
<body>
    <h1>{{.Title}}</h1>
    <table>
        <tr>
            <th>Name</th>
            <th>Price</th>
            <th>Quantity</th>
        </tr>
        {{range .Products}}
        <tr>
            <td>{{.Name}}</td>
            <td>{{formatPrice .Price}}</td>
            <td>{{.Quantity}}</td>
        </tr>
        {{end}}
    </table>
</body>
</html>

Conclusión

En este módulo, hemos aprendido a trabajar con plantillas en Go, desde la sintaxis básica hasta la implementación de funciones personalizadas. Las plantillas son una herramienta esencial para generar contenido dinámico en aplicaciones web, y su correcta utilización puede mejorar significativamente la mantenibilidad y escalabilidad de tu código.

En el próximo módulo, exploraremos cómo trabajar con bases de datos en Go, lo que nos permitirá almacenar y recuperar datos de manera eficiente.

© Copyright 2024. Todos los derechos reservados