Golang模板中如何操作DOM添加/删除属性
Golang模板中如何操作DOM添加/删除属性 在我的代码中,我想根据用户认证级别禁用某些输入字段。我可以用 JavaScript 实现,但这不是推荐的做法,我希望从服务器端来实现。
以下是我的 Go 代码:
package main
import (
"context"
"html/template"
"net/http"
"strings"
"time"
)
type User struct {
Flags string
Title string
}
type UsersPageData struct {
PageTitle string
Users []User
}
func requestTime(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
ctx = context.WithValue(ctx, "requestTime", time.Now().Format(time.RFC3339))
r = r.WithContext(ctx)
next.ServeHTTP(w, r)
})
}
func helloHandler(name string) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
var title string
if requestTime := r.Context().Value("requestTime"); requestTime != nil {
if str, ok := requestTime.(string); ok {
title = "\ngenerated at: " + str
}
}
master := strings.Join([]string{"admin", "user", "superuser", "read"}, " ")
admin := strings.Join([]string{"admin"}, " ")
user := strings.Join([]string{"user"}, " ")
tmpl := template.Must(template.ParseFiles("index.html"))
data := UsersPageData{
PageTitle: "Users list: " + title,
Users: []User{
{Flags: master, Title: "Everything"},
{Flags: admin, Title: "Administrator"},
{Flags: user, Title: "Normal user"},
},
}
tmpl.Execute(w, data)
})
}
func main() {
http.Handle("/john", requestTime(helloHandler("John")))
http.ListenAndServe(":8080", nil)
}
这是我的模板,包含 JS 代码:
<style>
.admin {
color: green;
}
.user {
color: red;
--btn-disable: 0;
}
[data-authorized="no"] {
/* Attribute has this exact value */
cursor: not-allowed;
pointer-events: none;
/*Button disabled - CSS color class*/
color: #c0c0c0;
background-color: rgb(229, 229, 229) !important;
}
</style>
<h1>{{.PageTitle}}</h1>
<ul>
{{range .Users}}
<input type="text" data-permissions={{.Flags}} data-authorized="no">{{.Title}}</s>
{{end}}
</ul>
<script>
var flags = ["admin", "super user"]
var elements = document.querySelectorAll("input");
elements.forEach((element, index, array) => {
if(element.hasAttribute("data-permissions")){
console.log(element.dataset.permissions)
var perm = element.dataset.permissions.split(" ");
var found = false;
for (var i = 0; i < perm.length; i++) {
if (flags.indexOf(perm[i]) > -1) {
element.dataset.authorized = "yes"
element.removeAttribute("data-permissions")
break;
}
}
}
});
</script>
以下是输出结果:

