一个不错的html渲染页面模板
This commit is contained in:
43
main.go
43
main.go
@@ -1,23 +1,52 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"html/template"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// Article 文章结构体,用于存储文章相关信息
|
||||
type Article struct {
|
||||
Title string
|
||||
Content string
|
||||
Title string // 文章标题
|
||||
Content string // 文章内容
|
||||
}
|
||||
|
||||
// UnixToTime 将Unix时间戳转换为格式化的日期时间字符串
|
||||
// 参数:
|
||||
//
|
||||
// timestamp: Unix时间戳(秒)
|
||||
//
|
||||
// 返回值:
|
||||
//
|
||||
// 格式化后的日期时间字符串,格式为"2006-01-02 15:04:05"
|
||||
func UnixToTime(timestamp int) string {
|
||||
t := time.Unix(int64(timestamp), 0)
|
||||
return t.Format("2006-01-02 15:04:05")
|
||||
}
|
||||
|
||||
// main 函数是程序的入口点,初始化并启动Web服务器
|
||||
func main() {
|
||||
// 创建默认的gin引擎
|
||||
r := gin.Default()
|
||||
// 加载模板(支持多层目录)
|
||||
|
||||
// 注册模板函数,使模板可以使用自定义函数UnixToTime
|
||||
r.SetFuncMap(template.FuncMap{
|
||||
"UnixToTime": UnixToTime,
|
||||
})
|
||||
|
||||
// 加载模板文件,支持多层目录结构
|
||||
r.LoadHTMLGlob("templates/**/*")
|
||||
|
||||
// 配置静态文件目录,将./static目录映射到URL路径/static
|
||||
r.Static("/static", "./static")
|
||||
|
||||
// 路由
|
||||
// 设置路由
|
||||
// 根路由处理函数,渲染首页
|
||||
r.GET("/", func(c *gin.Context) {
|
||||
c.HTML(200, "pages/index.html", gin.H{
|
||||
// 渲染pages/index.html模板,并传递数据
|
||||
c.HTML(200, "pages/index", gin.H{
|
||||
"title": "Main website",
|
||||
"score": 60,
|
||||
"hobby": []string{"吃饭", "睡觉", "打豆豆"},
|
||||
@@ -37,10 +66,12 @@ func main() {
|
||||
Title: "标题",
|
||||
Content: "测试2",
|
||||
},
|
||||
"data": 1764077331, // Unix时间戳示例
|
||||
})
|
||||
})
|
||||
|
||||
err := r.Run(":8080")
|
||||
// 启动HTTP服务器,监听在8081端口
|
||||
err := r.Run(":8081")
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
135
static/navbar.css
Normal file
135
static/navbar.css
Normal file
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
* navbar.css - 网站导航栏样式文件
|
||||
* 负责定义网站的导航栏和主内容区域的基本样式
|
||||
*/
|
||||
|
||||
/*
|
||||
* 全局样式设置
|
||||
* 重置浏览器默认边距,设置全局字体和背景色
|
||||
*/
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: "Segoe UI", Arial, sans-serif;
|
||||
background: #f4f6f9;
|
||||
color: #333;
|
||||
/* 为固定导航栏留出顶部空间 */
|
||||
padding-top: 70px; /* 大于或等于导航栏高度 */
|
||||
}
|
||||
|
||||
/*
|
||||
* 导航栏容器样式
|
||||
* 使用flex布局实现两端对齐的导航栏,应用渐变背景和阴影效果
|
||||
* 添加position: fixed使其固定在页面顶部
|
||||
*/
|
||||
.navbar {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
background: linear-gradient(90deg, #1e3c72, #2a5298);
|
||||
padding: 0.8rem 2rem;
|
||||
box-shadow: 0 4px 10px rgba(0,0,0,0.3);
|
||||
|
||||
/* 固定定位相关样式 */
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 1000; /* 确保导航栏在其他元素之上 */
|
||||
}
|
||||
|
||||
/*
|
||||
* 网站Logo样式
|
||||
* 设置Logo字体大小、粗细和颜色,添加悬停动画效果
|
||||
*/
|
||||
.navbar .logo {
|
||||
font-size: 1.5rem;
|
||||
font-weight: bold;
|
||||
color: #fff;
|
||||
letter-spacing: 2px;
|
||||
transition: transform 0.3s ease;
|
||||
}
|
||||
|
||||
/*
|
||||
* Logo悬停效果
|
||||
* 鼠标悬停时放大并轻微旋转Logo
|
||||
*/
|
||||
.navbar .logo:hover {
|
||||
transform: scale(1.1) rotate(-3deg);
|
||||
}
|
||||
|
||||
/*
|
||||
* 导航链接列表样式
|
||||
* 移除默认列表样式,使用flex布局排列导航项
|
||||
*/
|
||||
.nav-links {
|
||||
list-style: none;
|
||||
display: flex;
|
||||
gap: 1.5rem;
|
||||
}
|
||||
|
||||
/*
|
||||
* 导航链接样式
|
||||
* 移除下划线,设置文字颜色和粗细,为动画效果做准备
|
||||
*/
|
||||
.nav-links li a {
|
||||
text-decoration: none;
|
||||
color: #fff;
|
||||
font-weight: 500;
|
||||
position: relative;
|
||||
transition: color 0.3s ease;
|
||||
}
|
||||
|
||||
/*
|
||||
* 导航链接下划线效果
|
||||
* 使用伪元素创建底部横线,初始宽度为0
|
||||
*/
|
||||
.nav-links li a::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
width: 0;
|
||||
height: 2px;
|
||||
bottom: -4px;
|
||||
left: 0;
|
||||
background-color: #ffcc00;
|
||||
transition: width 0.3s ease;
|
||||
}
|
||||
|
||||
/*
|
||||
* 导航链接悬停文字颜色变化
|
||||
* 鼠标悬停时文字变为金色
|
||||
*/
|
||||
.nav-links li a:hover {
|
||||
color: #ffcc00;
|
||||
}
|
||||
|
||||
/*
|
||||
* 导航链接下划线动画
|
||||
* 鼠标悬停时底部横线从0扩展到100%宽度
|
||||
*/
|
||||
.nav-links li a:hover::after {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/*
|
||||
* 主内容区域样式
|
||||
* 设置主内容区域的内边距
|
||||
*/
|
||||
main {
|
||||
padding: 2rem;
|
||||
}
|
||||
|
||||
/*
|
||||
* 主内容区域标题样式
|
||||
* 设置主内容区域中标题的颜色
|
||||
*/
|
||||
main h1, main h2 {
|
||||
color: #2a5298;
|
||||
}
|
||||
|
||||
/*
|
||||
* 主内容区域段落样式
|
||||
* 设置主内容区域中段落的行高
|
||||
*/
|
||||
main p {
|
||||
line-height: 1.6;
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: "Segoe UI", Arial, sans-serif;
|
||||
background: #f4f6f9;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.navbar {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
background: linear-gradient(90deg, #1e3c72, #2a5298);
|
||||
padding: 0.8rem 2rem;
|
||||
box-shadow: 0 4px 10px rgba(0,0,0,0.3);
|
||||
}
|
||||
|
||||
.navbar .logo {
|
||||
font-size: 1.5rem;
|
||||
font-weight: bold;
|
||||
color: #fff;
|
||||
letter-spacing: 2px;
|
||||
transition: transform 0.3s ease;
|
||||
}
|
||||
.navbar .logo:hover {
|
||||
transform: scale(1.1) rotate(-3deg);
|
||||
}
|
||||
|
||||
.nav-links {
|
||||
list-style: none;
|
||||
display: flex;
|
||||
gap: 1.5rem;
|
||||
}
|
||||
.nav-links li a {
|
||||
text-decoration: none;
|
||||
color: #fff;
|
||||
font-weight: 500;
|
||||
position: relative;
|
||||
transition: color 0.3s ease;
|
||||
}
|
||||
.nav-links li a::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
width: 0%;
|
||||
height: 2px;
|
||||
bottom: -4px;
|
||||
left: 0;
|
||||
background-color: #ffcc00;
|
||||
transition: width 0.3s ease;
|
||||
}
|
||||
.nav-links li a:hover {
|
||||
color: #ffcc00;
|
||||
}
|
||||
.nav-links li a:hover::after {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
main {
|
||||
padding: 2rem;
|
||||
}
|
||||
main h1, main h2 {
|
||||
color: #2a5298;
|
||||
}
|
||||
main p {
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
@@ -1,14 +1,19 @@
|
||||
{{ define "base" }}
|
||||
{{/* 定义基础模板,作为其他页面模板的布局基础 */}}
|
||||
{{ define "layout/base" }}
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
{{/* 标题块定义 - 允许子模板重写标题内容 */}}
|
||||
<title>{{ block "title" . }}默认标题{{ end }}</title>
|
||||
{{/* 引入静态样式文件 */}}
|
||||
<link rel="stylesheet" href="/static/style.css">
|
||||
</head>
|
||||
<body>
|
||||
{{/* 引入导航栏模板 */}}
|
||||
{{ template "navbar" . }}
|
||||
|
||||
{{/* 主内容区域定义 - 子模板应在此处填充具体内容 */}}
|
||||
<main>
|
||||
{{ block "content" . }}{{ end }}
|
||||
</main>
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
{{ define "navbar" }}
|
||||
{{/* 定义导航栏模板,包含网站导航链接 */}}
|
||||
{{ define "layout/navbar" }}
|
||||
|
||||
<link rel="stylesheet" href="/static/navbar.css">
|
||||
<nav class="navbar">
|
||||
{{/* 网站Logo区域 */}}
|
||||
<div class="logo">🔥 MyGinSite</div>
|
||||
|
||||
{{/* 导航链接列表 */}}
|
||||
<ul class="nav-links">
|
||||
<li><a href="/">首页</a></li>
|
||||
<li><a href="/about">关于我们</a></li>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
{{define "pages/index.html"}}
|
||||
{{/* 定义index页面模板 */}}
|
||||
{{define "pages/index"}}
|
||||
<!doctype html>
|
||||
<html lang="zh">
|
||||
<head>
|
||||
@@ -7,50 +8,54 @@
|
||||
<title>{{.title}}</title>
|
||||
</head>
|
||||
<body>
|
||||
{{/*输出*/}}
|
||||
{{template "layout/navbar"}}
|
||||
{{/* 基本数据输出示例 - 直接渲染标题变量 */}}
|
||||
<h2>{{.title}}</h2>
|
||||
|
||||
{{/*定义变量*/}}
|
||||
{{$t :=.title}}
|
||||
{{/* 模板变量定义示例 - 将标题赋值给局部变量t */}}
|
||||
{{$t := .title}}
|
||||
<h4>{{$t}}</h4>
|
||||
|
||||
|
||||
{{/*条件判断*/}}
|
||||
{{if ge .score 60}}
|
||||
{{/* 条件判断示例 - 根据score值判断是否及格 */}}
|
||||
{{if ge .score 60}} <!-- ge: 大于等于 -->
|
||||
<p>及格</p>
|
||||
{{else}}
|
||||
<P></P>
|
||||
<p></p>
|
||||
{{end}}
|
||||
|
||||
{{/*循环遍历数据*/}}
|
||||
|
||||
{{range $key,$value:=.hobby}}
|
||||
{{/* 简单数组循环遍历示例 */}}
|
||||
{{range $key, $value := .hobby}} <!-- 遍历爱好列表 -->
|
||||
<ul>
|
||||
<li>{{$key}}--{{$value}}</li>
|
||||
<li>{{$key}}--{{$value}}</li> <!-- 输出索引和值 -->
|
||||
</ul>
|
||||
{{end}}
|
||||
|
||||
{{range $key,$value:=.newsList}}
|
||||
{{/* 结构体数组循环遍历示例 */}}
|
||||
{{range $key, $value := .newsList}} <!-- 遍历文章列表 -->
|
||||
<ul>
|
||||
<li>{{$key}}--{{$value.Title}}--{{$value.Content}}</li>
|
||||
<li>{{$key}}--{{$value.Title}}--{{$value.Content}}</li> <!-- 输出索引和文章属性 -->
|
||||
</ul>
|
||||
{{end}}
|
||||
|
||||
{{range $key,$value:=.newsList2}}
|
||||
{{/* 空数组处理示例 - 当newsList2为空时显示提示信息 */}}
|
||||
{{range $key, $value := .newsList2}}
|
||||
<ul>
|
||||
<li>{{$key}}--{{$value.Title}}--{{$value.Content}}</li>
|
||||
</ul>
|
||||
{{else}}
|
||||
<li>没有数据</li>
|
||||
<li>没有数据</li> <!-- 当数组为空时执行 -->
|
||||
{{end}}
|
||||
|
||||
{{/*结构结构*/}}
|
||||
{{with .news}}
|
||||
{{.Title}}
|
||||
{{.Content}}
|
||||
{{/* 结构体数据访问示例 - 使用with语句简化结构体属性访问 */}}
|
||||
{{with .news}} <!-- 针对news结构体设置上下文 -->
|
||||
{{.Title}} <!-- 直接访问Title属性,等同于.news.Title -->
|
||||
{{.Content}} <!-- 直接访问Content属性,等同于.news.Content -->
|
||||
{{end}}
|
||||
<br>
|
||||
|
||||
|
||||
{{/* 自定义模板函数使用示例 */}}
|
||||
{{.data}} <!-- 输出原始时间戳 -->
|
||||
{{UnixToTime .data}} <!-- 使用自定义函数将时间戳转换为格式化日期 -->
|
||||
</body>
|
||||
</html>
|
||||
{{end}}
|
||||
Reference in New Issue
Block a user