En aquest tema, aprendrem a treballar amb plantilles en Go per generar contingut dinàmic en aplicacions web. Les plantilles són una eina poderosa per separar la lògica de presentació de la lògica de negoci, permetent una millor organització i mantenibilitat del codi.

Continguts

Introducció a les Plantilles

Go proporciona el paquet html/template per treballar amb plantilles HTML. Aquest paquet permet definir plantilles amb placeholders que poden ser reemplaçats per dades dinàmiques en temps d'execució.

Exemple de Plantilla

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

En aquest exemple, {{.Title}}, {{.Heading}} i {{.Content}} són placeholders que seran reemplaçats per dades dinàmiques.

Creació d'una Plantilla Bàsica

Pas 1: Definir la Plantilla

Crea un fitxer anomenat template.html amb el següent contingut:

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

Pas 2: Carregar i Executar la Plantilla

Crea un fitxer Go anomenat main.go amb el següent codi:

package main

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

type PageData struct {
    Title   string
    Heading string
    Content 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:   "Pàgina d'Exemple",
        Heading: "Benvingut a Go Templates",
        Content: "Aquesta és una pàgina generada dinàmicament amb plantilles.",
    }

    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ó del Codi

  1. Definició de la Plantilla: El fitxer template.html conté la plantilla HTML amb placeholders.
  2. Estructura de Dades: La struct PageData defineix les dades que passarem a la plantilla.
  3. Handler HTTP: La funció handler carrega la plantilla, crea una instància de PageData amb les dades, i executa la plantilla passant-li les dades.
  4. Servidor HTTP: La funció main configura un servidor HTTP que escolta a la porta 8080 i utilitza el handler definit.

Passar Dades a les Plantilles

Les dades es passen a les plantilles mitjançant una struct o un map. Els placeholders a la plantilla corresponen als camps de la struct o les claus del map.

Exemple amb Map

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 := map[string]string{
        "Title":   "Pàgina d'Exemple",
        "Heading": "Benvingut a Go Templates",
        "Content": "Aquesta és una pàgina generada dinàmicament amb plantilles.",
    }

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

Plantilles Niuades

Les plantilles niuades permeten reutilitzar components comuns com capçaleres, peus de pàgina, etc.

Exemple de Plantilles Niuades

base.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{{.Title}}</title>
</head>
<body>
    {{template "header" .}}
    {{template "content" .}}
    {{template "footer" .}}
</body>
</html>

header.html

{{define "header"}}
<header>
    <h1>{{.Heading}}</h1>
</header>
{{end}}

footer.html

{{define "footer"}}
<footer>
    <p>Peu de pàgina</p>
</footer>
{{end}}

content.html

{{define "content"}}
<main>
    <p>{{.Content}}</p>
</main>
{{end}}

Carregar i Executar Plantilles Niuades

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

    data := PageData{
        Title:   "Pàgina d'Exemple",
        Heading: "Benvingut a Go Templates",
        Content: "Aquesta és una pàgina generada dinàmicament amb plantilles.",
    }

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

Funcions de Plantilla

Go permet definir funcions personalitzades que es poden utilitzar dins de les plantilles.

Exemple de Funció de Plantilla

func uppercase(s string) string {
    return strings.ToUpper(s)
}

func handler(w http.ResponseWriter, r *http.Request) {
    tmpl := template.New("template.html").Funcs(template.FuncMap{
        "uppercase": uppercase,
    })

    tmpl, err := tmpl.ParseFiles("template.html")
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }

    data := PageData{
        Title:   "Pàgina d'Exemple",
        Heading: "Benvingut a Go Templates",
        Content: "Aquesta és una pàgina generada dinàmicament amb plantilles.",
    }

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

template.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{{.Title}}</title>
</head>
<body>
    <h1>{{uppercase .Heading}}</h1>
    <p>{{.Content}}</p>
</body>
</html>

Exercicis Pràctics

Exercici 1: Crear una Plantilla amb Llista

Crea una plantilla que mostri una llista d'elements passats des del servidor.

template.html

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

main.go

package main

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

type PageData struct {
    Title   string
    Heading 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:   "Llista d'Elements",
        Heading: "Elements",
        Items:   []string{"Element 1", "Element 2", "Element 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)
}

Exercici 2: Plantilles Niuades amb Funcions

Crea una aplicació que utilitzi plantilles niuades i una funció personalitzada per formatar les dades.

base.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{{.Title}}</title>
</head>
<body>
    {{template "header" .}}
    {{template "content" .}}
    {{template "footer" .}}
</body>
</html>

header.html

{{define "header"}}
<header>
    <h1>{{.Heading}}</h1>
</header>
{{end}}

footer.html

{{define "footer"}}
<footer>
    <p>Peu de pàgina</p>
</footer>
{{end}}

content.html

{{define "content"}}
<main>
    <p>{{uppercase .Content}}</p>
</main>
{{end}}

main.go

package main

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

type PageData struct {
    Title   string
    Heading string
    Content string
}

func uppercase(s string) string {
    return strings.ToUpper(s)
}

func handler(w http.ResponseWriter, r *http.Request) {
    tmpl := template.New("base.html").Funcs(template.FuncMap{
        "uppercase": uppercase,
    })

    tmpl, err := tmpl.ParseFiles("base.html", "header.html", "footer.html", "content.html")
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }

    data := PageData{
        Title:   "Pàgina d'Exemple",
        Heading: "Benvingut a Go Templates",
        Content: "Aquesta és una pàgina generada dinàmicament amb plantilles.",
    }

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

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

Conclusió

En aquesta secció, hem après a treballar amb plantilles en Go, incloent la creació de plantilles bàsiques, el pas de dades, l'ús de plantilles niuades i la definició de funcions personalitzades. Les plantilles són una eina essencial per a la generació de contingut dinàmic en aplicacions web, i la seva correcta utilització pot millorar significativament l'organització i mantenibilitat del codi.

En el següent mòdul, explorarem com treballar amb bases de dades en Go, incloent la connexió a bases de dades, operacions CRUD, ús d'ORM i migracions de bases de dades.

© Copyright 2024. Tots els drets reservats