Beego-开发轻博客(二)

Beego 添加路由功能

   beego 添加路由功能通过修改 routers->router.go 文件来实现,beego 实现路由的方式有多种,参考文档:

https://beego.me/docs/mvc/controller/router.md,在这里我们使用注解路由

    beego 的控制器有很多种方法,其中包括 Init、Prepare等方法。其中 Prepare 方法是每次请求都会调用的方法,看源

码如下:

// Prepare runs after Init before request function execution.
func (c *Controller) Prepare() {}

  这个方法是一个空方法,我们需要创建一个基类重写 Prepare 方法

   1.首先创建一个 controllers->base.go ,新增结构体 BaseController 继承 beego.Controller ,为 BaseController 添加

Prepare 方法,所有继承了 BaseController 的字 controller 每次请求都会调用 Prepare 方法,在这里我们约定所有的子

controller 都会继承 BaseController ,可以将每次请求的通用逻辑写在 BaseController 的 Prepare 方法里

    2.如果子 controller 里面的所有方法除了调用 BaseController 里面的 PrePare 方法的通用逻辑外,还有一些当前子 con

troller 的通用逻辑怎么办?难道当前子 controller 的每个方法都要重写一遍吗?我们可以在 BaseController 里面定义个接口

,然后在 BaseController 里面的 Prepare 方法判断子  controller 是否实现了接口,如果实现了就调用接口方法

package controllers

import (
	"github.com/astaxie/beego"
	"log"
)

// 约定: 如果子 controller 存在 NestPrepare 方法,就实现了该接口
type NestPrepare interface {
	NestPrepare()
}

type BaseController struct {
	beego.Controller
}

// 重写 Prepare 方法
func (ctx *BaseController) Prepare()  {
	log.Println("BaseController")

	// 判断子 controller 是否实现了 NestPrepare 接口,如果实现了就调用接口方法
	if app,ok := ctx.AppController.(NestPrepare);ok{
		app.NestPrepare()
	}
}

  3.上面定义了基础控制器 BaseController ,下面新增一个 controllers->index.go 文件,定义 IndexController 文件如下:

package controllers

type 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"
}

  4.上面定义了 3 个路由以及对应的处理方法,下面我们 routers->router.go 调整一下才能生效

package routers

import (
	"github.com/astaxie/beego"
	"liteblog/controllers"
)

func init() {
    // 注解路由
    beego.Include(&controllers.IndexController{})
}

 5.在上我们已经把路由定义好了,我们现在来调整一下前端代码

      5.1修改 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.html">关于</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>

  5.2 调整 layui-this 属性

<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.html">关于</a></li>
            </ul>
            <a href="#" class="personal pull-left">
                <i class="layui-icon layui-icon-username"></i>
            </a>
</div>

  上面这段代码,我们发现 layui-this 属性被写死了,这个属性应该根据当前的页面选择对应的 li,那么这就需要拿到

当前页面的路径,还要有方法去判断路径是否相同

         5.2.1 获取当前页面的路径,属于通用功能,需要写在 BaseController 的 Prepare 方法,添加变量的输出

func (ctx *BaseController) Prepare()  {
	// 将当前页面的路径保存到 Path 变量里面
	ctx.Data["Path"] = ctx.Ctx.Request.RequestURI

	// 判断子 controller 是否实现了 NestPrepare 接口,如果实现了就调用接口方法
	if app,ok := ctx.AppController.(NestPrepare);ok{
		app.NestPrepare()
	}
}

  5.2.2 beego 模板自定义

       beego 中模板渲染可以自定义方法,模板自定义方法,定义的方式为:

beego.AddFuncMap("模板中调用的方法名",具体函数)

  我们现在自定义一个 equrl 模板方法,用来判断路径是否相同,写在 main.go 中:

package main

import (
	_ "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
	})
}

  5.2.3 修改views->comm->header.html 里面的代码,加上路径比较的逻辑

<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.html">关于</a></li>
</ul>

 6.错误页面处理

       如果我们访问的地址不存在,页面会怎么样?beego 提供了一个默认的错误页面,一般我们需要根据项目的需求定制一个

符合自己的错误页面,因此需要修改 beego 的默认错误页面

       6.1 添加个controllers->error.go 文件,定义  ErrorController 的控制器,里面定义好 Error404 方法,代码如下:

package controllers

type ErrorController struct {
	BaseController
}

func (c *ErrorController) Error404()  {
	c.Data["content"] = "page not found"
	c.TplName = "404.html"
}

  6.2接着将 ErrorController 注入到 beego 里面,修改默认的错误页面处理,修改方法是 beego.ErrorController (错误控制器),

修改 router.go 文件,代码如下:

func init()  {
	// 注解路由 需要调用 Include
	beego.ErrorController(&controllers.ErrorController{})
	beego.Include(&controllers.IndexController{})
}

  注意:golang 引入包的地方出现 "_" 表示调用 xxx 包下的 init 方法,main.go 为入口函数,没有调用 router.go 的任意函数,但是

注意引入包的地方有 _ "liteblog/routers" ,就默认调用 rotuters 包下的 init 方法

猜你喜欢

转载自www.cnblogs.com/leeyongbard/p/10445527.html
今日推荐