From 1b85586e22df8f38058c0cf293195c186346ba6e Mon Sep 17 00:00:00 2001 From: Denis Koltsov Date: Sat, 19 Nov 2016 16:37:09 +0100 Subject: [PATCH] Fix failing build for a Japanese version because of template tags --- ja/04.3.md | 2 ++ ja/04.5.md | 4 +++- ja/06.4.md | 2 ++ ja/07.1.md | 2 ++ ja/07.4.md | 2 ++ ja/09.1.md | 2 ++ ja/10.2.md | 2 ++ ja/10.3.md | 2 ++ ja/12.2.md | 18 ++++++++++-------- ja/13.3.md | 42 ++++++++++++++++++++++-------------------- ja/13.5.md | 50 ++++++++++++++++++++++++++------------------------ ja/14.3.md | 14 ++++++++------ ja/14.5.md | 36 +++++++++++++++++++----------------- 13 files changed, 102 insertions(+), 76 deletions(-) diff --git a/ja/04.3.md b/ja/04.3.md index f8818f8c..78cf119b 100644 --- a/ja/04.3.md +++ b/ja/04.3.md @@ -1,3 +1,4 @@ +{% raw %} # 4.3 クロスサイトスクリプティングの予防 現在のホームページは大量の動的なコンテンツを含みユーザのエクスペリエンスを高めています。以前に比べてとても複雑になっています。いわゆる動的なコンテンツとはユーザの環境と要求に応じてWebアプリケーションが目的の内容を出力できることを指します。動的なホームページは"クロスサイトスクリプティング"(Cross Site Scripting、セキュリティ専門家が一般的にXSSと省略するもの)と呼ばれる攻撃を受けることがあります。 @@ -66,3 +67,4 @@ Goのhtml/templateパッケージはデフォルトでhtmlタグをフィルタ * [目次]() * 前へ: [入力値の検証](<04.2.md>) * 次へ: [フォームの複数回送信の防止](<04.4.md>) +{% endraw %} diff --git a/ja/04.5.md b/ja/04.5.md index 7bf16234..c02357e6 100644 --- a/ja/04.5.md +++ b/ja/04.5.md @@ -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 @@ * [目次]() * 前へ: [フォームの多重送信の防止](<04.4.md>) * 次へ: [まとめ](<04.6.md>) +{% endraw %} diff --git a/ja/06.4.md b/ja/06.4.md index 312bbae8..5f001b46 100644 --- a/ja/06.4.md +++ b/ja/06.4.md @@ -1,3 +1,4 @@ +{% raw %} # 6.4 sessionハイジャックの予防 sessionハイジャックは広範囲に存在する比較的重大な脆弱性です。session技術において、クライアントサイドとサーバサイドはsessionのIDによってセッションを維持します。しかしこのIDは簡単にスニッフィングされ、第三者に利用されてしまいます。これは中間者攻撃の一種です。 @@ -87,3 +88,4 @@ sessionが始まると、生成されたsessionIDの時間を記録する一つ * [目次]() * 前へ: [sessionストレージ](<06.3.md>) * 次へ: [まとめ](<06.5.md>) +{% endraw %} diff --git a/ja/07.1.md b/ja/07.1.md index 29424aee..1ca83bfd 100644 --- a/ja/07.1.md +++ b/ja/07.1.md @@ -1,3 +1,4 @@ +{% raw %} # 7.1 XMLの処理 XMLはデータと情報のやりとりするための形式として十分普及しています。Webサービスが日々広範囲で応用されてくるにつれ、現在XMLは日常的な開発作業において重要な役割を演じてきました。この節ではGo言語の標準パッケージにあるXML関連のパッケージをご紹介します。 @@ -219,3 +220,4 @@ XMLをstructに解析する際は以下のルールに従います:  * [目次]() * 前へ: [テキスト処理](<07.0.md>) * 次へ: [Jsonの処理](<07.2.md>) +{% endraw %} diff --git a/ja/07.4.md b/ja/07.4.md index 61e95da3..9f5f7150 100644 --- a/ja/07.4.md +++ b/ja/07.4.md @@ -1,3 +1,4 @@ +{% raw %} # 7.4 テンプレートの処理 ## テンプレートとは何か おそらくあなたはMVCのデザインパターンについて聞いたことがあると思います。Modelはデータを処理を、Viewは表示結果を、Controllerはユーザのリクエストの制御を行います。Viewレイヤーの処理では、多くの動的な言語ではどれも静的なHTMLの中に動的言語が生成したデータを挿入します。例えばJSPでは`<%=....=%>`を挿入することで、PHPでは``を挿入することで実現します。 @@ -348,3 +349,4 @@ Webアプリケーションを作る時はテンプレートの一部が固定 * [目次]() * 前へ: [正規表現の処理](<07.3.md>) * 次へ: [ファイルの操作](<07.5.md>) +{% endraw %} diff --git a/ja/09.1.md b/ja/09.1.md index 25ef0df6..74c30a45 100644 --- a/ja/09.1.md +++ b/ja/09.1.md @@ -1,3 +1,4 @@ +{% raw %} # 9.1 CSRF攻撃の予防 ## CSRFとは何か  @@ -91,3 +92,4 @@ tokenを検証 * [目次]() * 前へ: [セキュリティと暗号化](<09.0.md>) * 次へ: [入力フィルタリングの確保](<09.2.md>) +{% endraw %} diff --git a/ja/10.2.md b/ja/10.2.md index e693acb2..c761e099 100644 --- a/ja/10.2.md +++ b/ja/10.2.md @@ -1,3 +1,4 @@ +{% raw %} # 10.2 ローカライズリソース 前の節ではどのようにしてLocaleを設定するかご紹介しました。Localeを設定したあとはどのようにしてLocaleに対応する情報を保存するかという問題を解決する必要があります。ここでの情報とは以下の内容を含みます:テキスト情報、時間と日時、通貨の値、画像、ファイルや動画といったリソース等です。ここではこれらの情報に対してご紹介していきたいと思います。Go言語ではこれらのフォーマットの情報をJSONに保存します。その後それぞれ適した方法によって表示します。(以下では日本語と英語の2つの言語を対比して例を挙げます。保存の形式はそれぞれen.jsonとja-JP.jsonです。) ## ローカライズテキスト情報 @@ -132,3 +133,4 @@ Localeの違いによってビューを表示させる場合もあるかもし * [目次]() * 前へ: [デフォルトロケールの設定](<10.1.md>) * 次へ: [国際化サイト](<10.3.md>) +{% endraw %} diff --git a/ja/10.3.md b/ja/10.3.md index dea1ecda..dfa7eaa1 100644 --- a/ja/10.3.md +++ b/ja/10.3.md @@ -1,3 +1,4 @@ +{% raw %} # 10.3 国際化サイト 前の節でどのようにしてローカライズリソースを処理するかご紹介しました。Localeに対応した設定ファイルです。ではもし複数のローカライズリソースを処理する場合は?いくつかの我々が通常使用する例は:簡単なテキスト翻訳、時間や日時、数字といったものはどのように処理するのでしょうか?この節では一つ一つこれらの問題を解決していきます。 ## 複数のロケールパッケージの管理 @@ -178,3 +179,4 @@ * [目次]() * 前へ: [ローカライズリソース](<10.2.md>) * 次へ: [まとめ](<10.4.md>) +{% endraw %} diff --git a/ja/12.2.md b/ja/12.2.md index 3e1c0d05..f186ac0f 100644 --- a/ja/12.2.md +++ b/ja/12.2.md @@ -1,8 +1,9 @@ +{% raw %} # 12.2 サイトエラー処理 我々のWebアプリケーションが一旦実運用されると、さまざまなエラーが発生する可能性があります。Webアプリケーションの日常の実行ではいくつものエラーが発生する可能性があります。具体的には以下のとおり: - データベースエラー:データベースサーバへのアクセスまたはデータと関係のあるエラーです。例えば、以下は何らかのデータベースエラーを発生させることがあります。 - + - 接続エラー:このエラーはデータベースサーバのネットワークが切断された時や、ユーザ名とパスワードが不正だった場合、またはデータベースが存在しない場合に発生することがあります。 - 検索エラー:使用されたSQLが正しく無く、エラーが発生する場合です。このようなSQLエラーはもしプログラムに厳格なテストを行うことで回避できます。 - データエラー:データベースの約束が衝突する場合。例えば一つしかないフィールドに複数の主キーを持つデータが挿入されるとエラーを発生させます。しかし、あなたのアプリケーションプログラムが運用される前に厳格なテストを行うことでこれらの問題を回避することもできます。 @@ -27,9 +28,9 @@ エラー処理は実は我々も第十一章の第一節でどのようにエラー処理を設計するかご紹介しました。ここではまたひとつの例から詳細にご解説します。どのように異なるエラーを処理するのでしょうか: - ユーザにエラーが発生したことを通知する: - + ユーザがページにアクセスした時はふたつのエラーがあります:404.htmlとerror.htmlです。以下はそれぞれエラーページを表示するソースです: - + @@ -51,7 +52,7 @@ もうひとつのソース: - + @@ -72,9 +73,9 @@ - + 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 @@ * [目次]() * 前へ: [アプリケーションログ](<12.1.md>) * 次へ: [アプリケーションのデプロイ](<12.3.md>) +{% endraw %} diff --git a/ja/13.3.md b/ja/13.3.md index 9e1e1458..5526c9a8 100644 --- a/ja/13.3.md +++ b/ja/13.3.md @@ -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のコードは以下のようになります。データの設定と * [目次]() * 前へ: [カスタム定義のルータの設計](<13.2.md>) * 次へ: [ログとコンフィグ設計](<13.4.md>) +{% endraw %} diff --git a/ja/13.5.md b/ja/13.5.md index b465aee8..b18c68d7 100644 --- a/ja/13.5.md +++ b/ja/13.5.md @@ -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 - + - + {{.LayoutContent}} - + - + index.tpl

