如何在Golang中为文件夹内所有HTML文件引入统一的header.html头部文件?
在Golang中复用HTML头部模板并在浏览器展示页面的解决方案
问题背景
之前用PHP开发时,我只要通过<?php include 'header.php'; ?>就能给文件夹内的HTML文件统一引入头部,改个扩展名就能复用。但现在转用Golang开发,不知道怎么给所有HTML文件引入header.html——目前只有2个文件还能手动写引入代码,要是有50个文件的话手动操作太耗时了。另外我现在的代码执行后内容会输出在终端,而我想要在浏览器里展示页面。
我当前的代码如下:
HTML文件(buttons.html)
<body> <header>{{template "bootstrap_header.html"}}</header> <h3>Login Here</h3> <input type="text" id="email" name="email" value="" placeholder="enter your email here"> <input type="text" id="password" name="password" value="" placeholder="enter your password here"> <button id="button_first">Click it for Login</button> <script> $(document).ready(function(){ $('button').on('click', function(e){ var email = $('#email').val() var password = $('#password').val() $.ajax({ url:"/api/v2/login", type:"POST", data: {'email':email, "password":password}, success: function(results) { console.log(results) if(results.response.message === "Success"){ console.log("hello") alert(results.response.message); function setCookie(cname, cvalue, exdays) { document.cookie = cname + "=" + cvalue + ";path=/"; } setCookie("X-Test-Header", results.response.total_record) document.location.href = "/api/v1/customer?Number="+results.response.data[0]._id; } if(results.response.message === "Failure"){ console.log("hello") alert(results.response.data); } } }); }); }); </script> </body>
这个页面会通过document.location.href = "/api/v1/customer?Number="+results.response.data[0]._id;进行跳转。
Go代码
t, err := template.ParseFiles("buttons.html", "bootstrap_header.html") if err != nil { panic(err) } err = t.ExecuteTemplate(os.Stdout, "buttons.html", nil) if err != nil { panic(err) }
解决方案
一、用模板嵌套实现头部复用(告别手动引入)
Go的html/template支持模板继承和嵌套,我们可以搭建一个统一的基础模板结构,让所有页面自动复用头部:
- 改造头部模板(bootstrap_header.html)
给头部模板定义一个名称,方便后续引用:
{{define "bootstrap_header"}} <!-- 这里放你的头部内容,比如导航栏、全局样式等 --> <nav class="navbar navbar-expand-lg navbar-light bg-light"> <!-- 头部具体内容 --> </nav> {{end}}
- 创建基础布局模板(base.html)
这个模板作为所有页面的框架,统一包含头部、内容区域和全局资源:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>{{.Title}}</title> <!-- 全局CSS、JS引入,比如Bootstrap、jQuery --> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet"> <script src="https://code.jquery.com/jquery-3.6.4.min.js"></script> </head> <body> {{template "bootstrap_header"}} <!-- 自动引入头部模板 --> <div class="container mt-4"> {{template "content" .}} <!-- 内容区域,由具体页面填充 --> </div> </body> </html>
- 改造业务页面(buttons.html)
只需要定义content模板,填充页面的具体内容即可,不用再手动写头部引入:
{{define "content"}} <h3>Login Here</h3> <div class="mb-3"> <input type="email" class="form-control" id="email" name="email" placeholder="enter your email here"> </div> <div class="mb-3"> <input type="password" class="form-control" id="password" name="password" placeholder="enter your password here"> </div> <button id="button_first" class="btn btn-primary">Click it for Login</button> <script> // 原有的JS代码直接放在这里即可 $(document).ready(function(){ $('button').on('click', function(e){ var email = $('#email').val() var password = $('#password').val() $.ajax({ url:"/api/v2/login", type:"POST", data: {'email':email, "password":password}, success: function(results) { console.log(results) if(results.response.message === "Success"){ alert(results.response.message); function setCookie(cname, cvalue, exdays) { document.cookie = cname + "=" + cvalue + ";path=/"; } setCookie("X-Test-Header", results.response.total_record) document.location.href = "/api/v1/customer?Number="+results.response.data[0]._id; } if(results.response.message === "Failure"){ alert(results.response.data); } } }); }); }); </script> {{end}}
这样不管你有多少个页面,只要遵循这个结构定义content模板,就能自动复用头部,完全不用手动一个个写引入代码。
二、让页面在浏览器中展示(替代终端输出)
你当前的代码是把模板输出到终端(os.Stdout),要在浏览器展示,需要用Go的net/http包搭建HTTP服务器,把模板输出到HTTP响应里:
修改后的Go代码:
package main import ( "html/template" "net/http" ) // 提前解析所有模板,避免每次请求重复解析,提升性能 var tpl = template.Must(template.ParseFiles("base.html", "bootstrap_header.html", "buttons.html")) // 处理登录页面请求的Handler func loginPageHandler(w http.ResponseWriter, r *http.Request) { // 可以传递页面需要的数据,比如标题 pageData := map[string]interface{}{ "Title": "User Login", } // 执行基础模板,把内容输出到HTTP响应中 if err := tpl.ExecuteTemplate(w, "base.html", pageData); err != nil { // 如果模板执行出错,返回500错误 http.Error(w, err.Error(), http.StatusInternalServerError) } } func main() { // 注册路由:访问/login时展示登录页面 http.HandleFunc("/login", loginPageHandler) // 启动HTTP服务器,监听8080端口 println("Server is running at http://localhost:8080/login") if err := http.ListenAndServe(":8080", nil); err != nil { panic(err) } }
现在运行这个Go程序,打开浏览器访问http://localhost:8080/login,就能看到你的登录页面了。
三、批量处理大量模板的技巧
如果有50个页面文件,一个个写ParseFiles太麻烦,可以用ParseGlob匹配所有HTML文件:
var tpl = template.Must(template.ParseGlob("*.html"))
它会自动解析当前目录下所有.html文件。建议把模板文件放到单独的templates目录下,结构更清晰:
var tpl = template.Must(template.ParseGlob("templates/*.html"))
内容的提问来源于stack exchange,提问作者gourav
相关产品推荐
相关产品推荐

