Warning: Undefined array key "typ" in /srv/vhost/diaridigital.net/home/html/sourcecode/main/articles.php on line 18
Proyectos web dinámicos
Tiempo de lectura: 1 minutos
Un proyecto web con una plantilla HTML a la que pasamos variables para no tener que repetir páginas estáticas.
Servir los recursos
Utilizaremos el paquete html/template que se encargará de gestionar las variables dentro de la plantilla HTML. Primero establecemos el directorio de recursos web, que lo ubicamos en static para disponer de un gestor que los sirva:
fs := http.FileServer(http.Dir("./static"))
http.Handle("/static/", http.StripPrefix("/static/", fs)) Como nuestro directorio estático está configurado como la raíz del sistema de archivos, debemos quitar el prefijo /static/ de la ruta de solicitud antes de buscar el archivo indicado en el sistema de archivos. Para ello, utilizamos la función http.StripPrefix().
Las plantillas
Utilizaremos dos ficheros HTML, uno funcionará como plantilla y el segundo como página principal.
La plantilla (layout) será:
{{define "layout"}}
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>{{template "title"}}</title>
<link rel="stylesheet" type="text/css" href="./web/static/css/main.css" />
</head>
<body>
{{template "body"}}
<footer>Página en Go</footer>
</body>
</html>
{{end}} Los bloques quedan delimitados por los marcadores {{define}} ... {{end}}. Y podemos incluir unos en otros con los marcadores {{template}}.
La página principal será así:
{{define "title"}}A templated page{{end}}
{{define "body"}}
<h1>Hello from a templated page</h1>
{{end}} Programa principal
El programa en Go nos queda de la siguiente manera:
package main
import (
"log"
"net/http"
// nuevos paquetes:
"html/template" // plantilla html
"path/filepath" // limpieza de la ruta
)
func main() {
fs := http.FileServer(http.Dir("./web/static"))
http.Handle("/web/static/", http.StripPrefix("/web/static/", fs))
// Ver detalles (1)
http.HandleFunc("/", serveTemplate)
log.Print("Escuchano por :8081...")
err := http.ListenAndServe(":8081", nil)
if err != nil {
log.Fatal(err)
}
}
func serveTemplate(w http.ResponseWriter, r *http.Request) {
lp := filepath.Join("web", "static", "templates", "layout.html")
fp := filepath.Join("web", "static", "templates", filepath.Clean(r.URL.Path))
// Ver deallales (2)
page, err := template.ParseFiles(lp, fp)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
page.ExecuteTemplate(w, "layout", nil)
} Ref (1)
Todas las solicitudes que no son recogidas por el servidor en static se procesan con la función serveTemplate(), donde creamos rutas al fichero layout y al directorio templates, utilizando el método .Join para no depender del sistema operativo. Además, el método .Clean lo utilizamos para evitar caracteres especiales y otros errores en la URL que proporcione el usuario.
Ref (2)
Y, finalmente, template.ParseFiles() para unirlo todo y tener una plantilla dinámica para las páginas web.
Ejecutamos:
http://localhost:8081/main.html - html/template
https://pkg.go.dev
