Fix failing build for a Japanese version because of template tags

This commit is contained in:
Denis Koltsov
2016-11-19 16:37:09 +01:00
parent 58cfbca7ff
commit 1b85586e22
13 changed files with 102 additions and 76 deletions

View File

@@ -1,3 +1,4 @@
{% raw %}
# 4.3 クロスサイトスクリプティングの予防
現在のホームページは大量の動的なコンテンツを含みユーザのエクスペリエンスを高めています。以前に比べてとても複雑になっています。いわゆる動的なコンテンツとはユーザの環境と要求に応じてWebアプリケーションが目的の内容を出力できることを指します。動的なホームページは"クロスサイトスクリプティング"(Cross Site Scripting、セキュリティ専門家が一般的にXSSと省略するもの)と呼ばれる攻撃を受けることがあります。
@@ -66,3 +67,4 @@ Goのhtml/templateパッケージはデフォルトでhtmlタグをフィルタ
* [目次](<preface.md>)
* 前へ: [入力値の検証](<04.2.md>)
* 次へ: [フォームの複数回送信の防止](<04.4.md>)
{% endraw %}

View File

@@ -1,3 +1,4 @@
{% raw %}
# 4.5 ファイルのアップロード処理
ユーザによるファイルのアップロードを処理したいとします。例えば、現在Instagramのようなホームページを作成しているとします。ユーザが撮影した写真を保存する必要があります。このような要求はどのように実現するのでしょうか
@@ -115,7 +116,7 @@
return err
}
defer fh.Close()
//iocopy
_, err = io.Copy(fileWriter, fh)
if err != nil {
@@ -155,3 +156,4 @@
* [目次](<preface.md>)
* 前へ: [フォームの多重送信の防止](<04.4.md>)
* 次へ: [まとめ](<04.6.md>)
{% endraw %}

View File

@@ -1,3 +1,4 @@
{% raw %}
# 6.4 sessionハイジャックの予防
sessionハイジャックは広範囲に存在する比較的重大な脆弱性です。session技術において、クライアントサイドとサーバサイドはsessionのIDによってセッションを維持します。しかしこのIDは簡単にスニッフィングされ、第三者に利用されてしまいます。これは中間者攻撃の一種です。
@@ -87,3 +88,4 @@ sessionが始まると、生成されたsessionIDの時間を記録する一つ
* [目次](<preface.md>)
* 前へ: [sessionストレージ](<06.3.md>)
* 次へ: [まとめ](<06.5.md>)
{% endraw %}

View File

@@ -1,3 +1,4 @@
{% raw %}
# 7.1 XMLの処理
XMLはデータと情報のやりとりするための形式として十分普及しています。Webサービスが日々広範囲で応用されてくるにつれ、現在XMLは日常的な開発作業において重要な役割を演じてきました。この節ではGo言語の標準パッケージにあるXML関連のパッケージをご紹介します。
@@ -219,3 +220,4 @@ XMLをstructに解析する際は以下のルールに従います 
* [目次](<preface.md>)
* 前へ: [テキスト処理](<07.0.md>)
* 次へ: [Jsonの処理](<07.2.md>)
{% endraw %}

View File

@@ -1,3 +1,4 @@
{% raw %}
# 7.4 テンプレートの処理
## テンプレートとは何か
おそらくあなたはMVCのデザインパターンについて聞いたことがあると思います。Modelはデータを処理を、Viewは表示結果を、Controllerはユーザのリクエストの制御を行います。Viewレイヤーの処理では、多くの動的な言語ではどれも静的なHTMLの中に動的言語が生成したデータを挿入します。例えばJSPでは`<%=....=%>`を挿入することで、PHPでは`<?php.....?>`を挿入することで実現します。
@@ -348,3 +349,4 @@ Webアプリケーションを作る時はテンプレートの一部が固定
* [目次](<preface.md>)
* 前へ: [正規表現の処理](<07.3.md>)
* 次へ: [ファイルの操作](<07.5.md>)
{% endraw %}

View File

@@ -1,3 +1,4 @@
{% raw %}
# 9.1 CSRF攻撃の予防
## CSRFとは何か 
@@ -91,3 +92,4 @@ tokenを検証
* [目次](<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とja-JP.jsonです。)
## ローカライズテキスト情報
@@ -132,3 +133,4 @@ 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("システムエラー") //システムエラーはクリティカルですので、ログに記録するだけでなくメールを送信します。
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クラスを定義しました。ですので、ここではこのインターフェースを実装すれば十分です。基底クラスのContorollerの実装は以下のようなメソッドになります
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を通してブログシステムを設計しましょう。これにはブログの閲覧、追加、修正、削除といった操作が含まれます。
@@ -52,19 +53,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)
@@ -77,12 +78,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
@@ -98,14 +99,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
@@ -116,39 +117,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 {
@@ -157,25 +158,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)
@@ -198,17 +199,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>
@@ -216,7 +217,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>
@@ -228,7 +229,7 @@ view.tpl
<h1>{{.Post.Title}}</h1>
{{.Post.Created}}<br/>
{{.Post.Content}}
new.tpl
@@ -241,7 +242,7 @@ new.tpl
</form>
edit.tpl
<h1>Edit {{.Post.Title}}</h1>
<h1>New Blog Post</h1>
@@ -256,3 +257,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 @@ Web開発ではこのようなプロセスをよく見かけます
Email string `form:text,valid:required|valid_email`
Introduce string `form:textarea`
}
structを定義したらcontrollerにおいてこのように操作します
func (this *AddController) Get() {
@@ -36,26 +37,26 @@ structを定義したらcontrollerにおいてこのように操作します
this.Layout = "admin/layout.html"
this.TplNames = "admin/add.tpl"
}
テンプレートで以下のようにフォームを表示します
<h1>New Blog Post</h1>
<form action="" method="post">
{{.form.render()}}
</form>
上では全体の第1ステップを定義しました。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 @@ structを定義したらcontrollerにおいてこのように操作します
</tbody></table>
## フォームの検証
以下のリストは使用されるオリジナルのルールを表しています
<table cellpadding="0" cellspacing="1" border="0" style="width:100%" class="tableborder">
@@ -279,3 +280,4 @@ structを定義したらcontrollerにおいてこのように操作します
* [目次](<preface.md>)
* 前へ: [Sessionのサポート](<14.2.md>)
* 次へ: [ユーザの認証](<14.4.md>)
{% endraw %}

View File

@@ -1,3 +1,4 @@
{% raw %}
# 14.5 多言語サポート
第10章において国際化とローカライゼーションおよび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ファイルです。第10章でご紹介したのと同じように、設計する必要のあるファイルを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>)
{% endraw %}