在过去,人们通常使用 HTML、CSS 和 JavaScript 来构建网站,同时在后端使用 PHP。如今,已经有许多 JavaScript 框架可供选择,比如 React.js、Next.js、Vue.js、Nuxt、Svelte、SvelteKit、Astro 等等。
在本文中,我将尝试使用 Golang、HTML、CSS 和一些 JavaScript 来创建我的网站。前端 HTML 模板部分将使用Templ。如果你熟悉 Ruby on Rails 或 Laravel,那么你可能已经了解 HTML 模板的概念。Rails 提供 ERB,Laravel 提供 Blade,它们的目的都是将后端代码与 HTML 直接集成,同时创建模块化的 HTML 模块以便在项目中复用。
安装 Templ
首先,我们需要安装 Templ 的最新版本(本文撰写时的版本为 v0.2.778,尚未达到 v1 版本)。
go install github.com/a-h/templ/cmd/templ@latest
安装完成后,我们可以开始创建一个空的 Golang 项目。假设项目名称为personal
。
mkdir personal && cd personal
touch main.go
go mod init personal
现在,项目已经初始化完成。接下来,我们将在main.go
文件中创建一个简单的 HTTP 服务器。在本文中,我将使用Echo 框架。
创建 HTTP 服务器
以下是main.go
文件的代码:
package main
import (
"context"
"fmt"
"log"
"net/http"
"os"
"os/signal"
"personal/internal/config"
"syscall"
"github.com/caarlos0/env/v11"
"github.com/labstack/echo/v4"
"golang.org/x/net/http2"
"golang.org/x/net/http2/h2c"
)
func main() {
cfg, err := env.ParseAs[config.Config]()
if err != nil {
log.Println("error loading config")
}
e := echo.New()
h2s := &http2.Server{
MaxConcurrentStreams: 250,
MaxReadFrameSize: 1048576,
IdleTimeout: cfg.GracefulTimeout,
}
s := http.Server{
Addr: fmt.Sprintf(":%s", cfg.Port),
Handler: h2c.NewHandler(e, h2s),
}
log.Printf("server running on port: %s", cfg.Port)
gofunc() {
if err := s.ListenAndServe(); err != nil && err != http.ErrServerClosed {
log.Println("shutting down the server")
}
}()
quit := make(chan os.Signal, 1)
signal.Notify(quit, os.Interrupt, syscall.SIGTERM)
<-quit
log.Println("shutting down server...")
ctx, cancel := context.WithTimeout(context.Background(), cfg.GracefulTimeout)
defer cancel()
if err := s.Shutdown(ctx); err != nil {
log.Println("server forced to shutdown")
}
log.Println("server exiting")
}
运行以下命令以安装所有依赖项:
go mod tidy
接下来,创建一个名为config.go
的文件,用于存储服务器的配置信息:
package config
import "time"
type Config struct {
Port string `env:"PORT" envDefault:"8080"`
Env string `env:"ENV" envDefault:"dev"`
GracefulTimeout time.Duration `env:"GRACEFUL_TIMEOUT" envDefault:"10s"`
}
为了确保服务器正常运行,可以在终端中运行以下命令:
go run main.go
如果一切正常,终端会显示类似以下的输出:
集成 Templ
在服务器可以正常运行后,我们开始将 Templ 集成到项目中。首先,在internal
目录下创建一个名为views
的文件夹,路径为/personal/internal/views
。然后创建一个名为layout.templ
的文件,用于定义项目的基础布局。
以下是layout.templ
的代码:
package views
templ head(title string, description string) {
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>{title}</title>
<meta name="description" content={description} />
<style>
html {
--font-sans: 'Manrope', sans-serif;
--font-mono: 'JetBrains Mono', monospace;
scroll-behavior: smooth;
}
.app {
display: flex;
flex-direction: column;
min-height: 100vh;
}
main {
flex: 1;
display: flex;
flex-direction: column;
padding: 1rem;
width: 100%;
max-width: 64rem;
margin: 0 auto;
box-sizing: border-box;
}
</style>
</head>
}
templ Layout(title string, description string, content templ.Component) {
<!DOCTYPE html>
<html>
@head(title, description)
<body>
<div class="app">
<main>
@content
</main>
</div>
</body>
</html>
}
上述代码中,我们定义了一个名为Layout
的 HTML 布局函数,它包含三个参数:title
、description
和content
。同时,我们还定义了一个head
函数,用于存储网站的元信息。
注意:可以使用 VSCode 的 Templ 插件 来更方便地导航和编辑 Templ 函数。
接下来,运行以下命令生成 Golang 文件,以便在代码中调用 Templ 函数:
templ generate
如果终端提示templ version check: templ not found in go.mod file
,不要担心。运行以下命令将 Templ 添加到go.mod
文件中:
go get github.com/a-h/templ
再次运行templ generate
,你会在/personal/internal/views
目录下看到一个名为layout_templ.go
的文件,这是 Templ 自动生成的代码文件。
创建主页
接下来,我们为项目创建一个简单的主页。在/personal/internal/views
目录下创建一个名为home.templ
的文件,内容如下:
package views
templ Home() {
<section>
<p>Hello World.</p>
</section>
}
然后运行以下命令生成对应的 Golang 文件:
templ generate
渲染模板
为了在 Echo 的路由中渲染模板,我们需要创建一个渲染函数。在personal/pkg/renderer
目录下创建一个文件,并添加以下代码:
package renderer
import (
"github.com/a-h/templ"
"github.com/labstack/echo/v4"
)
func Render(c echo.Context, statusCode int, t templ.Component) error {
buf := templ.GetBuffer()
defer templ.ReleaseBuffer(buf)
if err := t.Render(c.Request().Context(), buf); err != nil {
return err
}
return c.HTML(statusCode, buf.String())
}
这个函数会将模板渲染为字节缓冲区,然后通过c.HTML
方法将其转换为 HTML 响应。
修改主程序
最后,修改main.go
文件,添加路由并渲染模板:
package main
import (
...
"personal/pkg/renderer"
)
func main() {
...
e.GET("/", func(c echo.Context) error {
return renderer.Render(c, http.StatusOK,
views.Layout("Home",
"Zainokta's home page, feels like home",
views.Home()))
})
...
}
运行以下命令启动服务器:
go run main.go
访问http://localhost:8080/
,你将看到以下页面内容:
总结
通过本文的步骤,我们成功使用 Golang 和 Templ 创建了一个简单的网站。Templ 提供了强大的 HTML 模板功能,使得前后端的集成更加便捷。你可以基于本文的示例代码进一步扩展和自定义你的项目。