I servizi Goa possono renderizzare contenuti HTML dinamici utilizzando il pacchetto
standard html/template
di Go. Questa guida ti mostra come integrare la renderizzazione
dei template nel tuo servizio Goa.
Prima, definisci gli endpoint del servizio che renderizzeranno i template HTML:
package design
import . "goa.design/goa/v3/dsl"
var _ = Service("front", func() {
Description("Servizio front-end con renderizzazione dei template")
Method("home", func() {
Description("Renderizza la home page")
Payload(func() {
Field(1, "name", String, "Nome da visualizzare nella homepage")
Required("name")
})
Result(Bytes)
HTTP(func() {
GET("/")
Response(StatusOK, func() {
ContentType("text/html")
})
})
})
})
Crea un servizio che gestisce la renderizzazione dei template:
package front
import (
"embed"
"html/template"
"io"
"path/filepath"
)
//go:embed templates/*
var templateFS embed.FS
type Service struct {
templates *template.Template
}
func NewService() (*Service, error) {
// Carica e analizza tutti i template dalla directory templates
templates, err := template.ParseFS(templateFS, "templates/*.html")
if err != nil {
return nil, err
}
return &Service{
templates: templates,
}, nil
}
Crea i template HTML nella directory templates
:
<!-- templates/home.html -->
<!DOCTYPE html>
<html>
<head>
<title>Benvenuto</title>
</head>
<body>
<h1>Ciao, {{.Name}}!</h1>
</body>
</html>
Implementa il metodo home
per renderizzare il template:
func (s *Service) Home(ctx context.Context, p *front.HomePayload) ([]byte, error) {
// Prepara i dati per il template
data := struct {
Name string
}{
Name: p.Name,
}
// Crea un buffer per la renderizzazione
var buf bytes.Buffer
// Esegui il template
if err := s.templates.ExecuteTemplate(&buf, "home.html", data); err != nil {
return nil, err
}
return buf.Bytes(), nil
}
È importante gestire correttamente gli errori durante la renderizzazione dei template:
Errori di Analisi: Gli errori durante template.ParseFS
indicano problemi
con la sintassi del template.
Errori di Esecuzione: Gli errori durante ExecuteTemplate
possono verificarsi
se i dati non corrispondono a ciò che il template si aspetta.
func (s *Service) Home(ctx context.Context, p *front.HomePayload) ([]byte, error) {
data := struct {
Name string
}{
Name: p.Name,
}
var buf bytes.Buffer
if err := s.templates.ExecuteTemplate(&buf, "home.html", data); err != nil {
// Converti l'errore del template in un errore Goa
return nil, front.MakeInternalError(err)
}
return buf.Bytes(), nil
}
Go supporta la composizione dei template, permettendoti di creare layout riutilizzabili:
<!-- templates/layout.html -->
<!DOCTYPE html>
<html>
<head>
<title>{{.Title}}</title>
</head>
<body>
<header>
<nav>{{template "nav" .}}</nav>
</header>
<main>
{{template "content" .}}
</main>
<footer>
{{template "footer" .}}
</footer>
</body>
</html>
<!-- templates/nav.html -->
{{define "nav"}}
<ul>
<li><a href="/">Home</a></li>
<li><a href="/about">Chi Siamo</a></li>
</ul>
{{end}}
<!-- templates/footer.html -->
{{define "footer"}}
<p>© 2024 Il Mio Servizio Goa</p>
{{end}}
func (s *Service) Home(ctx context.Context, p *front.HomePayload) ([]byte, error) {
data := struct {
Title string
Name string
}{
Title: "Home Page",
Name: p.Name,
}
var buf bytes.Buffer
if err := s.templates.ExecuteTemplate(&buf, "layout.html", data); err != nil {
return nil, front.MakeInternalError(err)
}
return buf.Bytes(), nil
}
L’integrazione dei template HTML in un servizio Goa ti permette di:
embed
Questo approccio fornisce un modo robusto per servire contenuti web dinamici mantenendo la type safety e le funzionalità di Goa.