Fix failing build for a Chinese version because of template tags

This commit is contained in:
Denis Koltsov
2016-11-19 16:40:48 +01:00
parent 1b85586e22
commit 1e5131b5c7
8 changed files with 93 additions and 77 deletions

View File

@@ -1,3 +1,4 @@
{% raw %}
# 9.1 预防CSRF攻击
## 什么是CSRF
@@ -91,3 +92,4 @@ CSRF的防御可以从服务端和客户端两方面着手防御效果是从
* [目录](<preface.md>)
* 上一节: [安全与加密](<09.0.md>)
* 下一节: [确保输入过滤](<09.2.md>)
{% endraw %}

View File

@@ -1,3 +1,4 @@
{% raw %}
# 10.2 本地化资源
前面小节我们介绍了如何设置Locale设置好Locale之后我们需要解决的问题就是如何存储相应的Locale对应的信息呢这里面的信息包括文本信息、时间和日期、货币值、图片、包含文件以及视图等资源。那么接下来我们将对这些信息一一进行介绍Go语言中我们把这些格式信息存储在JSON中然后通过合适的方式展现出来。(接下来以中文和英文两种语言对比举例,存储格式文件en.json和zh-CN.json)
## 本地化文本消息
@@ -132,3 +133,4 @@ $GOROOT/lib/time包中的timeinfo.zip含有locale对应的时区的定义
* [目录](<preface.md>)
* 上一节: [设置默认地区](<10.1.md>)
* 下一节: [国际化站点](<10.3.md>)
{% endraw %}

View File

@@ -1,3 +1,4 @@
{% raw %}
# 10.3 国际化站点
前面小节介绍了如何处理本地化资源即Locale一个相应的配置文件那么如果处理多个的本地化资源呢而对于一些我们经常用到的例如简单的文本翻译、时间日期、数字等如果处理呢本小节将一一解决这些问题。
## 管理多个本地包
@@ -178,3 +179,4 @@
* [目录](<preface.md>)
* 上一节: [本地化资源](<10.2.md>)
* 下一节: [小结](<10.4.md>)
{% endraw %}

View File

@@ -1,8 +1,9 @@
{% raw %}
# 12.2 网站错误处理
我们的Web应用一旦上线之后那么各种错误出现的概率都有Web应用日常运行中可能出现多种错误具体如下所示
- 数据库错误:指与访问数据库服务器或数据相关的错误。例如,以下可能出现的一些数据库错误。
- 连接错误:这一类错误可能是数据库服务器网络断开、用户名密码不正确、或者数据库不存在。
- 查询错误使用的SQL非法导致错误这样子SQL错误如果程序经过严格的测试应该可以避免。
- 数据错误:数据库中的约束冲突,例如一个唯一字段中插入一条重复主键的值就会报错,但是如果你的应用程序在上线之前经过了严格的测试也是可以避免这类问题。
@@ -27,9 +28,9 @@
错误处理其实我们已经在十一章第一小节里面有过介绍如何设计错误处理,这里我们再从一个例子详细的讲解一下,如何来处理不同的错误:
- 通知用户出现错误:
通知用户在访问页面的时候我们可以有两种错误404.html和error.html下面分别显示了错误页面的源码
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
@@ -51,7 +52,7 @@
</body>
</html>
另一个源码:
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
@@ -72,9 +73,9 @@
</div>
</body>
</html>
404的错误处理逻辑如果是系统的错误也是类似的操作同时我们看到在
func (p *MyMux) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if r.URL.Path == "/" {
sayhelloName(w, r)
@@ -90,7 +91,7 @@
ErrorInfo := "文件找不到" //获取当前用户信息
t.Execute(w, ErrorInfo) //执行模板的merger操作
}
func SystemError(w http.ResponseWriter, r *http.Request) {
log.Critical("系统错误") //系统错误触发了Critical那么不仅会记录日志还会发送邮件
t, _ = t.ParseFiles("tmpl/error.html", nil) //解析模板文件
@@ -109,7 +110,7 @@
username = ""
}
}()
username = User[uid]
return
}
@@ -122,3 +123,4 @@
* [目录](<preface.md>)
* 上一章: [应用日志](<12.1.md>)
* 下一节: [应用部署](<12.3.md>)
{% endraw %}

