Fix failing build for a Chinese version because of template tags
This commit is contained in:
@@ -1,3 +1,4 @@
|
|||||||
|
{% raw %}
|
||||||
# 9.1 预防CSRF攻击
|
# 9.1 预防CSRF攻击
|
||||||
|
|
||||||
## 什么是CSRF
|
## 什么是CSRF
|
||||||
@@ -91,3 +92,4 @@ CSRF的防御可以从服务端和客户端两方面着手,防御效果是从
|
|||||||
* [目录](<preface.md>)
|
* [目录](<preface.md>)
|
||||||
* 上一节: [安全与加密](<09.0.md>)
|
* 上一节: [安全与加密](<09.0.md>)
|
||||||
* 下一节: [确保输入过滤](<09.2.md>)
|
* 下一节: [确保输入过滤](<09.2.md>)
|
||||||
|
{% endraw %}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
{% raw %}
|
||||||
# 10.2 本地化资源
|
# 10.2 本地化资源
|
||||||
前面小节我们介绍了如何设置Locale,设置好Locale之后我们需要解决的问题就是如何存储相应的Locale对应的信息呢?这里面的信息包括:文本信息、时间和日期、货币值、图片、包含文件以及视图等资源。那么接下来我们将对这些信息一一进行介绍,Go语言中我们把这些格式信息存储在JSON中,然后通过合适的方式展现出来。(接下来以中文和英文两种语言对比举例,存储格式文件en.json和zh-CN.json)
|
前面小节我们介绍了如何设置Locale,设置好Locale之后我们需要解决的问题就是如何存储相应的Locale对应的信息呢?这里面的信息包括:文本信息、时间和日期、货币值、图片、包含文件以及视图等资源。那么接下来我们将对这些信息一一进行介绍,Go语言中我们把这些格式信息存储在JSON中,然后通过合适的方式展现出来。(接下来以中文和英文两种语言对比举例,存储格式文件en.json和zh-CN.json)
|
||||||
## 本地化文本消息
|
## 本地化文本消息
|
||||||
@@ -132,3 +133,4 @@ $GOROOT/lib/time包中的timeinfo.zip含有locale对应的时区的定义,为
|
|||||||
* [目录](<preface.md>)
|
* [目录](<preface.md>)
|
||||||
* 上一节: [设置默认地区](<10.1.md>)
|
* 上一节: [设置默认地区](<10.1.md>)
|
||||||
* 下一节: [国际化站点](<10.3.md>)
|
* 下一节: [国际化站点](<10.3.md>)
|
||||||
|
{% endraw %}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
{% raw %}
|
||||||
# 10.3 国际化站点
|
# 10.3 国际化站点
|
||||||
前面小节介绍了如何处理本地化资源,即Locale一个相应的配置文件,那么如果处理多个的本地化资源呢?而对于一些我们经常用到的例如:简单的文本翻译、时间日期、数字等如果处理呢?本小节将一一解决这些问题。
|
前面小节介绍了如何处理本地化资源,即Locale一个相应的配置文件,那么如果处理多个的本地化资源呢?而对于一些我们经常用到的例如:简单的文本翻译、时间日期、数字等如果处理呢?本小节将一一解决这些问题。
|
||||||
## 管理多个本地包
|
## 管理多个本地包
|
||||||
@@ -178,3 +179,4 @@
|
|||||||
* [目录](<preface.md>)
|
* [目录](<preface.md>)
|
||||||
* 上一节: [本地化资源](<10.2.md>)
|
* 上一节: [本地化资源](<10.2.md>)
|
||||||
* 下一节: [小结](<10.4.md>)
|
* 下一节: [小结](<10.4.md>)
|
||||||
|
{% endraw %}
|
||||||
|
|||||||
18
zh/12.2.md
18
zh/12.2.md
@@ -1,8 +1,9 @@
|
|||||||
|
{% raw %}
|
||||||
# 12.2 网站错误处理
|
# 12.2 网站错误处理
|
||||||
我们的Web应用一旦上线之后,那么各种错误出现的概率都有,Web应用日常运行中可能出现多种错误,具体如下所示:
|
我们的Web应用一旦上线之后,那么各种错误出现的概率都有,Web应用日常运行中可能出现多种错误,具体如下所示:
|
||||||
|
|
||||||
- 数据库错误:指与访问数据库服务器或数据相关的错误。例如,以下可能出现的一些数据库错误。
|
- 数据库错误:指与访问数据库服务器或数据相关的错误。例如,以下可能出现的一些数据库错误。
|
||||||
|
|
||||||
- 连接错误:这一类错误可能是数据库服务器网络断开、用户名密码不正确、或者数据库不存在。
|
- 连接错误:这一类错误可能是数据库服务器网络断开、用户名密码不正确、或者数据库不存在。
|
||||||
- 查询错误:使用的SQL非法导致错误,这样子SQL错误如果程序经过严格的测试应该可以避免。
|
- 查询错误:使用的SQL非法导致错误,这样子SQL错误如果程序经过严格的测试应该可以避免。
|
||||||
- 数据错误:数据库中的约束冲突,例如一个唯一字段中插入一条重复主键的值就会报错,但是如果你的应用程序在上线之前经过了严格的测试也是可以避免这类问题。
|
- 数据错误:数据库中的约束冲突,例如一个唯一字段中插入一条重复主键的值就会报错,但是如果你的应用程序在上线之前经过了严格的测试也是可以避免这类问题。
|
||||||
@@ -27,9 +28,9 @@
|
|||||||
错误处理其实我们已经在十一章第一小节里面有过介绍如何设计错误处理,这里我们再从一个例子详细的讲解一下,如何来处理不同的错误:
|
错误处理其实我们已经在十一章第一小节里面有过介绍如何设计错误处理,这里我们再从一个例子详细的讲解一下,如何来处理不同的错误:
|
||||||
|
|
||||||
- 通知用户出现错误:
|
- 通知用户出现错误:
|
||||||
|
|
||||||
通知用户在访问页面的时候我们可以有两种错误:404.html和error.html,下面分别显示了错误页面的源码:
|
通知用户在访问页面的时候我们可以有两种错误:404.html和error.html,下面分别显示了错误页面的源码:
|
||||||
|
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||||
@@ -51,7 +52,7 @@
|
|||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
另一个源码:
|
另一个源码:
|
||||||
|
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||||
@@ -72,9 +73,9 @@
|
|||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
||||||
404的错误处理逻辑,如果是系统的错误也是类似的操作,同时我们看到在:
|
404的错误处理逻辑,如果是系统的错误也是类似的操作,同时我们看到在:
|
||||||
|
|
||||||
func (p *MyMux) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
func (p *MyMux) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
if r.URL.Path == "/" {
|
if r.URL.Path == "/" {
|
||||||
sayhelloName(w, r)
|
sayhelloName(w, r)
|
||||||
@@ -90,7 +91,7 @@
|
|||||||
ErrorInfo := "文件找不到" //获取当前用户信息
|
ErrorInfo := "文件找不到" //获取当前用户信息
|
||||||
t.Execute(w, ErrorInfo) //执行模板的merger操作
|
t.Execute(w, ErrorInfo) //执行模板的merger操作
|
||||||
}
|
}
|
||||||
|
|
||||||
func SystemError(w http.ResponseWriter, r *http.Request) {
|
func SystemError(w http.ResponseWriter, r *http.Request) {
|
||||||
log.Critical("系统错误") //系统错误触发了Critical,那么不仅会记录日志还会发送邮件
|
log.Critical("系统错误") //系统错误触发了Critical,那么不仅会记录日志还会发送邮件
|
||||||
t, _ = t.ParseFiles("tmpl/error.html", nil) //解析模板文件
|
t, _ = t.ParseFiles("tmpl/error.html", nil) //解析模板文件
|
||||||
@@ -109,7 +110,7 @@
|
|||||||
username = ""
|
username = ""
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
username = User[uid]
|
username = User[uid]
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -122,3 +123,4 @@
|
|||||||
* [目录](<preface.md>)
|
* [目录](<preface.md>)
|
||||||
* 上一章: [应用日志](<12.1.md>)
|
* 上一章: [应用日志](<12.1.md>)
|
||||||
* 下一节: [应用部署](<12.3.md>)
|
* 下一节: [应用部署](<12.3.md>)
|
||||||
|
{% endraw %}
|
||||||
|
|||||||
42
zh/13.3.md
42
zh/13.3.md
@@ -1,3 +1,4 @@
|
|||||||
|
{% raw %}
|
||||||
# 13.3 controller设计
|
# 13.3 controller设计
|
||||||
|
|
||||||
传统的MVC框架大多数是基于Action设计的后缀式映射,然而,现在Web流行REST风格的架构。尽管使用Filter或者rewrite能够通过URL重写实现REST风格的URL,但是为什么不直接设计一个全新的REST风格的 MVC框架呢?本小节就是基于这种思路来讲述如何从头设计一个基于REST风格的MVC框架中的controller,最大限度地简化Web应用的开发,甚至编写一行代码就可以实现“Hello, world”。
|
传统的MVC框架大多数是基于Action设计的后缀式映射,然而,现在Web流行REST风格的架构。尽管使用Filter或者rewrite能够通过URL重写实现REST风格的URL,但是为什么不直接设计一个全新的REST风格的 MVC框架呢?本小节就是基于这种思路来讲述如何从头设计一个基于REST风格的MVC框架中的controller,最大限度地简化Web应用的开发,甚至编写一行代码就可以实现“Hello, world”。
|
||||||
@@ -17,7 +18,7 @@ MVC设计模式是目前Web应用开发中最常见的架构模式,通过分
|
|||||||
Layout []string
|
Layout []string
|
||||||
TplExt string
|
TplExt string
|
||||||
}
|
}
|
||||||
|
|
||||||
type ControllerInterface interface {
|
type ControllerInterface interface {
|
||||||
Init(ct *Context, cn string) //初始化上下文和子类名称
|
Init(ct *Context, cn string) //初始化上下文和子类名称
|
||||||
Prepare() //开始执行之前的一些处理
|
Prepare() //开始执行之前的一些处理
|
||||||
@@ -31,7 +32,7 @@ MVC设计模式是目前Web应用开发中最常见的架构模式,通过分
|
|||||||
Finish() //执行完成之后的处理
|
Finish() //执行完成之后的处理
|
||||||
Render() error //执行完method对应的方法之后渲染页面
|
Render() error //执行完method对应的方法之后渲染页面
|
||||||
}
|
}
|
||||||
|
|
||||||
那么前面介绍的路由add函数的时候是定义了ControllerInterface类型,因此,只要我们实现这个接口就可以,所以我们的基类Controller实现如下的方法:
|
那么前面介绍的路由add函数的时候是定义了ControllerInterface类型,因此,只要我们实现这个接口就可以,所以我们的基类Controller实现如下的方法:
|
||||||
|
|
||||||
func (c *Controller) Init(ct *Context, cn string) {
|
func (c *Controller) Init(ct *Context, cn string) {
|
||||||
@@ -42,43 +43,43 @@ MVC设计模式是目前Web应用开发中最常见的架构模式,通过分
|
|||||||
c.Ct = ct
|
c.Ct = ct
|
||||||
c.TplExt = "tpl"
|
c.TplExt = "tpl"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Controller) Prepare() {
|
func (c *Controller) Prepare() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Controller) Finish() {
|
func (c *Controller) Finish() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Controller) Get() {
|
func (c *Controller) Get() {
|
||||||
http.Error(c.Ct.ResponseWriter, "Method Not Allowed", 405)
|
http.Error(c.Ct.ResponseWriter, "Method Not Allowed", 405)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Controller) Post() {
|
func (c *Controller) Post() {
|
||||||
http.Error(c.Ct.ResponseWriter, "Method Not Allowed", 405)
|
http.Error(c.Ct.ResponseWriter, "Method Not Allowed", 405)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Controller) Delete() {
|
func (c *Controller) Delete() {
|
||||||
http.Error(c.Ct.ResponseWriter, "Method Not Allowed", 405)
|
http.Error(c.Ct.ResponseWriter, "Method Not Allowed", 405)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Controller) Put() {
|
func (c *Controller) Put() {
|
||||||
http.Error(c.Ct.ResponseWriter, "Method Not Allowed", 405)
|
http.Error(c.Ct.ResponseWriter, "Method Not Allowed", 405)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Controller) Head() {
|
func (c *Controller) Head() {
|
||||||
http.Error(c.Ct.ResponseWriter, "Method Not Allowed", 405)
|
http.Error(c.Ct.ResponseWriter, "Method Not Allowed", 405)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Controller) Patch() {
|
func (c *Controller) Patch() {
|
||||||
http.Error(c.Ct.ResponseWriter, "Method Not Allowed", 405)
|
http.Error(c.Ct.ResponseWriter, "Method Not Allowed", 405)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Controller) Options() {
|
func (c *Controller) Options() {
|
||||||
http.Error(c.Ct.ResponseWriter, "Method Not Allowed", 405)
|
http.Error(c.Ct.ResponseWriter, "Method Not Allowed", 405)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Controller) Render() error {
|
func (c *Controller) Render() error {
|
||||||
if len(c.Layout) > 0 {
|
if len(c.Layout) > 0 {
|
||||||
var filenames []string
|
var filenames []string
|
||||||
@@ -108,10 +109,10 @@ MVC设计模式是目前Web应用开发中最常见的架构模式,通过分
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Controller) Redirect(url string, code int) {
|
func (c *Controller) Redirect(url string, code int) {
|
||||||
c.Ct.Redirect(code, url)
|
c.Ct.Redirect(code, url)
|
||||||
}
|
}
|
||||||
|
|
||||||
上面的controller基类已经实现了接口定义的函数,通过路由根据url执行相应的controller的原则,会依次执行如下:
|
上面的controller基类已经实现了接口定义的函数,通过路由根据url执行相应的controller的原则,会依次执行如下:
|
||||||
|
|
||||||
@@ -125,21 +126,21 @@ MVC设计模式是目前Web应用开发中最常见的架构模式,通过分
|
|||||||
上面beego框架中完成了controller基类的设计,那么我们在我们的应用中可以这样来设计我们的方法:
|
上面beego框架中完成了controller基类的设计,那么我们在我们的应用中可以这样来设计我们的方法:
|
||||||
|
|
||||||
package controllers
|
package controllers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/astaxie/beego"
|
"github.com/astaxie/beego"
|
||||||
)
|
)
|
||||||
|
|
||||||
type MainController struct {
|
type MainController struct {
|
||||||
beego.Controller
|
beego.Controller
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *MainController) Get() {
|
func (this *MainController) Get() {
|
||||||
this.Data["Username"] = "astaxie"
|
this.Data["Username"] = "astaxie"
|
||||||
this.Data["Email"] = "astaxie@gmail.com"
|
this.Data["Email"] = "astaxie@gmail.com"
|
||||||
this.TplNames = "index.tpl"
|
this.TplNames = "index.tpl"
|
||||||
}
|
}
|
||||||
|
|
||||||
上面的方式我们实现了子类MainController,实现了Get方法,那么如果用户通过其他的方式(POST/HEAD等)来访问该资源都将返回403,而如果是Get来访问,因为我们设置了AutoRender=true,那么在执行完Get方法之后会自动执行Render函数,就会显示如下界面:
|
上面的方式我们实现了子类MainController,实现了Get方法,那么如果用户通过其他的方式(POST/HEAD等)来访问该资源都将返回403,而如果是Get来访问,因为我们设置了AutoRender=true,那么在执行完Get方法之后会自动执行Render函数,就会显示如下界面:
|
||||||
|
|
||||||

|

|
||||||
@@ -161,3 +162,4 @@ index.tpl的代码如下所示,我们可以看到数据的设置和显示都
|
|||||||
* [目录](<preface.md>)
|
* [目录](<preface.md>)
|
||||||
* 上一章: [自定义路由器设计](<13.2.md>)
|
* 上一章: [自定义路由器设计](<13.2.md>)
|
||||||
* 下一节: [日志和配置设计](<13.4.md>)
|
* 下一节: [日志和配置设计](<13.4.md>)
|
||||||
|
{% endraw %}
|
||||||
|
|||||||
50
zh/13.5.md
50
zh/13.5.md
@@ -1,3 +1,4 @@
|
|||||||
|
{% raw %}
|
||||||
# 13.5 实现博客的增删改
|
# 13.5 实现博客的增删改
|
||||||
|
|
||||||
前面介绍了beego框架实现的整体构思以及部分实现的伪代码,这小节介绍通过beego建立一个博客系统,包括博客浏览、添加、修改、删除等操作。
|
前面介绍了beego框架实现的整体构思以及部分实现的伪代码,这小节介绍通过beego建立一个博客系统,包括博客浏览、添加、修改、删除等操作。
|
||||||
@@ -53,19 +54,19 @@ IndexController:
|
|||||||
type IndexController struct {
|
type IndexController struct {
|
||||||
beego.Controller
|
beego.Controller
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *IndexController) Get() {
|
func (this *IndexController) Get() {
|
||||||
this.Data["blogs"] = models.GetAll()
|
this.Data["blogs"] = models.GetAll()
|
||||||
this.Layout = "layout.tpl"
|
this.Layout = "layout.tpl"
|
||||||
this.TplNames = "index.tpl"
|
this.TplNames = "index.tpl"
|
||||||
}
|
}
|
||||||
|
|
||||||
ViewController:
|
ViewController:
|
||||||
|
|
||||||
type ViewController struct {
|
type ViewController struct {
|
||||||
beego.Controller
|
beego.Controller
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *ViewController) Get() {
|
func (this *ViewController) Get() {
|
||||||
id, _ := strconv.Atoi(this.Ctx.Input.Params[":id"])
|
id, _ := strconv.Atoi(this.Ctx.Input.Params[":id"])
|
||||||
this.Data["Post"] = models.GetBlog(id)
|
this.Data["Post"] = models.GetBlog(id)
|
||||||
@@ -78,12 +79,12 @@ NewController
|
|||||||
type NewController struct {
|
type NewController struct {
|
||||||
beego.Controller
|
beego.Controller
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *NewController) Get() {
|
func (this *NewController) Get() {
|
||||||
this.Layout = "layout.tpl"
|
this.Layout = "layout.tpl"
|
||||||
this.TplNames = "new.tpl"
|
this.TplNames = "new.tpl"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *NewController) Post() {
|
func (this *NewController) Post() {
|
||||||
inputs := this.Input()
|
inputs := this.Input()
|
||||||
var blog models.Blog
|
var blog models.Blog
|
||||||
@@ -99,14 +100,14 @@ EditController
|
|||||||
type EditController struct {
|
type EditController struct {
|
||||||
beego.Controller
|
beego.Controller
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *EditController) Get() {
|
func (this *EditController) Get() {
|
||||||
id, _ := strconv.Atoi(this.Ctx.Input.Params[":id"])
|
id, _ := strconv.Atoi(this.Ctx.Input.Params[":id"])
|
||||||
this.Data["Post"] = models.GetBlog(id)
|
this.Data["Post"] = models.GetBlog(id)
|
||||||
this.Layout = "layout.tpl"
|
this.Layout = "layout.tpl"
|
||||||
this.TplNames = "edit.tpl"
|
this.TplNames = "edit.tpl"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *EditController) Post() {
|
func (this *EditController) Post() {
|
||||||
inputs := this.Input()
|
inputs := this.Input()
|
||||||
var blog models.Blog
|
var blog models.Blog
|
||||||
@@ -117,39 +118,39 @@ EditController
|
|||||||
models.SaveBlog(blog)
|
models.SaveBlog(blog)
|
||||||
this.Ctx.Redirect(302, "/")
|
this.Ctx.Redirect(302, "/")
|
||||||
}
|
}
|
||||||
|
|
||||||
DeleteController
|
DeleteController
|
||||||
|
|
||||||
type DeleteController struct {
|
type DeleteController struct {
|
||||||
beego.Controller
|
beego.Controller
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *DeleteController) Get() {
|
func (this *DeleteController) Get() {
|
||||||
id, _ := strconv.Atoi(this.Ctx.Input.Params[":id"])
|
id, _ := strconv.Atoi(this.Ctx.Input.Params[":id"])
|
||||||
blog := models.GetBlog(id)
|
blog := models.GetBlog(id)
|
||||||
this.Data["Post"] = blog
|
this.Data["Post"] = blog
|
||||||
models.DelBlog(blog)
|
models.DelBlog(blog)
|
||||||
this.Ctx.Redirect(302, "/")
|
this.Ctx.Redirect(302, "/")
|
||||||
}
|
}
|
||||||
|
|
||||||
## model层
|
## model层
|
||||||
|
|
||||||
package models
|
package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"github.com/astaxie/beedb"
|
"github.com/astaxie/beedb"
|
||||||
_ "github.com/ziutek/mymysql/godrv"
|
_ "github.com/ziutek/mymysql/godrv"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Blog struct {
|
type Blog struct {
|
||||||
Id int `PK`
|
Id int `PK`
|
||||||
Title string
|
Title string
|
||||||
Content string
|
Content string
|
||||||
Created time.Time
|
Created time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetLink() beedb.Model {
|
func GetLink() beedb.Model {
|
||||||
db, err := sql.Open("mymysql", "blog/astaxie/123456")
|
db, err := sql.Open("mymysql", "blog/astaxie/123456")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -158,25 +159,25 @@ DeleteController
|
|||||||
orm := beedb.New(db)
|
orm := beedb.New(db)
|
||||||
return orm
|
return orm
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetAll() (blogs []Blog) {
|
func GetAll() (blogs []Blog) {
|
||||||
db := GetLink()
|
db := GetLink()
|
||||||
db.FindAll(&blogs)
|
db.FindAll(&blogs)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetBlog(id int) (blog Blog) {
|
func GetBlog(id int) (blog Blog) {
|
||||||
db := GetLink()
|
db := GetLink()
|
||||||
db.Where("id=?", id).Find(&blog)
|
db.Where("id=?", id).Find(&blog)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func SaveBlog(blog Blog) (bg Blog) {
|
func SaveBlog(blog Blog) (bg Blog) {
|
||||||
db := GetLink()
|
db := GetLink()
|
||||||
db.Save(&blog)
|
db.Save(&blog)
|
||||||
return bg
|
return bg
|
||||||
}
|
}
|
||||||
|
|
||||||
func DelBlog(blog Blog) {
|
func DelBlog(blog Blog) {
|
||||||
db := GetLink()
|
db := GetLink()
|
||||||
db.Delete(&blog)
|
db.Delete(&blog)
|
||||||
@@ -199,17 +200,17 @@ layout.tpl
|
|||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<ul id="menu">
|
<ul id="menu">
|
||||||
<li><a href="/">Home</a></li>
|
<li><a href="/">Home</a></li>
|
||||||
<li><a href="/new">New Post</a></li>
|
<li><a href="/new">New Post</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
{{.LayoutContent}}
|
{{.LayoutContent}}
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
||||||
index.tpl
|
index.tpl
|
||||||
|
|
||||||
<h1>Blog posts</h1>
|
<h1>Blog posts</h1>
|
||||||
@@ -217,7 +218,7 @@ index.tpl
|
|||||||
<ul>
|
<ul>
|
||||||
{{range .blogs}}
|
{{range .blogs}}
|
||||||
<li>
|
<li>
|
||||||
<a href="/view/{{.Id}}">{{.Title}}</a>
|
<a href="/view/{{.Id}}">{{.Title}}</a>
|
||||||
from {{.Created}}
|
from {{.Created}}
|
||||||
<a href="/edit/{{.Id}}">Edit</a>
|
<a href="/edit/{{.Id}}">Edit</a>
|
||||||
<a href="/delete/{{.Id}}">Delete</a>
|
<a href="/delete/{{.Id}}">Delete</a>
|
||||||
@@ -229,7 +230,7 @@ view.tpl
|
|||||||
|
|
||||||
<h1>{{.Post.Title}}</h1>
|
<h1>{{.Post.Title}}</h1>
|
||||||
{{.Post.Created}}<br/>
|
{{.Post.Created}}<br/>
|
||||||
|
|
||||||
{{.Post.Content}}
|
{{.Post.Content}}
|
||||||
|
|
||||||
new.tpl
|
new.tpl
|
||||||
@@ -242,7 +243,7 @@ new.tpl
|
|||||||
</form>
|
</form>
|
||||||
|
|
||||||
edit.tpl
|
edit.tpl
|
||||||
|
|
||||||
<h1>Edit {{.Post.Title}}</h1>
|
<h1>Edit {{.Post.Title}}</h1>
|
||||||
|
|
||||||
<h1>New Blog Post</h1>
|
<h1>New Blog Post</h1>
|
||||||
@@ -257,3 +258,4 @@ edit.tpl
|
|||||||
* [目录](<preface.md>)
|
* [目录](<preface.md>)
|
||||||
* 上一章: [日志和配置设计](<13.4.md>)
|
* 上一章: [日志和配置设计](<13.4.md>)
|
||||||
* 下一节: [小结](<13.6.md>)
|
* 下一节: [小结](<13.6.md>)
|
||||||
|
{% endraw %}
|
||||||
|
|||||||
16
zh/14.3.md
16
zh/14.3.md
@@ -1,3 +1,4 @@
|
|||||||
|
{% raw %}
|
||||||
# 14.3 表单及验证支持
|
# 14.3 表单及验证支持
|
||||||
在Web开发中对于这样的一个流程可能很眼熟:
|
在Web开发中对于这样的一个流程可能很眼熟:
|
||||||
|
|
||||||
@@ -28,7 +29,7 @@
|
|||||||
Email string `form:text,valid:required|valid_email`
|
Email string `form:text,valid:required|valid_email`
|
||||||
Introduce string `form:textarea`
|
Introduce string `form:textarea`
|
||||||
}
|
}
|
||||||
|
|
||||||
定义好struct之后接下来在controller中这样操作
|
定义好struct之后接下来在controller中这样操作
|
||||||
|
|
||||||
func (this *AddController) Get() {
|
func (this *AddController) Get() {
|
||||||
@@ -36,26 +37,26 @@
|
|||||||
this.Layout = "admin/layout.html"
|
this.Layout = "admin/layout.html"
|
||||||
this.TplNames = "admin/add.tpl"
|
this.TplNames = "admin/add.tpl"
|
||||||
}
|
}
|
||||||
|
|
||||||
在模板中这样显示表单
|
在模板中这样显示表单
|
||||||
|
|
||||||
<h1>New Blog Post</h1>
|
<h1>New Blog Post</h1>
|
||||||
<form action="" method="post">
|
<form action="" method="post">
|
||||||
{{.form.render()}}
|
{{.form.render()}}
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
上面我们定义好了整个的第一步,从struct到显示表单的过程,接下来就是用户填写信息,服务器端接收数据然后验证,最后插入数据库。
|
上面我们定义好了整个的第一步,从struct到显示表单的过程,接下来就是用户填写信息,服务器端接收数据然后验证,最后插入数据库。
|
||||||
|
|
||||||
func (this *AddController) Post() {
|
func (this *AddController) Post() {
|
||||||
var user User
|
var user User
|
||||||
form := this.GetInput(&user)
|
form := this.GetInput(&user)
|
||||||
if !form.Validates() {
|
if !form.Validates() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
models.UserInsert(&user)
|
models.UserInsert(&user)
|
||||||
this.Ctx.Redirect(302, "/admin/index")
|
this.Ctx.Redirect(302, "/admin/index")
|
||||||
}
|
}
|
||||||
|
|
||||||
## 表单类型
|
## 表单类型
|
||||||
以下列表列出来了对应的form元素信息:
|
以下列表列出来了对应的form元素信息:
|
||||||
<table cellpadding="0" cellspacing="1" border="0" style="width:100%" class="tableborder">
|
<table cellpadding="0" cellspacing="1" border="0" style="width:100%" class="tableborder">
|
||||||
@@ -121,7 +122,7 @@
|
|||||||
|
|
||||||
</tbody></table>
|
</tbody></table>
|
||||||
|
|
||||||
|
|
||||||
## 表单验证
|
## 表单验证
|
||||||
以下列表将列出可被使用的原生规则
|
以下列表将列出可被使用的原生规则
|
||||||
<table cellpadding="0" cellspacing="1" border="0" style="width:100%" class="tableborder">
|
<table cellpadding="0" cellspacing="1" border="0" style="width:100%" class="tableborder">
|
||||||
@@ -278,4 +279,5 @@
|
|||||||
## links
|
## links
|
||||||
* [目录](<preface.md>)
|
* [目录](<preface.md>)
|
||||||
* 上一节: [Session支持](<14.2.md>)
|
* 上一节: [Session支持](<14.2.md>)
|
||||||
* 下一节: [用户认证](<14.4.md>)
|
* 下一节: [用户认证](<14.4.md>)
|
||||||
|
{% endraw %}
|
||||||
|
|||||||
38
zh/14.5.md
38
zh/14.5.md
@@ -1,3 +1,4 @@
|
|||||||
|
{% raw %}
|
||||||
# 14.5 多语言支持
|
# 14.5 多语言支持
|
||||||
我们在第十章介绍过国际化和本地化,开发了一个go-i18n库,这小节我们将把该库集成到beego框架里面来,使得我们的框架支持国际化和本地化。
|
我们在第十章介绍过国际化和本地化,开发了一个go-i18n库,这小节我们将把该库集成到beego框架里面来,使得我们的框架支持国际化和本地化。
|
||||||
|
|
||||||
@@ -21,7 +22,7 @@ beego中设置全局变量如下:
|
|||||||
beegoTplFuncMap["Trans"] = i18n.I18nT
|
beegoTplFuncMap["Trans"] = i18n.I18nT
|
||||||
beegoTplFuncMap["TransDate"] = i18n.I18nTimeDate
|
beegoTplFuncMap["TransDate"] = i18n.I18nTimeDate
|
||||||
beegoTplFuncMap["TransMoney"] = i18n.I18nMoney
|
beegoTplFuncMap["TransMoney"] = i18n.I18nMoney
|
||||||
|
|
||||||
func I18nT(args ...interface{}) string {
|
func I18nT(args ...interface{}) string {
|
||||||
ok := false
|
ok := false
|
||||||
var s string
|
var s string
|
||||||
@@ -33,7 +34,7 @@ beego中设置全局变量如下:
|
|||||||
}
|
}
|
||||||
return beego.Translation.Translate(s)
|
return beego.Translation.Translate(s)
|
||||||
}
|
}
|
||||||
|
|
||||||
func I18nTimeDate(args ...interface{}) string {
|
func I18nTimeDate(args ...interface{}) string {
|
||||||
ok := false
|
ok := false
|
||||||
var s string
|
var s string
|
||||||
@@ -44,8 +45,8 @@ beego中设置全局变量如下:
|
|||||||
s = fmt.Sprint(args...)
|
s = fmt.Sprint(args...)
|
||||||
}
|
}
|
||||||
return beego.Translation.Time(s)
|
return beego.Translation.Time(s)
|
||||||
}
|
}
|
||||||
|
|
||||||
func I18nMoney(args ...interface{}) string {
|
func I18nMoney(args ...interface{}) string {
|
||||||
ok := false
|
ok := false
|
||||||
var s string
|
var s string
|
||||||
@@ -60,7 +61,7 @@ beego中设置全局变量如下:
|
|||||||
|
|
||||||
## 多语言开发使用
|
## 多语言开发使用
|
||||||
1. 设置语言以及语言包所在位置,然后初始化i18n对象:
|
1. 设置语言以及语言包所在位置,然后初始化i18n对象:
|
||||||
|
|
||||||
beego.Lang = "zh"
|
beego.Lang = "zh"
|
||||||
beego.LangPath = "views/lang"
|
beego.LangPath = "views/lang"
|
||||||
beego.InitLang()
|
beego.InitLang()
|
||||||
@@ -68,18 +69,18 @@ beego中设置全局变量如下:
|
|||||||
2. 设计多语言包
|
2. 设计多语言包
|
||||||
|
|
||||||
上面讲了如何初始化多语言包,现在设计多语言包,多语言包是json文件,如第十章介绍的一样,我们需要把设计的文件放在LangPath下面,例如zh.json或者en.json
|
上面讲了如何初始化多语言包,现在设计多语言包,多语言包是json文件,如第十章介绍的一样,我们需要把设计的文件放在LangPath下面,例如zh.json或者en.json
|
||||||
|
|
||||||
# zh.json
|
# zh.json
|
||||||
|
|
||||||
{
|
{
|
||||||
"zh": {
|
"zh": {
|
||||||
"submit": "提交",
|
"submit": "提交",
|
||||||
"create": "创建"
|
"create": "创建"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#en.json
|
#en.json
|
||||||
|
|
||||||
{
|
{
|
||||||
"en": {
|
"en": {
|
||||||
"submit": "Submit",
|
"submit": "Submit",
|
||||||
@@ -90,24 +91,25 @@ beego中设置全局变量如下:
|
|||||||
3. 使用语言包
|
3. 使用语言包
|
||||||
|
|
||||||
我们可以在controller中调用翻译获取响应的翻译语言,如下所示:
|
我们可以在controller中调用翻译获取响应的翻译语言,如下所示:
|
||||||
|
|
||||||
func (this *MainController) Get() {
|
func (this *MainController) Get() {
|
||||||
this.Data["create"] = beego.Translation.Translate("create")
|
this.Data["create"] = beego.Translation.Translate("create")
|
||||||
this.TplNames = "index.tpl"
|
this.TplNames = "index.tpl"
|
||||||
}
|
}
|
||||||
|
|
||||||
我们也可以在模板中直接调用响应的翻译函数:
|
我们也可以在模板中直接调用响应的翻译函数:
|
||||||
|
|
||||||
//直接文本翻译
|
//直接文本翻译
|
||||||
{{.create | Trans}}
|
{{.create | Trans}}
|
||||||
|
|
||||||
//时间翻译
|
//时间翻译
|
||||||
{{.time | TransDate}}
|
{{.time | TransDate}}
|
||||||
|
|
||||||
//货币翻译
|
//货币翻译
|
||||||
{{.money | TransMoney}}
|
{{.money | TransMoney}}
|
||||||
|
|
||||||
## links
|
## links
|
||||||
* [目录](<preface.md>)
|
* [目录](<preface.md>)
|
||||||
* 上一节: [用户认证](<14.4.md>)
|
* 上一节: [用户认证](<14.4.md>)
|
||||||
* 下一节: [pprof支持](<14.6.md>)
|
* 下一节: [pprof支持](<14.6.md>)
|
||||||
|
{% endraw %}
|
||||||
|
|||||||
Reference in New Issue
Block a user