使用HTMX和Go入门

使用 HTMX 和 Go 构建 Web 应用程序包括使用 Go(通常称为 Golang)创建后台,并在前端集成 HTMX 以实现动态和交互功能。

什么是HTMX
HTMX 是一个 JavaScript 库,通过利用 HTML 属性实现动态行为,您只需使用最少的 JavaScript 代码即可创建 Web 应用程序。
HTMX 在设计时考虑了 REST 后端,HTMX 通过替换和渲染服务器响应中的各个组件而不是整个页面,提供了一种类似于 SPA 的敏捷感觉。

什么是以下是使用 HTMX 和 Go 构建简单网络应用程序的分步指南:

1. 设置您的开发环境:
确保您的计算机上安装了 Go。可以从官网下载: https: //golang.org/dl/

2. 创建Go项目:
为您的项目创建一个新目录并将其初始化为 Go 模块:

mkdir myhtmxapp
cd myhtmxapp
go mod init github.com/yourusername/myhtmxapp

3. 创建一个简单的 Go 服务器:
main.go在项目目录中创建一个名为的文件:

// main.go
package main

import (
    
"fmt"
    
"net/http"
)

func main() {
    http.HandleFunc(
"/", func(w http.ResponseWriter, r *http.Request) {
        fmt.Fprintf(w,
"Hello, HTMX!")
    })

    http.ListenAndServe(
":8080", nil)
}

4. 将 HTMX 集成到您的 HTML 中:
在项目目录中创建一个 HTML 文件,例如index.html:

<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset=
"UTF-8">
    <meta name=
"viewport" content="width=device-width, initial-scale=1.0">
    <title>HTMX Go App</title>
    <script src=
"https://unpkg.com/htmx.org@1.7.0/dist/htmx.min.js"></script>
</head>
<body>

<h1 id=
"greeting" hx-get="/api/greeting">Loading...</h1>

</body>
</html>

5. 在 Go 中创建 API 端点:
修改您的main.go文件以包含 API 端点:

// main.go
package main

import (
    
"fmt"
    
"net/http"
)

func main() {
    http.HandleFunc(
"/", func(w http.ResponseWriter, r *http.Request) {
        http.ServeFile(w, r,
"index.html")
    })

    http.HandleFunc(
"/api/greeting", func(w http.ResponseWriter, r *http.Request) {
        fmt.Fprintf(w,
"Hello, HTMX from Go!")
    })

    http.ListenAndServe(
":8080", nil)
}

6. 运行您的 Go 应用程序:
使用以下命令运行您的 Go 应用程序:
go run main.go

在 Web 浏览器中访问http://localhost:8080,您应该会看到 HTMX 支持的 Web 应用程序正在运行。

简单案例2
这个 UI 和后端仅用 150 行代码(包括 HTML)就实现了!可以在babyapiGitHub 存储库中找到。

1、首先创建一个简单的 TODO 资源

package main

import "github.com/calvinmclean/babyapi"

type TODO struct {
    babyapi.DefaultResource

    Title       string
    Description string
    Completed   bool
}

func main() {
    api := babyapi.NewAPI[*TODO](
       
"TODOs", "/todos",
        func() *TODO { return &TODO{} },
    )

    api.RunCLI()
}

2、增加HtmlX
为了在此基础上添加 HTMX UI,我们需要做的就是:

(1)为TODO资源实现babyapi.HTMLer接口

(2)使用api.SetGetAllResponseWrapper新babyapi.HTMLer类型来呈现响应的/todosHTML

(3)为 HTMX 前端编写具有以下功能的模板:

  • 列出表中的所有 TODO
  • 用于将项目标记为已完成和删除的按钮
  • 服务器发送的事件自动附加新的 TODO
  • 创建 TODO 的表单

(4)使用 HTML 而不是 JSON 进行响应:

type HTMLer interface {
    HTML(*http.Request) string
}

HTML(*http.Request)方法可以如下实现:

const todoRowTemplate = `...`

func (t *TODO) HTML(*http.Request) string {
    tmpl := template.Must(
        template.New("todoRow").Parse(todoRowTemplate),
    )
    return babyapi.MustRenderHTML(tmpl, t)
}

该方法简单地从字符串渲染模板,并使用 babyapi.MustRenderHTML 与 TODO 数据一起执行。

(5)html模板:

<tr hx-target="this" hx-swap="outerHTML">
    <td>{{ .Title }}</td>
    <td>{{ .Description }}</td>
    <td>
        {{- $disabled :=
"" }}
        {{- if .Completed }}
            {{- $disabled =
"disabled" }}
        {{- end -}}

        <button
            hx-put=
"/todos/{{ .ID }}"
            hx-headers='{
"Accept": "text/html"}'
            hx-include=
"this"
            {{ $disabled }}>

            <!-- Include entire TODO item for idempotent PUT -->
            <input type=
"hidden" name="Completed" value="true">
            <input type=
"hidden" name="Title" value="{{ .Title }}">
            <input type=
"hidden" name="Description" value="{{ .Description }}">
            <input type=
"hidden" name="ID" value="{{ .ID }}">
            Complete
        </button>

        <button hx-delete=
"/todos/{{ .ID }}" hx-swap="swap:1s">
            Delete
        </button>
    </td>
</tr>

此模板会创建一个 HTML 表格行 (<tr>) 来显示 TODO 的标题和描述。该行还包含将项目标记为完成或删除的按钮。

除了常规的 HTML 之外,我们还可使用 HTMX 属性来控制与后台的交互。