View File

@@ -1,3 +1,4 @@
{% raw %}
# 13.3 controller设计
传统的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
TplExt string
}
type ControllerInterface interface {
Init(ct *Context, cn string) //初始化上下文和子类名称
Prepare() //开始执行之前的一些处理
@@ -31,7 +32,7 @@ MVC设计模式是目前Web应用开发中最常见的架构模式通过分
Finish() //执行完成之后的处理
Render() error //执行完method对应的方法之后渲染页面
}
那么前面介绍的路由add函数的时候是定义了ControllerInterface类型因此只要我们实现这个接口就可以所以我们的基类Controller实现如下的方法
func (c *Controller) Init(ct *Context, cn string) {
@@ -42,43 +43,43 @@ MVC设计模式是目前Web应用开发中最常见的架构模式通过分
c.Ct = ct
c.TplExt = "tpl"
}
func (c *Controller) Prepare() {
}
func (c *Controller) Finish() {
}
func (c *Controller) Get() {
http.Error(c.Ct.ResponseWriter, "Method Not Allowed", 405)
}
func (c *Controller) Post() {
http.Error(c.Ct.ResponseWriter, "Method Not Allowed", 405)
}
func (c *Controller) Delete() {
http.Error(c.Ct.ResponseWriter, "Method Not Allowed", 405)
}
func (c *Controller) Put() {
http.Error(c.Ct.ResponseWriter, "Method Not Allowed", 405)
}
func (c *Controller) Head() {
http.Error(c.Ct.ResponseWriter, "Method Not Allowed", 405)
}
func (c *Controller) Patch() {
http.Error(c.Ct.ResponseWriter, "Method Not Allowed", 405)
}
func (c *Controller) Options() {
http.Error(c.Ct.ResponseWriter, "Method Not Allowed", 405)
}
func (c *Controller) Render() error {
if len(c.Layout) > 0 {
var filenames []string
@@ -108,10 +109,10 @@ MVC设计模式是目前Web应用开发中最常见的架构模式通过分
}
return nil
}
func (c *Controller) Redirect(url string, code int) {
c.Ct.Redirect(code, url)
}
}
上面的controller基类已经实现了接口定义的函数通过路由根据url执行相应的controller的原则会依次执行如下
@@ -125,21 +126,21 @@ MVC设计模式是目前Web应用开发中最常见的架构模式通过分
上面beego框架中完成了controller基类的设计那么我们在我们的应用中可以这样来设计我们的方法
package controllers
import (
"github.com/astaxie/beego"
)
type MainController struct {
beego.Controller
}
func (this *MainController) Get() {
this.Data["Username"] = "astaxie"
this.Data["Email"] = "astaxie@gmail.com"
this.TplNames = "index.tpl"
}
上面的方式我们实现了子类MainController实现了Get方法那么如果用户通过其他的方式(POST/HEAD等)来访问该资源都将返回403而如果是Get来访问因为我们设置了AutoRender=true那么在执行完Get方法之后会自动执行Render函数就会显示如下界面
![](images/13.4.beego.png?raw=true)
@@ -161,3 +162,4 @@ index.tpl的代码如下所示我们可以看到数据的设置和显示都
* [目录](<preface.md>)
* 上一章: [自定义路由器设计](<13.2.md>)
* 下一节: [日志和配置设计](<13.4.md>)
{% endraw %}

View File

