gpt4 book ai didi

go - 通过堆栈管理和提供 html/模板数据绑定(bind)

转载 作者:数据小太阳 更新时间:2023-10-29 03:29:40 25 4
gpt4 key购买 nike

有没有人在使用 Go 的 html/template 时实现了管理 View 绑定(bind)的解决方案?具体来说,我希望找到能让我做类似事情的东西:

  • 在安装过程中设置全局 Site.Title
  • 提供请求范围的变量,如 CurrentURL
  • 然后,在 Render 步骤中,只需提供特定于 http.Handler 的变量,然后将其组合并提供给模板。

现有应用程序的示例如下所示(我使用 unrolled/render 进行布局继承,但这是可替换的):

package main

import (
"log"
"net"
"net/http"
"os"
"strings"

"github.com/go-chi/chi"
"github.com/go-chi/chi/middleware"
"github.com/unrolled/render"
)

type HelloBinding struct {
Name string
}

func helloHandler(render *render.Render) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
_ = render.HTML(w, http.StatusOK, "hello", &HelloBinding{
Name: "World!",
})
}
}

func main() {
port, ok := os.LookupEnv("PORT")
if !ok {
port = "8080"
}

render := render.New(render.Options{
Directory: "templates",
Layout: "layout",
Extensions: []string{".html"},
IsDevelopment: true,
})

r := chi.NewMux()

r.Use(middleware.Logger)
r.Use(middleware.Recoverer)

r.Get("/", helloHandler(render))

httpServer := &http.Server{
Addr: net.JoinHostPort("", port),
Handler: r,
}

log.Printf("http server listening at %s\n", httpServer.Addr)
if err := httpServer.ListenAndServe(); err != nil {
log.Panic(err)
}
}

<html>
<head>
<title></title>
</head>
<body>

{{ yield }}

</body>
</html>

共享 View

Hello, {{ .Name }}

在理想的解决方案中,这样的事情是可能的:

Warning: Pseudo code

package main

import (
"log"
"net"
"net/http"
"os"
"strings"

"github.com/go-chi/chi"
"github.com/go-chi/chi/middleware"
"github.com/unrolled/render"
)

type GlobalBinding struct {
Title string
}

type RequestBinding struct {
CurrentURL string
}

type HelloBinding struct {
Name string
}

func helloHandler(render *render.Render) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
_ = render.HTML(w, http.StatusOK, "hello", &HelloBinding{
Name: "World!",
})
}
}

func main() {
port, ok := os.LookupEnv("PORT")
if !ok {
port = "8080"
}

render := render.New(render.Options{
Directory: "templates",
Layout: "layout",
Extensions: []string{".html"},
IsDevelopment: true,
})

// Binds data to be used
render.Bind(GlobalBindings{
Title: "My Site",
})

r := chi.NewMux()

r.Use(middleware.Logger)
r.Use(middleware.Recoverer)

// Binds data for the request context only
r.Use(func(next http.Handler) http.Handler {
return func(w http.ResponseWriter, r *http.Request) {
render.BindContext(r.Context, RequestBinding{
CurrentURL: r.URL.String(),
})
next(w, r)
}
})

r.Get("/", helloHandler(render))

httpServer := &http.Server{
Addr: net.JoinHostPort("", port),
Handler: r,
}

log.Printf("http server listening at %s\n", httpServer.Addr)
if err := httpServer.ListenAndServe(); err != nil {
log.Panic(err)
}
}

允许我将布局更改为:

<html>
<head>
<title>{{ .Global.Title }}</title>
</head>
<body>

{{ .CurrentURL }}

{{ yield }}

</body>
</html>

并且各个处理程序在不考虑太多的情况下合并和绑定(bind)。


希望你们有一些解决办法!我为此苦苦挣扎了一段时间。

最佳答案

不在 html/template 但考虑使用 quicktemplates

https://github.com/valyala/quicktemplate

它是围绕常规代码设计的,因此您的渲染器只是可以采用任意参数(和接口(interface))的函数。您可以导入包并调用常规函数并访问全局变量。

与内置的模板引擎相比,它使用起来更舒适,而且您还可以进行静态类型检查。唯一的缺点是您需要在编辑后重建/重新启动以反射(reflect)更改。

关于go - 通过堆栈管理和提供 html/模板数据绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54134591/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com