有什么想法吗?
更多关于Golang模板中如何操作DOM添加/删除属性的实战教程也可以访问 https://www.itying.com/category-94-b0.html
如果你有已授权的用户,只需从应用程序发送不同的HTML代码即可。
更多关于Golang模板中如何操作DOM添加/删除属性的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
只需渲染另一个模板
关键就在这里,我希望能使用同一个模板。
没明白,你能用一些代码详细说明一下吗,谢谢
我想在服务器端实现它。
一种方法是在 Go 模板中隐藏/显示元素
{{if and .User .User.Admin}}
You are an admin user!
{{else}}
Access denied!
{{end}}
Sibert:
一种方法是在 Go 模板中隐藏/显示元素
谢谢,但这意味着要使用不同的模板。实际上,我有两种认证情况:
- 每种权限对应不同的视图,这可以通过您提供的代码在
GO中控制。 - 单一视图,其中某些字段对某些权限级别禁用,而对其他权限级别开放。这正是我试图实现的功能。
- 对于某些权限级别,单一视图中的某些字段被禁用,而对其他权限级别则开放,这正是我试图实现的功能。
你可以使用一个带有内置条件的模板。
<form>
{{if .SuperAdmin}}
<input type="text" name="subject" placeholder="For Superadmin" required>
{{else if .Admin}}
<input type="text" name="subject" placeholder="For Admin" required>
{{else}}
<input type="text" name="subject" placeholder="For Normal Users" required>
{{end}}
//outside if statement:
<input type="text" name="subject" placeholder="For all users" required>
</form>
引用 Sibert:
您可以使用一个带有内置条件的模板。
如果每个用户只有一个标志,这个方法对我有效,例如:
type Flag int
const (
Admin Flag = iota + 1 // iota = 0
Editer
Superuser
Viewer
)
type User struct {
Flags Flag
Title string
}
模板如下:
<h1>{{.PageTitle}}</h1>
<ul>
{{range .Users}}
<span>{{.Title}}</span>
{{if eq .Flags 1}}
<input type="text" name="subject" placeholder= {{.Flags}} required>
{{else if eq .Flags 4}}
<input type="text" name="subject" placeholder= {{.Flags}} disabled>
{{end}}
{{end}}
</ul>
但是,如果我的标志是数组形式,该怎么办?其中:
- 每个用户可能拥有多个标志
- 如果同一个用户的一个标志对元素有权限,而另一个标志不允许此权限,那么我该如何为更高优先级的标志开放权限?
一个例子是:
type User struct {
Flags []Flag
Title string
}
master := User{
Flags: []string{Admin, Viewer},
Title: "Abnormal user",
}
在上面的例子中,用户有两个标志:Admin 授予了对元素的访问权限,而 Viewer 则阻止了对同一元素的访问权限,我该如何处理这种情况?
更新 经过搜索,我尝试了下面的方法,但问题仍未解决。如果同一个用户有多个标志,并且它们都没有权限,那么同一个字段会重复多次;
master := []flag{Admin, Editer, Superuser, Viewer}
admin := []flag{Admin, Superuser}
user := []flag{Viewer, Dummy}
// template
<h1>{{.PageTitle}}</h1>
<ul>
{{range .Users}}
<span>{{.Title}}</span>
{{ $done := false }}
{{range $i, $v := .Flags}}
{{ if $done }}
{{ else }}
{{if or (eq $v 1) (eq $v 3)}}
<input type="text" name="subject" placeholder= {{$v}} required>
{{ $done = true }}
{{else}}
<input type="text" name="subject" placeholder= {{$v}} disabled>
{{end}}
{{end}}
{{end}}
{{end}}
</ul>

谢谢
package main
import (
"html/template"
"net/http"
)
type User struct {
Flags []flag //string
Title string
}
type UsersPageData struct {
PageTitle string
Users []User
}
type flag int
const (
Admin flag = iota + 1 // iota = 0
Editer
Superuser
Viewer
Dummy
)
func subtract(arg1, arg2 int) int {
return arg1 - arg2
}
func helloHandler(name string) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// 在模板中映射自定义的 `subtract` 函数
funcMap := map[string]interface{}{"subtract": subtract}
master := []flag{Admin, Editer, Superuser, Viewer}
admin := []flag{Admin, Superuser, Viewer}
user := []flag{Viewer, Dummy}
tmpl := template.New("").Funcs(template.FuncMap(funcMap))
template.Must(tmpl.ParseFiles("index.html"))
data := UsersPageData{
PageTitle: "Users list: ",
Users: []User{
{Flags: master, Title: "Everything"},
{Flags: admin, Title: "Administrator"},
{Flags: user, Title: "Normal user"},
},
}
tmpl.ExecuteTemplate(w, "index.html", data)
})
}
func main() {
fs := http.StripPrefix("/www/", http.FileServer(http.Dir("./www")))
http.Handle("/www/", fs)
http.Handle("/", helloHandler("John"))
http.ListenAndServe(":8080", nil)
}
index.html 文件内容如下:
<html>
{{/* This is a comment
{{$flags := []flag{Admin, Editer, Superuser, Viewer};}}
Admin Flag = iota + 1 // iota = 0
Editer
Superuser
Viewer
}}
*/}}
<ul>
{{range .Users}}
<span>{{.Title}}</span>
{{ $done := false}} {{$length := len .Flags}}
{{range $i, $v := .Flags}}
{{ if $done }}
{{ else }}
{{if or (eq $v 1) (eq $v 3)}}
<input type="text" name="subject" placeholder= {{$v}} required>
{{ $done = true }}
{{else}}
{{ if eq $i (subtract $length 1)}}
<input type="text" name="subject" placeholder= {{$v}} disabled>
{{ end }}
{{end}}
{{end}}
{{end}}
{{end}}
</ul>
</html>