@@ -1,3 +1,4 @@
{% raw %}
# 13.5 实现博客的增删改
前面介绍了beego框架实现的整体构思以及部分实现的伪代码这小节介绍通过beego建立一个博客系统包括博客浏览、添加、修改、删除等操作。
@@ -53,19 +54,19 @@ IndexController:
type IndexController struct {
beego.Controller
}
func (this *IndexController) Get() {
this.Data["blogs"] = models.GetAll()
this.Layout = "layout.tpl"
this.TplNames = "index.tpl"
}
ViewController:
type ViewController struct {
beego.Controller
}
func (this *ViewController) Get() {
id, _ := strconv.Atoi(this.Ctx.Input.Params[":id"])
this.Data["Post"] = models.GetBlog(id)
@@ -78,12 +79,12 @@ NewController
type NewController struct {
beego.Controller
}
func (this *NewController) Get() {
this.Layout = "layout.tpl"
this.TplNames = "new.tpl"
}
func (this *NewController) Post() {
inputs := this.Input()
var blog models.Blog
@@ -99,14 +100,14 @@ EditController
type EditController struct {
beego.Controller
}
func (this *EditController) Get() {
id, _ := strconv.Atoi(this.Ctx.Input.Params[":id"])
this.Data["Post"] = models.GetBlog(id)
this.Layout = "layout.tpl"
this.TplNames = "edit.tpl"
}
func (this *EditController) Post() {
inputs := this.Input()
var blog models.Blog
@@ -117,39 +118,39 @@ EditController
models.SaveBlog(blog)
this.Ctx.Redirect(302, "/")
}
DeleteController
type DeleteController struct {
beego.Controller
}
func (this *DeleteController) Get() {
id, _ := strconv.Atoi(this.Ctx.Input.Params[":id"])
blog := models.GetBlog(id)
this.Data["Post"] = blog
models.DelBlog(blog)
this.Ctx.Redirect(302, "/")
}
}
## model层
package models
import (
"database/sql"
"github.com/astaxie/beedb"
_ "github.com/ziutek/mymysql/godrv"
"time"
)
type Blog struct {
Id int `PK`
Title string
Content string
Created time.Time
}
func GetLink() beedb.Model {
db, err := sql.Open("mymysql", "blog/astaxie/123456")
if err != nil {
@@ -158,25 +159,25 @@ DeleteController
orm := beedb.New(db)
return orm
}
func GetAll() (blogs []Blog) {
db := GetLink()
db.FindAll(&blogs)
return
}
func GetBlog(id int) (blog Blog) {
db := GetLink()
db.Where("id=?", id).Find(&blog)
return
}
func SaveBlog(blog Blog) (bg Blog) {
db := GetLink()
db.Save(&blog)
return bg
}
func DelBlog(blog Blog) {
db := GetLink()
db.Delete(&blog)
@@ -199,17 +200,17 @@ layout.tpl
</style>
</head>
<body>
<ul id="menu">
<li><a href="/">Home</a></li>
<li><a href="/new">New Post</a></li>
</ul>
{{.LayoutContent}}
</body>
</html>
index.tpl
<h1>Blog posts</h1>
@@ -217,7 +218,7 @@ index.tpl
<ul>
{{range .blogs}}
<li>
<a href="/view/{{.Id}}">{{.Title}}</a>
<a href="/view/{{.Id}}">{{.Title}}</a>
from {{.Created}}
<a href="/edit/{{.Id}}">Edit</a>
<a href="/delete/{{.Id}}">Delete</a>
@@ -229,7 +230,7 @@ view.tpl
<h1>{{.Post.Title}}</h1>
{{.Post.Created}}<br/>
{{.Post.Content}}
new.tpl
@@ -242,7 +243,7 @@ new.tpl
</form>
edit.tpl
<h1>Edit {{.Post.Title}}</h1>
<h1>New Blog Post</h1>
@@ -257,3 +258,4 @@ edit.tpl
* [目录](<preface.md>)
* 上一章: [日志和配置设计](<13.4.md>)
* 下一节: [小结](<13.6.md>)
{% endraw %}

View File

@@ -1,3 +1,4 @@
{% raw %}
# 14.3 表单及验证支持
在Web开发中对于这样的一个流程可能很眼熟
@@ -28,7 +29,7 @@
Email string `form:text,valid:required|valid_email`
Introduce string `form:textarea`
}
定义好struct之后接下来在controller中这样操作
func (this *AddController) Get() {
@@ -36,26 +37,26 @@
this.Layout = "admin/layout.html"
this.TplNames = "admin/add.tpl"
}
在模板中这样显示表单
<h1>New Blog Post</h1>
<form action="" method="post">
{{.form.render()}}
</form>
上面我们定义好了整个的第一步从struct到显示表单的过程接下来就是用户填写信息服务器端接收数据然后验证最后插入数据库。
func (this *AddController) Post() {
var user User
form := this.GetInput(&user)
if !form.Validates() {
return
return
}
models.UserInsert(&user)
this.Ctx.Redirect(302, "/admin/index")
}
## 表单类型
以下列表列出来了对应的form元素信息
<table cellpadding="0" cellspacing="1" border="0" style="width:100%" class="tableborder">
@@ -121,7 +122,7 @@
</tbody></table>
## 表单验证
以下列表将列出可被使用的原生规则
<table cellpadding="0" cellspacing="1" border="0" style="width:100%" class="tableborder">
@@ -278,4 +279,5 @@
## links
* [目录](<preface.md>)
* 上一节: [Session支持](<14.2.md>)
* 下一节: [用户认证](<14.4.md>)
* 下一节: [用户认证](<14.4.md>)
{% endraw %}

View File

@@ -1,3 +1,4 @@
{% raw %}
# 14.5 多语言支持
我们在第十章介绍过国际化和本地化开发了一个go-i18n库这小节我们将把该库集成到beego框架里面来使得我们的框架支持国际化和本地化。
@@ -21,7 +22,7 @@ beego中设置全局变量如下
beegoTplFuncMap["Trans"] = i18n.I18nT
beegoTplFuncMap["TransDate"] = i18n.I18nTimeDate
beegoTplFuncMap["TransMoney"] = i18n.I18nMoney
func I18nT(args ...interface{}) string {
ok := false
var s string
@@ -33,7 +34,7 @@ beego中设置全局变量如下
}
return beego.Translation.Translate(s)
}
func I18nTimeDate(args ...interface{}) string {
ok := false
var s string
@@ -44,8 +45,8 @@ beego中设置全局变量如下
s = fmt.Sprint(args...)
}
return beego.Translation.Time(s)
}
}
func I18nMoney(args ...interface{}) string {
ok := false
var s string
@@ -60,7 +61,7 @@ beego中设置全局变量如下
## 多语言开发使用
1. 设置语言以及语言包所在位置然后初始化i18n对象
beego.Lang = "zh"
beego.LangPath = "views/lang"
beego.InitLang()
@@ -68,18 +69,18 @@ beego中设置全局变量如下
2. 设计多语言包
上面讲了如何初始化多语言包现在设计多语言包多语言包是json文件如第十章介绍的一样我们需要把设计的文件放在LangPath下面例如zh.json或者en.json
# zh.json
{
"zh": {
"submit": "提交",
"create": "创建"
}
}
#en.json
{
"en": {
"submit": "Submit",
@@ -90,24 +91,25 @@ beego中设置全局变量如下
3. 使用语言包
我们可以在controller中调用翻译获取响应的翻译语言如下所示
func (this *MainController) Get() {
this.Data["create"] = beego.Translation.Translate("create")
this.TplNames = "index.tpl"
}
我们也可以在模板中直接调用响应的翻译函数:
//直接文本翻译
{{.create | Trans}}
//时间翻译
{{.time | TransDate}}
{{.time | TransDate}}
//货币翻译
{{.money | TransMoney}}
{{.money | TransMoney}}
## links
* [目录](<preface.md>)
* 上一节: [用户认证](<14.4.md>)
* 下一节: [pprof支持](<14.6.md>)
* 下一节: [pprof支持](<14.6.md>)
{% endraw %}