手撸博客5 导航栏及layout模板

截止目前,我们的blog只有单个的页面,没有将其统一管理起来。要管理有两种方法,相信大家都见过:

  • 首页,包含指向每部分内容的链接
  • 导航栏,无论位于哪个页面,都有一个导航栏指向其他的页面
    从blog的使用场景来说,导航栏更加使用,在阅读当前文章的同时,可以通过导航栏快速移动到其他专题。

1 设计思路

在每个页面的顶部添加一个导航栏,目前可以导航到博客,留言板和关于3个页面。后面按照需要扩展。

导航栏

如果要在每个页面模板都新增这个模块,同样的内容需要修改的文件太多,后续调整导航栏和新增页面都太麻烦,因此我们需要一个框架模板,在框架模板里将所有页面中共有的内容(导航栏、css、js等)统一部署,每个功能页面只关注自己的功能就行,减少后续的开发量。
gin官方并不支持这种框架模板,但官方github上推荐了使用ez-gin-template这个包。其使用和源码解析见https://www.jianshu.com/p/a9c81e02e8f6

2 框架模板

框架模板如下,主要有几个点:

  • 从参数中解析本页的title
  • 添加公共属性和静态资源
  • 引入模板header
  • 引入模板contentcontent为页面的实际内容
<!DOCTYPE html>
<html>
    <header>
        <title>{{.Title}}</title>
        <meta charset="utf8"/>
        <link rel="stylesheet" type="text/css" href="../../static/css/common.css">
    </header>
    <body>
        <div class="header">
            {{template "header"}}
        </div>
        <div class="content">
            {{template "content" .Content}}
        </div>
    </body>
</html>

3 header模板

header模板实现了导航栏。

使用一个列表表示导航栏中的条目,将关于放置在页面的最右端:

{{define "header"}}
<ul class="navi">
    <li class="navi_li active"><a class="navi_a" href="/article_list">博客</a></li>
    <li class="navi_li"><a class="navi_a" href="/msgboard">留言板</a></li>
    <li class="navi_li" style="float: right"><a class="navi_a" href="/about">关于</a></li>
</ul>
{{end}}

通过CSS将列表显示成导航栏的样子:

.footer-fixed {
    position: fixed;
    margin: 0;
    padding: 0;
    left: 0;
    bottom: 0;
    width: 1000px;
    height: 50px;
    margin-left: auto;
    margin-right: auto;
}

ul.navi {
    list-style-type: none;
    margin: 0;
    padding: 0;
    overflow: hidden;
    background-color: #333333;
    top: 0;
    width: 100%;
    height: 50;
}

li.navi_li {
    float: left;
}

a.navi_a {
    display: block;
    width: 60px;
    padding: 14px 16px;
    color: white;
    text-decoration: none;
    text-align: center;
}

li.navi_li:hover {
    background-color: #111111
}

4 以article_list模板为例的content

article_list模板不再需要公共的部分,只需要描述文章列表的块中需要哪些内容。其模板名必须定义为在content,因为我们在layout模板中会加载名字为content的模板。

{{ define "content"}}
<div class="article_list">
    {{ if len .}}
    <h2>Article List:</h2>
    <ul>
        {{ range . }}
        <li><a href="/article/{{.ID}}">{{.Title}}</a></li>
        {{ end }}
    </ul>
    {{ else }}
    <p>当前没有文章 :( </p>
    {{ end }}
</div>
{{end}}

article_list模板的使用如下:

// ArticleListGet handle route to /article_list
func ArticleListGet(c *gin.Context) {
    articles, err := service.ShowArticleList()
    ctx := make(map[string]interface{})
    ctx["Title"] = "博客列表"
    ctx["Content"] = articles
    if err != nil {
        fmt.Println("get articles from db err", err)
        c.String(http.StatusInternalServerError, err.Error())
    }

    c.HTML(http.StatusOK, "blogs/article_list", ctx)
}

和原来相比,有如下几点差异:

  • 模板名从article_list变为了blogs/article_list,因为ez-gin-template会将每个模板名设置为配置的模板目录下的相对路径。
  • 传入的参数不再是articles,而是包含了articles和页面Titlemap,因为layout模板要根据Title字段设置当前页面的标题,然后将Content中的内容,即article传递给article_list模板解析。

5 使用ez-gin-template将所有内容组织起来

5.1 模板目录结构

  • layouts目录中放置框架模板。
  • partials目录中放置全局组件模板,当前是_header.html模板,即导航栏。ez-gin-template认为所有以"_"开头的模板文件作为组件模板,只会嵌入到其他模板中,而不会作为最终模板去解析。
  • blogs目录中放置的就是我们最终要展示给用户的页面模板,所有页面都会嵌入到layout模板后重新生成组合之后的模板,提供给gin的HTML渲染模块。
    模板目录结构

5.2 ez-gin-template配置

2-3行代码就完成了模板的组合和加载,可以使用了

import (
    eztemp "github.com/michelloworld/ez-gin-template"
)
engine := gin.Default()
render := eztemp.New()
// 配置模板文件所在的目录
render.TemplatesDir = "template/" 
// render.Layout = "layouts/base"     // default
// render.Ext = ".html"               // default
// 组合模板目录下的模板,并赋值给HTMLRender,以后的HTML渲染就使用新生成的组合模板
engine.HTMLRender = render.Init()

6 效果

文章列表

留言板
关于

7 小结

今天通过使用ez-gin-template模板实现了框架模板,并添加了导航类。 为后面的扩展省了很多工作。
ez-gin-template通过140行代码实现了这样一个功能,其主要依靠对ginRender模块的熟悉,将自己想要的东西嵌入到了里面。只要熟悉了Render模块的原理,相信想要实现其他想法都不难。也就是行业常说的,程序员看代码和写代码的时间比例应该在10:1才比较合理。
我也是通过这次事件对Render模块有了初步的了解,果然做事还是需要了解清楚需求,了解清楚背景,对症下药最省事。
ez-gin-template的详解可以看上面给出的另外一篇文章。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,753评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,668评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,090评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,010评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,054评论 6 395
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,806评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,484评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,380评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,873评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,021评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,158评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,838评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,499评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,044评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,159评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,449评论 3 374
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,136评论 2 356

推荐阅读更多精彩内容

  • 今天打算给博客添加导航栏。先写了一个header模板插入到了article_list模板中,并在article_l...
    FinaLone阅读 545评论 0 0
  • 黑色的海岛上悬着一轮又大又圆的明月,毫不嫌弃地把温柔的月色照在这寸草不生的小岛上。一个少年白衣白发,悠闲自如地倚坐...
    小水Vivian阅读 3,110评论 1 5
  • 渐变的面目拼图要我怎么拼? 我是疲乏了还是投降了? 不是不允许自己坠落, 我没有滴水不进的保护膜。 就是害怕变得面...
    闷热当乘凉阅读 4,247评论 0 13
  • 感觉自己有点神经衰弱,总是觉得手机响了;屋外有人走过;每次妈妈不声不响的进房间突然跟我说话,我都会被吓得半死!一整...
    章鱼的拥抱阅读 2,172评论 4 5
  • 夜莺2517阅读 127,720评论 1 9