在Go模板中直接操作DOM添加/删除属性是可行的,可以通过模板函数和条件逻辑实现。以下是修改后的示例:
package main
import (
"context"
"html/template"
"net/http"
"strings"
"time"
)
type User struct {
Flags string
Title string
}
type UsersPageData struct {
PageTitle string
Users []User
UserFlags []string // 当前用户权限
}
// 模板函数检查权限
func hasPermission(userFlags []string, requiredFlags string) bool {
required := strings.Fields(requiredFlags)
for _, req := range required {
found := false
for _, userFlag := range userFlags {
if userFlag == req {
found = true
break
}
}
if !found {
return false
}
}
return true
}
func requestTime(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
ctx = context.WithValue(ctx, "requestTime", time.Now().Format(time.RFC3339))
r = r.WithContext(ctx)
next.ServeHTTP(w, r)
})
}
func helloHandler(name string) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
var title string
if requestTime := r.Context().Value("requestTime"); requestTime != nil {
if str, ok := requestTime.(string); ok {
title = "\ngenerated at: " + str
}
}
// 模拟当前用户权限
currentUserFlags := []string{"admin", "superuser"}
// 创建模板函数映射
funcMap := template.FuncMap{
"hasPermission": func(requiredFlags string) bool {
return hasPermission(currentUserFlags, requiredFlags)
},
}
tmpl := template.Must(template.New("index.html").Funcs(funcMap).ParseFiles("index.html"))
data := UsersPageData{
PageTitle: "Users list: " + title,
UserFlags: currentUserFlags,
Users: []User{
{Flags: "admin user superuser read", Title: "Everything"},
{Flags: "admin", Title: "Administrator"},
{Flags: "user", Title: "Normal user"},
},
}
tmpl.Execute(w, data)
})
}
func main() {
http.Handle("/john", requestTime(helloHandler("John")))
http.ListenAndServe(":8080", nil)
}
模板文件修改为:
<style>
.admin {
color: green;
}
.user {
color: red;
}
.disabled {
cursor: not-allowed;
pointer-events: none;
color: #c0c0c0;
background-color: rgb(229, 229, 229) !important;
}
</style>
<h1>{{.PageTitle}}</h1>
<ul>
{{range .Users}}
{{if hasPermission .Flags}}
<input type="text" class="admin" value="{{.Title}}">
{{else}}
<input type="text" class="disabled user" value="{{.Title}}" disabled>
{{end}}
{{end}}
</ul>
<!-- 或者使用属性条件设置 -->
<h2>方法二:动态设置属性</h2>
<ul>
{{range .Users}}
<input type="text"
value="{{.Title}}"
{{if not (hasPermission .Flags)}}disabled{{end}}
{{if not (hasPermission .Flags)}}class="disabled"{{else}}class="enabled"{{end}}>
{{end}}
</ul>
另一种更灵活的方式是使用自定义模板函数生成属性:
// 添加模板函数生成属性字符串
funcMap := template.FuncMap{
"hasPermission": func(requiredFlags string) bool {
return hasPermission(currentUserFlags, requiredFlags)
},
"inputAttrs": func(flags string) template.HTMLAttr {
if hasPermission(currentUserFlags, flags) {
return `class="enabled" type="text"`
}
return `class="disabled" type="text" disabled`
},
}
模板中使用:
<h2>方法三:使用属性生成函数</h2>
<ul>
{{range .Users}}
<input {{inputAttrs .Flags}} value="{{.Title}}">
{{end}}
</ul>
对于data属性的操作,可以在模板中直接生成:
<h2>方法四:控制data属性</h2>
<ul>
{{range .Users}}
<input type="text"
value="{{.Title}}"
{{if hasPermission .Flags}}
data-authorized="yes"
{{else}}
data-authorized="no"
{{end}}
data-permissions="{{.Flags}}">
{{end}}
</ul>
这样完全在服务器端处理权限逻辑,无需客户端JavaScript。模板会根据用户权限动态生成正确的HTML属性和类名。


