I’m just starting to use golang and the template system to redevelop my webserver. Now I just want to write constant variables for each website but I don’t even really know what I’m searching. I hope some one can help.
I have this gohtml file for the "base" of every html File
{{define "topdoc"}}
<!DOCTYPE html>
<html lang="en" data-bs-theme="dark">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{{.title}}</title>
<!-- Bootstrap -->
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-KK94CHFLLe+nY2dmCWGMq91rCGa5gtU4mk92HdvYe+M/SXH301p5ILy+dN9+nJOZ"
crossorigin="anonymous">
</head>
<body>
{{end}}
{{define "botdoc"}}
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"
integrity="sha384-ENjdO4Dr2bkBIFxQpeoTz1HIcje39Wm4jDKdf19U8gI4ddQ3GYNS7NTKfAdVQSZe"
crossorigin="anonymous"></script>
</body>
</html>
{{end}}
Than I want to change the title and later for example meta data description and stuff like that the same way.
{{template "topdoc" .}}
{{template "navbar"}}
HOME
{{template "botdoc"}}
Navbar is defined in another file.
Now I want to give the variable in this file like
{{template "topdoc" .title="Home" .otherParam="Checking..."}}
{{template "navbar"}}
HOME
{{template "botdoc"}}
Maybe someon can help me with this very trivial issue.
When I use this method
{{define "title"}}Home{{end}}
{{template "topdoc"}}
{{template "navbar"}}
HOME
{{template "botdoc"}}
And load the base file first, it shows a blank website.
I load the template files like this:
func main() {
r := gin.Default()
tmpl = make(map[string]*template.Template)
// Load templates files
templateFiles := []string{}
fmt.Println("Loading templates...")
// Walk through the "templates" folder and all its subdirectories
nerr := filepath.Walk("main/web/assets/templates", func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
// Check if the file is an HTML templates
if !info.IsDir() && strings.HasSuffix(info.Name(), ".gohtml") {
// Replace backslashes with forward slashes (for Windows compatibility)
templateName := strings.Replace(path, "\", "/", -1)
// Parse the file and add it to the "tmpl" map
templateFiles = append(templateFiles, path)
//console log
fmt.Print(templateName + " ")
}
return nil
})
if nerr != nil {
panic(nerr)
}
fmt.Println("nnLoading sites...")
// Walk through the "public" folder and all its subdirectories
err := filepath.Walk("main/web/public", func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
// Check if the file is an HTML templates
if !info.IsDir() && strings.HasSuffix(info.Name(), ".gohtml") {
// Get the directory path (relative to the "public" folder)
relPath, err := filepath.Rel("main/web/public", filepath.Dir(path))
if err != nil {
return err
}
// Replace backslashes with forward slashes (for Windows compatibility)
templateName := strings.Replace(relPath, "\", "/", -1)
// Parse the file and add it to the "tmpl" map
parsing := []string{}
parsing = append(parsing, templateFiles...)
parsing = append(parsing, path)
fmt.Println(parsing)
tmpl[templateName] = template.Must(template.ParseFiles(parsing...))
// If the path is empty, default to "index"
if templateName == "." {
templateName = ""
}
// Register the templates with the appropriate route
r.GET("/"+templateName, handler)
}
return nil
})
if err != nil {
panic(err)
}
r.Run()
}
2
Answers
In order to use "constants" in go templates, its the easiest way to just use a template to define them. Therefor its important to load the base template file at first, so it can be overriten. When doing that, its important to define a "content" template, so that the actual website can be displayed.
So the base.golang would look like this
The website file would thant look like this
This is usually achieved using template composition. In your "topdoc" template, simply call other templates:
And define the "title" template as
Then, you can override the "title" template with a redefinition of it in a separate file:
You have to compose these different template files so that you load the "topdoc" first (which defines the default "title"), and then load the template redefining the "title".