【小雞軟體】使用架構:beego + grom +xianyan
本章目標:添加頁面路由,能正常訪問輕部落格頁面
github地址: 開啟後,點擊右上方star按鈕
beego添加路由功能
beego 添加路由 通過修改 routers--> router.go 檔案,來實現,beego實現路由的方式有多種點我查看beego路由文檔,咱們採用註解路由
//註解路由 // path路由路徑,method路由方法:get、put、post...// @router path [method]func (this *Controller) Doit() { ...}
//在 router.go 中通過如下方式註冊路由:beego.Include(&CMSController{})
beego的controller控制器擁有很多方法,其中包括 Init、Prepare 等方法。其中Prepare方法是每次請求都會調用的方法,所以我們需要建立個“基類”來重寫結構體的Prepare方法。
控制器和路由的關係就好比:使用者到銀行,路由告訴到哪個視窗,控制器則是具體如何為使用者提供具體服務。
golang的繼承是用組合來類比繼承的,而golang的多態是通過介面(interface)來實現。
golang的介面實現,沒有強制性約定。只要實現了介面定義的所有方法,就是實現了介面。
- 咱們首先建立一個controllers-->base.go,新增結構體BaseController繼承beego.Controller,為BaseController添加的Prepare() 方法。所有繼承了BaseController的子controller 每次請求都會調用BaseController的Prepare()方法,因此咱們約定所有的子controller都會繼承BaseController,可以將每次請求的通用邏輯寫在BaseController的Prepare方法裡面。
- 如果子controller裡面的所有方法,除了要調用BaseController裡面的Prepare方法的通用邏輯外,還有一些當前子controller的通用邏輯,咋辦?難道當前子controller的每個方法都寫重複一樣的代碼嗎?有辦法,咱們自己在BaseController定義個介面,在BaseController的Prepare方法裡面判斷子controller是否實現了介面。如果實現了,咱們就調用介面方法。
下面是 檔案base.go的代碼
import ( "github.com/astaxie/beego" "log")// 約定:如果子controller 存在NestPrepare()方法,就實現了該介面,type NestPreparer interface { NestPrepare()}type BaseController struct { beego.Controller}func (ctx *BaseController) Prepare() { log.Println("BaseControll") // 判斷子類是否實現了NestPreparer介面,如果實現了就調用介面方法。 if app, ok := ctx.AppController.(NestPreparer); ok { app.NestPrepare() }}
- 咱們上面定義了基礎控制器BaseController。下面咱們新增個controllers-->index.go檔案,定義IndexController代碼如下:
package controllerstype IndexController struct { BaseController}//首頁// @router / [get]func (c *IndexController) Get() { c.TplName = "index.html"}//留言// @router /message [get]func (c *IndexController) GetMessage() { c.TplName = "message.html"}//關於// @router /about [get]func (c *IndexController) GetAbout() { c.TplName = "about.html"}
- 上面咱們定了3個路由已經對於的處理方法,但是,還需要調整routers->router.go才會生效。
import ( "github.com/jicg/liteblog/controllers" "github.com/astaxie/beego")func init() { //註解路由 需要調用Include。 beego.Include(&controllers.IndexController{})}
上面咱們定義好了golang部分代碼(後端代碼),還需要稍微調整下前端代碼,就可正常所有頁面了。
beego 模版渲染可以自訂方法(是對golang的html/template包進一步的封裝)
模版自訂方法,定義的方式為:
beego.AddFuncMap("模版中調用的方法名", 具體函數)
- 咱們上講已經將 header.html抽離出來了。上面已經將路由已經定義好,現在咱們來調整views->comm->header.html。
修改header.html將路由路徑改成咱們現在定義好的
<div class="header"> <div class="header-wrap"> <h1 class="logo pull-left"> <a href="index.html"> <img src="/static/images/logo.png" alt="" class="logo-img"> <img src="/static/images/logo-text.png" alt="" class="logo-text"> </a> </h1> <form class="layui-form blog-seach pull-left" action=""> <div class="layui-form-item blog-sewrap"> <div class="layui-input-block blog-sebox"> <i class="layui-icon layui-icon-search"></i> <input type="text" name="title" lay-verify="title" autocomplete="off" class="layui-input"> </div> </div> </form> <!-- *************這段是調整的部分 開始 *************--> <div class="blog-nav pull-right"> <ul class="layui-nav pull-left"> <li class="layui-nav-item "><a href="/" >首頁</a></li> <li class="layui-nav-item "><a href="/message">留言</a></li> <li class="layui-nav-item layui-this "><a href="/about">關於</a></li> </ul> <a href="#" class="personal pull-left"> <i class="layui-icon layui-icon-username"></i> </a> </div> <div class="mobile-nav pull-right" id="mobile-nav"> <a href="javascript:;"> <i class="layui-icon layui-icon-more"></i> </a> </div> </div> <!-- 這段是手機開啟的路由--> <ul class="pop-nav" id="pop-nav"> <li><a href="/">首頁</a></li> <li><a href="/message">留言</a></li> <li><a href="/about">關於</a></li> </ul> <!-- *************調整的部分 結束 *************--></div>
- 調整後咱們發現 “layui-this”這個css樣式咱們目前寫死調了,應該根據當前的頁面,選擇對應的li的,這就需要拿到當前頁面的路徑,還要能夠有方法去判斷路徑是否相同
2.1 擷取當前頁面的路徑,屬於通用功能,就該在BaseControllers的Prepare方法,添加變數的輸出
func (ctx *BaseController) Prepare() { // 將頁面路徑 儲存到 Path變數裡面 ctx.Data["Path"] = ctx.Ctx.Request.RequestURI if app, ok := ctx.AppController.(NestPreparer); ok { app.NestPrepare() }}
2.2 咱們再定義 equrl 模版方法,用來路徑是否相同。咱們就寫在main.go檔案中吧。
package mainimport ( _ "github.com/jicg/liteblog/routers" "github.com/astaxie/beego" "strings")func main() { initTemplate() beego.Run()}func initTemplate() { beego.AddFuncMap("equrl", func(x, y string) bool { s1 := strings.Trim(x, "/") s2 := strings.Trim(y, "/") return strings.Compare(s1, s2) == 0 })}
2.3 再修改views->comm->header.html裡面的代碼,加上路徑比較的邏輯:
......<div class="blog-nav pull-right"> <ul class="layui-nav pull-left"> <li class="layui-nav-item {{if equrl "/" .Path }}layui-this{{end}}"><a href="/" >首頁</a></li> <li class="layui-nav-item {{if equrl "/message" .Path }}layui-this{{end}}"><a href="/message">留言</a></li> <li class="layui-nav-item {{if equrl "/about" .Path }}layui-this{{end}} "><a href="/about">關於</a></li> </ul> <a href="#" class="personal pull-left"> <i class="layui-icon layui-icon-username"></i> </a> </div>.......
到此,頁面可以正常瀏覽了
咱們有沒有想過,如果可以亂問地址,頁面會這樣?答案是beego會提供一個預設錯誤的頁面返回。因此需要修改beego的預設錯誤介面。
beego 提供了分頁錯誤的檔案說明 地址
- 添加個controllers->error.go 檔案,定義ErrorController的控制器,裡面定義好Error404、Error501 方法。代碼如下
package controllerstype ErrorController struct { BaseController}func (c *ErrorController) Error404() { c.Data["content"] = "page not found" c.TplName = "error/404.html"}
- 接著就將ErrorController 注入到beego裡面,修改預設的錯誤處理頁面,修改方法是beego.ErrorController(錯誤的控制器),咱們來修改router.go 檔案,再init函數開始加入要修改代碼,代碼如下:
func init() { beego.ErrorController(&controllers.ErrorController{}) beego.Include(&controllers.IndexController{})}
golang文法: golang 引入包的地方 出現這個 _ "xxx", 表示調用 xxx包下的init方法。
mian.go為入口函數,沒有調用router.go的任意方法,但是注意引入包的地方 有 _ "github.com/jicg/liteblog/routers",就預設調用routers包下的init方法。
終於結束,項目已經整合完畢,但是資料是靜態,咱們的輕部落格的旅程才開始。下期咱們再見。