欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

 更新時(shí)間:2025年01月14日 09:30:44   作者:老大白菜  
本文詳細(xì)介紹了Golang HTML模板的使用方法,包括基礎(chǔ)模板、高級模板、完整應(yīng)用示例、CSS樣式、JavaScript交互等,文章強(qiáng)調(diào)了模板組織、代碼復(fù)用、語義化HTML、響應(yīng)式設(shè)計(jì)、性能優(yōu)化等最佳實(shí)踐,感興趣的朋友跟隨小編一起看看吧

Golang HTML 模板使用指南

1. 基礎(chǔ)模板示例

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" >關(guān)于</a>
            <a href="/contact" rel="external nofollow" >聯(lián)系我們</a>
        </nav>
    </header>
    <main>
        {{template "content" .}}
    </main>
    <footer>
        <p>&copy; {{.Year}} 我的網(wǎng)站</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: "我的網(wǎng)站",
            Year:  time.Now().Year(),
        }
        tmpl.Execute(w, data)
    })
    http.ListenAndServe(":8080", nil)
}

1.2 列表渲染

<!-- templates/products.html -->
{{define "content"}}
<div class="products">
    <h2>產(chǎn)品列表</h2>
    <div class="product-grid">
        {{range .Products}}
        <div class="product-card">
            <img src="{{.Image}}" alt="{{.Name}}">
            <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        string
    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/products.html",
    ))
    data := struct {
        Title    string
        Year     int
        Products []Product
    }{
        Title: "產(chǎn)品列表",
        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="Logo">
    </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. 完整應(yīng)用示例

3.1 博客系統(tǒng)模板

<!-- 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="{{.Title}}">
            </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
    Content   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: "技術(shù)", Slug: "tech", Count: 10},
            {Name: "生活", Slug: "life", Count: 5},
        },
        Posts: []Post{
            {
                Title:     "示例文章",
                Slug:      "example-post",
                Content:   "這是一篇示例文章的內(nèi)容...",
                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 */
/* 基礎(chǔ)樣式 */
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;
}
/* 產(chǎn)品卡片樣式 */
.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 1rem;
    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));
    }
    // 表單驗(yàn)證
    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('請?zhí)顚懰斜靥钭侄?);
            }
        });
    });
});
// 工具函數(shù)
function debounce(func, wait) {
    let timeout;
    return function executedFunction(...args) {
        const later = () => {
            clearTimeout(timeout);
            func(...args);
        };
        clearTimeout(timeout);
        timeout = setTimeout(later, wait);
    };
}

總結(jié)

模板組織

  • 使用嵌套模板實(shí)現(xiàn)代碼復(fù)用
  • 保持模板結(jié)構(gòu)清晰
  • 合理使用模板函數(shù)

最佳實(shí)踐

  • 使用語義化 HTML
  • 保持 CSS 模塊化
  • 實(shí)現(xiàn)響應(yīng)式設(shè)計(jì)
  • 添加適當(dāng)?shù)慕换バЧ?/li>

性能優(yōu)化

  • 緩存編譯后的模板
  • 壓縮靜態(tài)資源
  • 使用 CDN 加速
  • 實(shí)現(xiàn)懶加載

到此這篇關(guān)于Golang HTML 模板使用指南的文章就介紹到這了,更多相關(guān)Golang HTML 模板內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • golang包循環(huán)引用的幾種解決方案總結(jié)

    golang包循環(huán)引用的幾種解決方案總結(jié)

    golang有包循環(huán)引用問題,用過的應(yīng)該都知道,下面這篇文章主要給大家介紹了關(guān)于golang包循環(huán)引用的幾種解決方案,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-09-09
  • Go語言如何實(shí)現(xiàn)線程安全的Map

    Go語言如何實(shí)現(xiàn)線程安全的Map

    Go語言內(nèi)置的map雖然高效,但并不是線程安全的,若在多線程環(huán)境中直接操作map,可能會(huì)引發(fā)并發(fā)寫入的錯(cuò)誤,下面我們就來看看如何實(shí)現(xiàn)線程安全的Map吧
    2024-11-11
  • 簡化Go開發(fā)提高生產(chǎn)力的強(qiáng)大工具及使用詳解

    簡化Go開發(fā)提高生產(chǎn)力的強(qiáng)大工具及使用詳解

    作為?Go?開發(fā)人員,應(yīng)該都知道維持簡潔高效開發(fā)工作流程的重要性,為了提高工作效率和代碼質(zhì)量,簡化開發(fā)流程并自動(dòng)執(zhí)行重復(fù)性任務(wù)至關(guān)重要,在本文中,我們將探討一些強(qiáng)大的工具和技術(shù),它們將簡化?Go?開發(fā)過程,助力您的編碼之旅
    2023-10-10
  • 5個(gè)可以在Golang中優(yōu)化代碼以提高性能的技巧分享

    5個(gè)可以在Golang中優(yōu)化代碼以提高性能的技巧分享

    作為一名軟件工程師,確保你的代碼高效且性能良好是非常重要的。本文主要和大家分享5個(gè)可以在Golang中優(yōu)化代碼以提高性能的技巧,希望對大家有所幫助
    2023-03-03
  • Golang實(shí)現(xiàn)Java虛擬機(jī)之解析class文件詳解

    Golang實(shí)現(xiàn)Java虛擬機(jī)之解析class文件詳解

    這篇文章主要為大家詳細(xì)介紹了Golang實(shí)現(xiàn)Java虛擬機(jī)之解析class文件的相關(guān)知識(shí),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-01-01
  • go sync.Map基本原理深入解析

    go sync.Map基本原理深入解析

    這篇文章主要為大家介紹了go sync.Map基本原理深入解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-01-01
  • GoLand安裝與環(huán)境配置的完整步驟

    GoLand安裝與環(huán)境配置的完整步驟

    作為一個(gè)go語言程序員,覺得自己有義務(wù)為go新手開一條更簡單便捷的上手之路,下面這篇文章主要給大家介紹了關(guān)于GoLand安裝與環(huán)境配置的完整步驟,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2022-12-12
  • go swagger生成接口文檔使用教程

    go swagger生成接口文檔使用教程

    這篇文章主要為大家介紹了go swagger生成接口文檔使用教程示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08
  • 從零封裝Gin框架及項(xiàng)目初始化教程

    從零封裝Gin框架及項(xiàng)目初始化教程

    這篇文章主要為大家介紹了從零封裝Gin框架及項(xiàng)目的初始化教程詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2024-01-01
  • Golang Printf,Sprintf,Fprintf 格式化詳解

    Golang Printf,Sprintf,Fprintf 格式化詳解

    這篇文章主要介紹了Golang Printf,Sprintf,Fprintf 格式化詳解,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-03-03

最新評論