开发者

Golang HTML 模板使用指南示例详解

目录
  • golang html 模板使用指南
  • 1. 基础模板示例
    • 1.1 简单页面模板
    • 1.2 列表渲染
  • 2. 高级模板示例
    • 2.1 嵌套模板
    • 2.2 表单处理
    • 2.3 分页组件
  • 3. 完整应用示例
    • 3.1 博客系统模板
  • 4. css 样式示例
    • 5. JavaScript 交互示例
      • 总结

        Golang HTML 模板使用指南

        1. 基础模板示例

        1.1 简单页面模板

        <!-- templates/layout.html -->
        <!DOCTYPE html>
        <html>
        <head>
            <title>{{.Title}}</title>
            <meta charset="utf-8">
            <meta name="viewport" content="width=device-width, initial-scale=1">
            <link rel="stylesheet" href="/static/css/style.css" rel="external nofollow" >
        </head>
        <body>
            <header>
                <h1>{{.Title}}</h1>
                <nav>
                    <a href="/" rel="external nofollow" >首页</a>
                    <a href="/about" rel="external nofollow" >关于</a>
                    <a href="/contact" rel="external nofollow" >联系我们</a>
                </nav>
            </header>
            <main>
                {{template "content" .}}
            </main>
            <footer>
                <p>&copy; {{.Year}} 我的网站</p>
            </footer>
        </body>
        </html>
        // main.go
        package main
        import (
            "html/template"
            "net/http"
            "time"
        )
        func main() {
            http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
                tmpl := template.Must(template.ParseFiles("templates/layout.html"))
                data := struct {
                    Title string
                    Year  int
                }{
                    Title: "我的网站",
                    Year:  time.Now().Year(),
                }
                tmpl.Execute(w, data)
            })
            http.ListenAndServe(":8080", nil)
        }

        1.2 列表渲染

        <!-- templates/products.html -->
        {{define "content"}}
        <div class="products">
            <h2>产品列表</h2>
            <div class="product-grid">
                {{range .Products}}
                <div class="product-card">
                    <img src="{{.Image}}" alt="Golang HTML 模板使用指南示例详解">
                    <h3>{{.Name}}</h3>
                    <p>{{.Description}}</p>
                    <div class="price">{{formatPrice .Price}}</div>
                    {{if .InStock}}
                        <button class="buy-btn">购买</button>
                    {{else}}
                        <button class="out-of-stock" disabled>缺货</button>
                    {{end}}
                </div>
                {{end}}
            </div>
        </div>
        {{end}}
        type Product struct {
            Name        s编程客栈tring
            Description string
            Price       float64
            Image       string
            InStock     bool
        }
        func productsHandler(w http.ResponseWriter, r *http.Request) {
            funcMap := template.FuncMap{
                "formatPrice": func(price float64) string {
                    return fmt.Sprintf("¥%.2f", price)
                },
            }
            tmpl := template.New("layout.html").Funcs(funcMap)
            tmpl = template.Must(tmpl.ParseFiles(
                "templates/layout.html",
                "templates/yxFSPproducts.html",
            ))
            data := struct {
                Title    string
                Year     int
                Products []Product
            }{
                Title: "产品列表",
                Year:  time.Now().Year(),
                Products: []Product{
                    {
                        Name:        "商品1",
                        Description: 编程"这是商品1的描述",
                        Price:       99.99,
                        Image:      "/static/images/product1.jpg",
                        InStock:    true,
                    },
                    // 更多商品...
                },
            }
            tmpl.Execute(w, data)
        }

        2. 高级模板示例

        2.1 嵌套模板

        <!-- templates/components/header.html -->
        {{define "header"}}
        <header class="site-header">
            <div class="logo">
                <img src="/static/images/logo.png" alt="Golang HTML 模板使用指南示例详解">
            </div>
            <nav class="main-nav">
                <ul>
                    {{range .NavItems}}
                    <li class="{{if eq $.CurrentPage .Link}}active{{end}}">
                        <a href="{{.Link}}" rel="external nofollow" >{{.Text}}</a>
                    </li>
                    {{end}}
                </ul>
            </nav>
            {{if .User}}
            <div class="user-menu">
                <span>欢迎, {{.User.Name}}</span>
                <a href="/logout" rel="external nofollow" >退出</a>
            </div>
            {{else}}
            <div class="auth-buttons">
                <a href="/login" rel="external nofollow"  class="btn btn-login">登录</a>
                <a href="/register" rel="external nofollow"  class="btn btn-register">注册</a>
            </div>
            {{end}}
        </header>
        {{end}}

        2.2 表单处理

        <!-- templates/form.html -->
        {{define "content"}}
        <div class="form-container">
            <h2>{{.FormTitle}}</h2>
            {{with .FormError}}
                <div class="error-message">{{.}}</div>
            {{end}}
            <form method="POST" action="{{.ForMACtion}}" enctype="multipart/form-data">
                {{range .Fields}}
                <div class="form-group">
                    <label for="{{.ID}}">{{.Label}}{{if .Required}}*{{end}}</label>
                    {{if eq .Type "text"}}
                        <input type="text" id="{{.ID}}" name="{{.Name}}" 
                               value="{{.Value}}" {{if .Required}}required{{end}}
                               {{with .Pattern}}pattern="{{.}}"{{end}}>
                    {{else if eq .Type "textarea"}}
                        <textarea id="{{.ID}}" name="{{.Name}}" 
                                 {{if .Required}}required{{end}}>{{.Value}}</textarea>
                    {{else if eq .Type "select"}}
                        <select id="{{.ID}}" name="{{.Name}}" 
                                {{if .Required}}required{{end}}>
                            {{range .Options}}
                            <option value="{{.Value}}" {{if eq .Value $.Selected}}selected{{end}}>
                                {{.Text}}
                            </option>
                            {{end}}
                        </select>
                    {{end}}
                    {{with .Error}}
                        <span class="field-error">{{.}}</span>
                    {{end}}
                </div>
                {{end}}
                <div class="form-actions">
                    <button type="submit" class="btn btn-primary">{{.SubmitText}}</button>
                    <button type="reset" class="btn btn-secondary">重置</button>
                </div>
            </form>
        </div>
        {{end}}

        2.3 分页组件

        <!-- templates/components/pagination.html -->
        {{define "pagination"}}
        <div class="pagination">
            {{if gt .TotalPages 1}}
                {{if gt .CurrentPage 1}}
                    <a href="?page=1" rel="external nofollow"  class="page-link first">&laquo;</a>
                    <a href="?page={{subtract .CurrentPage 1}}" rel="external nofollow"  class="page-link prev">&lsaquo;</a>
                {{end}}
                {{range $i := range (sequence .TotalPages)}}
                    {{if and (ge $i (subtract $.CurrentPage 2)) (le $i (add $.CurrentPage 2))}}
                        <a href="?page={{add $i 1}}" rel="external nofollow"  
                           class="page-link {{if eq $i (subtract $.CurrentPage 1)}}active{{end}}">
                            {{add $i 1}}
                        </a>
                    {{end}}
                {{end}}
                {{if lt .CurrentPage .TotalPages}}
                    <a href="?page={{add .CurrentPage 1}}" rel="external nofollow"  class="page-link next">&rsaquo;</a>
                    <a href="?page={{.TotalPages}}" rel="external nofollow"  class="page-link last">&raquo;</a>
                {{end}}
            {{end}}
        </div>
        {{end}}

        3. 完整应用示例

        3.1 博客系统模板

        <!-- templates/blog/list.html -->
        {{define "content"}}
        <div class="blog-list">
            <div class="filters">
                <div class="search">
                    <input type="text" placeholder="搜索文章..." 
                           value="{{.Query}}" id="searchInput">
                </div>
                <div class="categories">
                    {{range .Categories}}
                    <a href="/blog?category={{.Slug}}" rel="external nofollow"  
                       class="category {{if eq $.CurrentCategory .Slug}}active{{end}}">
                        {{.Name}} ({{.Count}})
                    </a>
                    {{end}}
                </div>
            </div>
            <div class="articles">
                {{range .Posts}}
                <article class="post-card">
                    {{if .Image}}
                    <div class="post-image">
                        <img src="{{.Image}}" alt="Golang HTML 模板使用指南示例详解">
                    </div>
                    {{end}}
                    <div class="post-content">
                        <h2><a href="/blog/{{.Slug}}" rel="external nofollow" >{{.Title}}</a></h2>
                        <div class="post-meta">
                            <span class="author">{{.Author}}</span>
                            <span class="date">{{formatDate .CreatedAt "2006-01-02"}}</span>
                            <span class="category">{{.Category}}</span>
                        </div>
                        <p class="excerpt">{{truncate .Content 200}}</p>
                        <div class="tags">
                            {{range .Tags}}
                            <a href="/blog?tag={{.}}" rel="external nofollow"  class="tag">{{.}}</a>
                            {{end}}
                        </div>
                    </div>
                </article>
                {{else}}
                <div class="no-posts">
                    暂无文章
                </div>
                {{end}}
            </div>
            {{template "pagination" .Pagination}}
        </div>
        {{end}}
        type BlogData struct {
            Query           string
            CurrentCategory string
            Categories      []Category
            Posts           []Post
            Pagination      Pagination
        }
        type Category struct {
            Name  string
            Slug  string
            Count int
        }
        type Post struct {
            Title     string
            Slug      string
            Con编程客栈tent   string
            Author    string
            Image     string
            Category  string
            Tags      []string
            CreatedAt time.Time
        }
        type Pagination struct {
            CurrentPage int
            TotalPages  int
            TotalItems  int
        }
        func blogHandler(w http.ResponseWriter, r *http.Request) {
            funcMap := template.FuncMap{
                "formatDate": func(t time.Time, layout string) string {
                    return t.Format(layout)
                },
                "truncate": func(s string, l int) string {
                    if len(s) <= l {
                        return s
                    }
                    return s[:l] + "..."
                },
            }
            tmpl := template.New("layout.html").Funcs(funcMap)
            tmpl = template.Must(tmpl.ParseFiles(
                "templates/layout.html",
                "templates/blog/list.html",
                "templates/components/pagination.html",
            ))
            data := BlogData{
                Query:           r.URL.Query().Get("q"),
                CurrentCategory: r.URL.Query().Get("category"),
                Categories: []Category{
                    {Name: "技术", Slug: "tech", Count: 10},
                    {Name: "生活", Slug: "life", Count: 5},
                },
                Posts: []Post{
                    {
                        Title:     "示例文章",
                        Slug:      "example-post",
                        Content:   "这是一篇示例文章的内容...",
                        Author:    "作者名",
                        Category: "tech",
                        Tags:     []string{"Go", "Web"},
                        CreatedAt: time.Now(),
                    },
                },
                Pagination: Pagination{
                    CurrentPage: 1,
                    TotalPages:  5,
                    TotalItems:  45,
                },
            }
            tmpl.Execute(w, data)
        }

        4. CSS 样式示例

        /* static/css/style.css */
        /* 基础样式 */
        body {
            font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
            line-height: 1.6;
            margin: 0;
            padding: 0;
            color: #333;
        }
        /* 头部样式 */
        .site-header {
            background: #fff;
            box-shadow: 0 2px 4px rgba(0,0,0,0.1);
            padding: 1rem;
        }
        .main-nav ul {
            list-style: none;
            display: Flex;
            gap: 1rem;
        }
        /* 产品卡片样式 */
        .product-grid {
            display: grid;
            grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
            gap: 2rem;
            padding: 2rem;
        }
        .product-card {
            border: 1px solid #eee;
            border-radius: 8px;
            overflow: hidden;
            transition: transform 0.2s;
        }
        .product-card:hover {
            transform: translateY(-5px);
            box-shadow: 0 4px 12px rgba(0,0,0,0.1);
        }
        /* 表单样式 */
        .form-container {
            max-width: 600px;
            margin: 2rem auto;
            padding: 2rem;
            background: #fff;
            border-radius: 8px;
            box-shadow: 0 2px 4px rgba(0,0,0,0.1);
        }
        .form-group {
            margin-bottom: 1.5rem;
        }
        /* 博客列表样式 */
        .blog-list {
            max-width: 1200px;
            margin: 0 auto;
            padding: 2rem;
        }
        .post-card {
            display: grid;
            grid-template-columns: 200px 1fr;
            gap: 1.5rem;
            margin-bottom: 2rem;
            padding: 1rem;
            background: #fff;
            border-radius: 8px;
            box-shadow: 0 2px 4px rgba(0,0,0,0.1);
        }
        /* 分页样式 */
        .pagination {
            display: flex;
            justify-content: center;
            gap: 0.5rem;
            margin: 2rem 0;
        }
        .page-link {
            padding: 0.5rem 1re编程客栈m;
            border: 1px solid #ddd;
            border-radius: 4px;
            color: #333;
            text-decoration: none;
        }
        .page-link.active {
            background: #007bff;
            color: #fff;
            border-color: #007bff;
        }

        5. javascript 交互示例

        // static/js/main.js
        document.addEventListener('DOMContentLoaded', function() {
            // 搜索功能
            const searchInput = document.getElementById('searchInput');
            if (searchInput) {
                searchInput.addEventListener('input', debounce(function(e) {
                    const query = e.target.value;
                    window.location.href = `/blog?q=${encodeURIComponent(query)}`;
                }, 500));
            }
            // 表单验证
            const forms = document.querySelectorAll('form');
            forms.forEach(form => {
                form.addEventListener('submit', function(e) {
                    const requiredFields = form.querySelectorAll('[required]');
                    let valid = true;
                    requiredFields.forEach(field => {
                        if (!field.value.trim()) {
                            valid = false;
                            field.classList.add('error');
                        } else {
                            field.classList.remove('error');
                        }
                    });
                    if (!valid) {
                        e.preventDefault();
                        alert('请填写所有必填字段');
                    }
                });
            });
        });
        // 工具函数
        function debounce(func, wait) {
            let timeout;
            return function executedFunction(...args) {
                const later = () => {
                    clearTimeout(timeout);
                    func(...args);
                };
                clearTimeout(timeout);
                timeout = setTimeout(later, wait);
            };
        }

        总结

        模板组织

        • 使用嵌套模板实现代码复用
        • 保持模板结构清晰
        • 合理使用模板函数

        最佳实践

        • 使用语义化 HTML
        • 保持 CSS 模块化
        • 实现响应式设计
        • 添加适当的交互效果

        性能优化

        • 缓存编译后的模板
        • 压缩静态资源
        • 使用 CDN 加速
        • 实现懒加载

        到此这篇关于Golang HTML 模板使用指南的文章就介绍到这了,更多相关Golang HTML 模板内容请搜索编程客栈(www.devze.com)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程客栈(www.devze.com)!

        0

        上一篇:

        下一篇:

        精彩评论

        暂无评论...
        验证码 换一张
        取 消

        最新开发

        开发排行榜