Blog posts

@@ -216,7 +217,7 @@ index.tpl
    {{range .blogs}}
  • - {{.Title}} + {{.Title}} from {{.Created}} Edit Delete @@ -228,7 +229,7 @@ view.tpl

    {{.Post.Title}}

    {{.Post.Created}}
    - + {{.Post.Content}} new.tpl @@ -241,7 +242,7 @@ new.tpl edit.tpl - +

    Edit {{.Post.Title}}

    New Blog Post

    @@ -256,3 +257,4 @@ edit.tpl * [目次]() * 前へ: [ログとコンフィグ設計](<13.4.md>) * 次へ: [まとめ](<13.6.md>) +{% endraw %} diff --git a/ja/14.3.md b/ja/14.3.md index 417ef079..12408378 100644 --- a/ja/14.3.md +++ b/ja/14.3.md @@ -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" } - + テンプレートで以下のようにフォームを表示します

    New Blog Post

    {{.form.render()}}
    - + 上では全体の第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要素の情報を表しています: @@ -121,7 +122,7 @@ structを定義したらcontrollerにおいてこのように操作します
    - + ## フォームの検証 以下のリストは使用されるオリジナルのルールを表しています @@ -279,3 +280,4 @@ structを定義したらcontrollerにおいてこのように操作します * [目次]() * 前へ: [Sessionのサポート](<14.2.md>) * 次へ: [ユーザの認証](<14.4.md>) +{% endraw %} diff --git a/ja/14.5.md b/ja/14.5.md index c1d7655b..a3e3cde0 100644 --- a/ja/14.5.md +++ b/ja/14.5.md @@ -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 * [目次]() * 前へ: [ユーザ認証](<14.4.md>) * 次へ: [pprofのサポート](<14.6.md>) +{% endraw %}