英文:
How to assign a variable of a go template inside a go template?
问题
我刚开始使用golang和模板系统来重新开发我的Web服务器。现在我只想为每个网站编写常量变量,但我实际上并不知道我在搜索什么。希望有人可以帮助我。
我有一个用于每个HTML文件的"base"的gohtml文件:
{{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/bootstrap@5.3.0-alpha3/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/bootstrap@5.3.0-alpha3/dist/js/bootstrap.bundle.min.js"
integrity="sha384-ENjdO4Dr2bkBIFxQpeoTz1HIcje39Wm4jDKdf19U8gI4ddQ3GYNS7NTKfAdVQSZe"
crossorigin="anonymous"></script>
</body>
</html>
{{end}}
然后我想以相同的方式更改标题,以及以后的元数据描述等等。
{{template "topdoc" .}}
{{template "navbar"}}
HOME
{{template "botdoc"}}
Navbar在另一个文件中定义。
现在我想在这个文件中传递变量,例如:
{{template "topdoc" .title="Home" .otherParam="Checking..."}}
{{template "navbar"}}
HOME
{{template "botdoc"}}
也许有人可以帮我解决这个非常琐碎的问题。
当我使用这种方法时:
{{define "title"}}Home{{end}}
{{template "topdoc"}}
{{template "navbar"}}
HOME
{{template "botdoc"}}
并首先加载基础文件时,它显示一个空白网站。
我像这样加载模板文件:
func main() {
r := gin.Default()
tmpl = make(map[string]*template.Template)
// 加载模板文件
templateFiles := []string{}
fmt.Println("加载模板文件...")
// 遍历"templates"文件夹及其所有子目录
nerr := filepath.Walk("main/web/assets/templates", func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
// 检查文件是否为HTML模板
if !info.IsDir() && strings.HasSuffix(info.Name(), ".gohtml") {
// 将反斜杠替换为正斜杠(用于兼容Windows)
templateName := strings.Replace(path, "\\", "/", -1)
// 解析文件并将其添加到"tmpl"映射中
templateFiles = append(templateFiles, path)
//console log
fmt.Print(templateName + " ")
}
return nil
})
if nerr != nil {
panic(nerr)
}
fmt.Println("\n\n加载网站...")
// 遍历"public"文件夹及其所有子目录
err := filepath.Walk("main/web/public", func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
// 检查文件是否为HTML模板
if !info.IsDir() && strings.HasSuffix(info.Name(), ".gohtml") {
// 获取目录路径(相对于"public"文件夹)
relPath, err := filepath.Rel("main/web/public", filepath.Dir(path))
if err != nil {
return err
}
// 将反斜杠替换为正斜杠(用于兼容Windows)
templateName := strings.Replace(relPath, "\\", "/", -1)
// 解析文件并将其添加到"tmpl"映射中
parsing := []string{}
parsing = append(parsing, templateFiles...)
parsing = append(parsing, path)
fmt.Println(parsing)
tmpl[templateName] = template.Must(template.ParseFiles(parsing...))
// 如果路径为空,则默认为"index"
if templateName == "." {
templateName = ""
}
// 使用适当的路由注册模板
r.GET("/"+templateName, handler)
}
return nil
})
if err != nil {
panic(err)
}
r.Run()
}
英文:
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/bootstrap@5.3.0-alpha3/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/bootstrap@5.3.0-alpha3/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("\n\nLoading 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()
}
答案1
得分: 1
这通常是通过模板组合来实现的。在你的“topdoc”模板中,只需调用其他模板:
{{define "topdoc"}}
...
{{template "title"}}
...
{{end}}
并将“title”模板定义为
{{define "title"}}默认标题{{end}}
然后,你可以在单独的文件中重新定义“title”模板来覆盖它:
{{define "title"}}新标题{{end}}
{{define "someTemplate"}}
{{template "topdoc"}}
...
{{end}}
你需要组合这些不同的模板文件,以便首先加载“topdoc”(它定义了默认的“title”),然后加载重新定义“title”的模板。
英文:
This is usually achieved using template composition. In your "topdoc" template, simply call other templates:
{{define "topdoc"}}
...
{{template "title"}}
...
{{end}}
And define the "title" template as
{{define "title"}}Default title{{end}}
Then, you can override the "title" template with a redefinition of it in a separate file:
{{define "title"}}New title{{end}}
{{define "someTemplate}}
{{template "topdoc"}}
...
{{end}}
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".
答案2
得分: 0
为了在Go模板中使用“常量”,最简单的方法是使用模板来定义它们。因此,首先加载基本模板文件非常重要,以便可以进行覆盖。在这样做时,定义一个“content”模板非常重要,以便可以显示实际的网站内容。
因此,base.golang文件的内容如下:
{{define "topdoc"}}
<!DOCTYPE html>
<html lang="eng" 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>{{template "title"}}</title>
<!-- Bootstrap -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-KK94CHFLLe+nY2dmCWGMq91rCGa5gtU4mk92HdvYe+M/SXH301p5ILy+dN9+nJOZ"
crossorigin="anonymous">
</head>
<body>
{{end}}
{{define "title"}} Default Title {{end}}
{{template "content"}}
{{define "botdoc"}}
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/js/bootstrap.bundle.min.js"
integrity="sha384-ENjdO4Dr2bkBIFxQpeoTz1HIcje39Wm4jDKdf19U8gI4ddQ3GYNS7NTKfAdVQSZe"
crossorigin="anonymous"></script>
</body>
</html>
{{end}}
网站文件的内容如下:
{{define "title"}}Home{{end}}
{{define "content"}}
{{template "topdoc"}}
{{template "navbar"}}
Home
{{template "botdoc"}}
{{end}}
英文:
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
{{define "topdoc"}}
<!DOCTYPE html>
<html lang="eng" 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>{{template "title"}}</title>
<!-- Bootstrap -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-KK94CHFLLe+nY2dmCWGMq91rCGa5gtU4mk92HdvYe+M/SXH301p5ILy+dN9+nJOZ"
crossorigin="anonymous">
</head>
<body>
{{end}}
{{define "title"}} Default Title {{end}}
{{template "content"}}
{{define "botdoc"}}
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/js/bootstrap.bundle.min.js"
integrity="sha384-ENjdO4Dr2bkBIFxQpeoTz1HIcje39Wm4jDKdf19U8gI4ddQ3GYNS7NTKfAdVQSZe"
crossorigin="anonymous"></script>
</body>
</html>
{{end}}
The website file would thant look like this
{{define "title"}}Home{{end}}
{{define "content"}}
{{template "topdoc"}}
{{template "navbar"}}
Home
{{template "botdoc"}}
{{end}}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论