golangでajaxを使用してrssのデータを取得する
構成
. ├── main.go ├── static │ ├── css │ │ ├── bootstrap-theme.css │ │ ├── bootstrap-theme.css.map │ │ ├── bootstrap-theme.min.css │ │ ├── bootstrap-theme.min.css.map │ │ ├── bootstrap.css │ │ ├── bootstrap.css.map │ │ ├── bootstrap.min.css │ │ └── bootstrap.min.css.map │ ├── fonts │ │ ├── glyphicons-halflings-regular.eot │ │ ├── glyphicons-halflings-regular.svg │ │ ├── glyphicons-halflings-regular.ttf │ │ ├── glyphicons-halflings-regular.woff │ │ └── glyphicons-halflings-regular.woff2 │ └── js │ ├── app.js │ ├── bootstrap.js │ ├── bootstrap.min.js │ ├── jquery-2.2.0.min.js │ ├── jquery-2.2.0.min.map │ └── npm.js └── templates └── index.html
実装
main.go
package main // インポート import ( "log" "net/http" "html/template" "github.com/gorilla/mux" "io/ioutil" "encoding/xml" "encoding/json" "fmt" ) // RSS一覧用 type RssListItem struct { Title string Url string } // RSS2用の構造体 type Rss2 struct { XMLName xml.Name `xml:"rss"` Version string `xml:"version,attr"` // Required Title string `xml:"channel>title"` Link string `xml:"channel>link"` Description string `xml:"channel>description"` // Optional PubDate string `xml:"channel>pubDate"` ItemList []Item `xml:"channel>item"` } // RSS2の各記事の部分(Item) type Item struct { // Required Title string `xml:"title"` Link string `xml:"link"` Description template.HTML `xml:"description"` // Optional Content template.HTML `xml:"encoded"` PubDate string `xml:"pubDate"` Comments string `xml:"comments"` } // RSSのjson用 type RssJsonList struct { Title string `json:"title"` List []RssJsonItem `json:"list"` } type RssJsonItem struct { Title string `json:"title"` Link string `json:"link"` Date string `json:"date"` } // 主処理 func main(){ // ルーティング初期化 r := mux.NewRouter() // 静的ファイルをサポート r.PathPrefix("/static/").Handler(http.StripPrefix("/static/", http.FileServer(http.Dir("static")))) // url別処理 r.HandleFunc("/", func(w http.ResponseWriter, r *http.Request){ // テンプレート生成 tmpl := template.Must(template.New("index").ParseFiles("templates/index.html")) // 変数を設定 tmpl.Execute(w, struct{ RssList []RssListItem }{ RssList: []RssListItem{ { Title: "m_shige1979のささやかな抵抗と欲望の日々", Url: "http://m-shige1979.hatenablog.com/rss", }, { Title: "ぎひょーさん", Url: "http://gihyo.jp/feed/rss2", }, { Title: "@IT", Url: "http://rss.rssad.jp/rss/itmatmarkit/rss.xml", }, }, }) // log log.Print(r.URL.Path) }) r.HandleFunc("/getRss", func(w http.ResponseWriter, r *http.Request){ r.ParseForm() _url := r.FormValue("url") // httpよりRSS取得 res, err := http.Get(_url) if err != nil { panic(err) } // text形式で読み込む asText, err2 := ioutil.ReadAll(res.Body) if err2 != nil { panic(err2) } // rss2構造体を定義 rssData := Rss2{} // パースして格納 err3 := xml.Unmarshal(asText, &rssData) if err3 != nil { panic(err3) } // json用に新規に用意 var jsonData = RssJsonList{} jsonData.Title = rssData.Title jsonData.List = []RssJsonItem{} // 記事の部分を取得 for _, value := range rssData.ItemList { jsonData.List = append(jsonData.List, RssJsonItem{Title: value.Title, Link: value.Link, Date: value.PubDate}) } // jsonエンコード outputJson, err := json.Marshal(&jsonData) if err != nil { panic(err) } // jsonヘッダーを出力 w.Header().Set("Content-Type", "application/json") // jsonデータを出力 fmt.Fprint(w, string(outputJson)) // log log.Print(r.URL.Path) }) // ルーティング設定 http.Handle("/", r) // ポート待ち log.Println(":9001") http.ListenAndServe(":9001", nil) }
templates/index.html
{{ define "index" }} <!DOCType html> <html> <head> <meta charset="utf-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>websample3</title> <link rel="stylesheet" href="/static/css/bootstrap.min.css" /> </head> <body> <div class="container-fluid"> <div class="row"> <div class="col-xs-12"> <h3>RSSリスト</h3> <ul> {{ range .RssList }} <li> <a href="javascript:void(0);" class="rss_click" data-url="{{ .Url }}"> {{ .Title }} </a> </li> {{ end }} </ul> </div> </div> <hr /> <div class="row"> <div class="col-xs-12"> <div class="rss_entry"> </div> <div class="rss_item_tag" style="display: none;"> <blockquote> <p class="date">aaaa</p> <p class="title">bbbb</p> <footer> <a href="cccc" target="_blank">xxxxx</a> </footer> </blockquote> </div> </div> </div> </div> <script src="/static/js/jquery-2.2.0.min.js"></script> <script src="/static/js/bootstrap.min.js"></script> <script src="/static/js/app.js"></script> </body> </html> {{ end }}
static/js/app.js
$(function(){ $(".rss_click").on("click", function(){ var _url = $(this).attr("data-url"); console.log(_url); // ajaxでrssを取得 $.ajax({ type: 'POST', url: '/getRss', data: { url: _url }, dataType: 'json', success: function(data, status){ console.log("success"); console.log(data); // クリア $(".rss_entry").empty(); for(var _key in data.list){ var _itemElement = $(".rss_item_tag").clone(true); _itemElement.removeClass("rss_item_tag"); _itemElement.css("display", "block"); // rss情報設定 _itemElement.find(".date").text(data.list[_key]["date"]); _itemElement.find(".title").text(data.list[_key]["title"]); _itemElement.find("footer > a").attr("href", data.list[_key]["link"]); _itemElement.find("footer > a").text(data.list[_key]["link"]); // 追加 $(".rss_entry").append(_itemElement); } }, error: function(err1, err2, err3){ console.log("error"); }, }); }); });
ソースのインデントが…まあいいか
結果
うん、まあこんなもんでいいかと
今回はこれで終わり
golangでjsonのデータを出力する
一気に気温が上がったり、下がったり大変
安定せんかな〜
実装1(シンプルな構造体)
main1.go
package main import ( "fmt" "net/http" "log" "github.com/gorilla/mux" "encoding/json" ) // 単純な構造体 type Data1 struct { Title string `json:"title"` Message string `json:"message"` Status int `json:"status"` } func main(){ // ルーティング router := mux.NewRouter() // URL別設定 router.HandleFunc("/sample1", func(w http.ResponseWriter, r *http.Request){ // 構造体を定義 var data1 = Data1{} data1.Title = "sample1" data1.Message = "hello, sample1" data1.Status = 100 // jsonエンコード outputJson, err := json.Marshal(&data1) if err != nil { panic(err) } // jsonヘッダーを出力 w.Header().Set("Content-Type", "application/json") // jsonデータを出力 fmt.Fprint(w, string(outputJson)) // log log.Print(r.URL.Path) }) // ハンドル割当 http.Handle("/", router) // log log.Print("localhost:9001") // ポート http.ListenAndServe(":9001", nil) }
↓
実装2(構造体に配列を含む)
main2.go
package main import ( "fmt" "net/http" "log" "github.com/gorilla/mux" "encoding/json" ) // 配列を含む構造体 type Data2 struct { Title string `json:"title"` Message string `json:"message"` Status int `json:"status"` List map[string]Item `json:"list"` } // 構造体の配列Item type Item struct { Name string `json:"name"` Age int `json:"age"` } func main(){ // ルーティング router := mux.NewRouter() // URL別設定 router.HandleFunc("/sample2", func(w http.ResponseWriter, r *http.Request){ // 構造体を定義 var data2 = Data2{} data2.Title = "sample2" data2.Message = "hello, sample2" data2.Status = 200 data2.List = map[string]Item{} data2.List["test1"] = Item{Name:"taro", Age: 10} data2.List["test2"] = Item{Name:"hanako", Age: 18} data2.List["test3"] = Item{Name:"pochi", Age: 50} // jsonエンコード outputJson, err := json.Marshal(&data2) if err != nil { panic(err) } // jsonヘッダーを出力 w.Header().Set("Content-Type", "application/json") // jsonデータを出力 fmt.Fprint(w, string(outputJson)) // log log.Print(r.URL.Path) }) // ハンドル割当 http.Handle("/", router) // log log.Print("localhost:9001") // ポート http.ListenAndServe(":9001", nil) }
↓
なんとかできました。
RSSの場合にもあったけど
type Data2 struct { Title string `json:"title"` Message string `json:"message"` Status int `json:"status"` List map[string]Item `json:"list"` }
右の方にjsonとか指定したらその名前になるので小文字にしたい場合などは役に立ちます…というかきまりみたいな感じかな…
テキトーにググったけどそれっぽいパッケージが見つからなかったのでこれでいいはず
golangでRSS2のデータを取得して表示
参考
[Golang] XML Parsing Example (7) - Parse RSS 2.0
※Atomや両方対応のパターンもあります
静的ファイルも参照したい
jsとかcssとか使用したいけどどうやって参照するか
web applications - Serving static content with a root URL with the Gorilla toolkit - Stack Overflow
実装
構成
. ├── main.go ├── static │ ├── css │ │ ├── bootstrap-theme.css │ │ ├── bootstrap-theme.css.map │ │ ├── bootstrap-theme.min.css │ │ ├── bootstrap-theme.min.css.map │ │ ├── bootstrap.css │ │ ├── bootstrap.css.map │ │ ├── bootstrap.min.css │ │ └── bootstrap.min.css.map │ ├── fonts │ │ ├── glyphicons-halflings-regular.eot │ │ ├── glyphicons-halflings-regular.svg │ │ ├── glyphicons-halflings-regular.ttf │ │ ├── glyphicons-halflings-regular.woff │ │ └── glyphicons-halflings-regular.woff2 │ └── js │ ├── bootstrap.js │ ├── bootstrap.min.js │ ├── jquery-2.2.0.min.js │ ├── jquery-2.2.0.min.map │ └── npm.js └── templates └── index.html
main.go
package main // インポート import ( "log" "net/http" "html/template" "github.com/gorilla/mux" "io/ioutil" "encoding/xml" ) // RSS2用の構造体 type Rss2 struct { XMLName xml.Name `xml:"rss"` Version string `xml:"version,attr"` // Required Title string `xml:"channel>title"` Link string `xml:"channel>link"` Description string `xml:"channel>description"` // Optional PubDate string `xml:"channel>pubDate"` ItemList []Item `xml:"channel>item"` } // RSS2の各記事の部分(Item) type Item struct { // Required Title string `xml:"title"` Link string `xml:"link"` Description template.HTML `xml:"description"` // Optional Content template.HTML `xml:"encoded"` PubDate string `xml:"pubDate"` Comments string `xml:"comments"` } // 主処理 func main(){ // ルーティング初期化 r := mux.NewRouter() // 静的ファイルをサポート r.PathPrefix("/static/").Handler(http.StripPrefix("/static/", http.FileServer(http.Dir("static")))) // url別処理 r.HandleFunc("/", func(w http.ResponseWriter, r *http.Request){ // httpよりRSS取得 _rssURL := "http://m-shige1979.hatenablog.com/rss" res, err := http.Get(_rssURL) if err != nil { panic(err) } // text形式で読み込む asText, err2 := ioutil.ReadAll(res.Body) if err2 != nil { panic(err2) } // rss2構造体を定義 rssData := Rss2{} // パースして格納 err3 := xml.Unmarshal(asText, &rssData) if err3 != nil { panic(err3) } // テンプレート生成 tmpl := template.Must(template.New("index").ParseFiles("templates/index.html")) // 変数を設定 tmpl.Execute(w, struct{ RssItemList []Item }{ RssItemList: rssData.ItemList, }) // url log.Println(r.URL.Path) }) // ルーティング設定 http.Handle("/", r) // ポート待ち log.Println(":9001") http.ListenAndServe(":9001", nil) }
templates/index.html
{{ define "index" }} <!DOCType html> <html> <head> <meta charset="utf-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>websample3</title> <link rel="stylesheet" href="/static/css/bootstrap.min.css" /> </head> <body> <div class="container-fluid"> <div class="row"> <div class="col-xs-12"> <h3>RSSリスト</h3> </div> </div> <div class="row"> <div class="col-xs-12"> {{ range .RssItemList }} <div> <blockquote> <p>{{ .PubDate }}</p> <p>{{ .Title }}</p> <footer> <a href="{{ .Link }}" target="_blank">{{ .Link }}</a> </footer> </blockquote> </div> {{ end }} </div> </div> </div> <script src="/static/js/jquery-2.2.0.min.js"></script> <script src="/static/js/bootstrap.min.js"></script> </body> </html> {{ end }}
結果
golangでgorillaとかいうのを使ってみる(sessions)
セッションを使用してみる
値を入れること自体はそんなに難しく無い感じですけど取り出すときになんかいろいろ手間取る感じ
基本的には構造体などで管理したほうがいい感じです
インストール
go get github.com/gorilla/sessions
実装
main.go
package main import ( "encoding/gob" "github.com/gorilla/mux" "github.com/gorilla/sessions" "net/http" "fmt" "time" "html/template" "crypto/rand" "encoding/base32" "io" "strings" ) // セッション名 var session_name string = "gsid" // Cookie型のstore情報 var store *sessions.CookieStore // セッションオブジェクト var session *sessions.Session // 構造体 type Data1 struct { Count int Msg string } // 主処理 func main(){ // 構造体を登録 gob.Register(&Data1{}) // セッション初期処理 sessionInit() // ルーティング生成 r := mux.NewRouter() // URL別の処理 r.HandleFunc("/", func(w http.ResponseWriter, r *http.Request){ // セッションオブジェクトを取得 session, _ := store.Get(r, session_name) data1, ok := session.Values["data1"].(*Data1) if data1 != nil { data1.Count++ data1.Msg = fmt.Sprintf("%d件カウント", data1.Count) } else { data1 = &Data1{0, "データ無し"} } fmt.Println(ok) fmt.Println(data1) session.Values["data1"] = data1 // 保存 sessions.Save(r, w) // テンプレートを指定 tmpl := template.Must(template.New("index").ParseFiles("templates/index.html")) tmpl.Execute(w, struct { Detail *Data1 }{ Detail: data1, }) // logの代わり fmt.Print(time.Now()) fmt.Println(" url = " + r.URL.Path) }) r.HandleFunc("/clear", func(w http.ResponseWriter, r *http.Request){ // セッション初期化 sessionInit() // logの代わり fmt.Print(time.Now()) fmt.Println(" url = " + r.URL.Path) // redirect http.Redirect(w, r, "/", http.StatusFound) }) // rを割当 http.Handle("/", r) // ポートを割当 fmt.Println("localhost:9001") http.ListenAndServe(":9001", nil) } // セッション用の初期処理 func sessionInit(){ // 乱数生成 b := make([]byte, 48) _, err := io.ReadFull(rand.Reader, b) if err != nil { panic(err) } str := strings.TrimRight(base32.StdEncoding.EncodeToString(b), "=") // 新しいstoreとセッションを準備 store = sessions.NewCookieStore([]byte(str)) session = sessions.NewSession(store, session_name) // セッションの有効範囲を指定 store.Options = &sessions.Options{ Domain: "localhost", Path: "/", MaxAge: 0, Secure: false, HttpOnly: true, } // log fmt.Println("key data --") fmt.Println(str) fmt.Println("") fmt.Println("store data --") fmt.Println(store) fmt.Println("") fmt.Println("session data --") fmt.Println(session) fmt.Println("") }
templates/index.html
{{ define "index" }} <!DOCType html> <html> <head> <meta charset="utf-8" /> <title>websample2</title> </head> <body> count = {{ .Detail.Count }}<br /> msg = {{ .Detail.Msg }}<br /> <br /> <a href="/clear">クリア<a/> </body> </html> {{ end }}
セッションのデータ管理は?
store = sessions.NewCookieStore([]byte(str))
これで"store"とかいう変数にCookie形式の形っぽいデータをどっかに管理するみたい
ちなみにローカルファイル内に配置したい場合は
store = sessions.NewFilesystemStore("", []byte(str))
こうなる
第1引数はセッションファイルの配置場所で空文字の場合は規定の場所を指定centosとかでは"/tmp"みたい…
byteで渡す値でデータを管理しているのでデータを初期化するという意味では一度別の名前にするのが良いかと
Valuesの値を消したりしてもいいかもしれないけど面倒な感じもあるので乱数を生成してから消すのも手かと思われる
所感
なんか遅い…
手動でログを出力しているせいかもしれないけどなんか応答が結構遅い感じがする
ルーティングとセッションをとりあえずだけど対応したのでちょっと他のこともやってみる
うーんやることが増えてきたのでソースがでかくなってきた\(^o^)/
golangでgorillaとかいうのを使ってみる(mux)
ゴリラ?
Gorilla, the golang web toolkit
まあ、http関連のやつでルーティングとかセッションとかを"net/http"よりは柔軟に使える感じのもの
なんか適当に調べたけど"net/http"ではセッションは使えないとかなんとか
ちょっと今回はルーティングの"gorilla/mux"を使用する
インストール
go get github.com/gorilla/mux
実装
今回の構成
. ├── main.go └── templates ├── index.html └── save.html
main.go
package main import ( "net/http" "github.com/gorilla/mux" "fmt" "time" "html/template" ) func main(){ // 生成 r := mux.NewRouter() // "/"の場合の処理 r.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { // テンプレート tmpl := template.Must(template.New("index").ParseFiles("templates/index.html")) err := tmpl.Execute(w, nil) if err != nil { panic(err) } // logの代わり fmt.Print(time.Now()) fmt.Printf(" path: " + r.URL.Path + "\n") }).Methods("GET") // "/save"の場合の処理 r.HandleFunc("/save", func(w http.ResponseWriter, r *http.Request) { // formの値を取得 r.ParseForm() data1 := r.FormValue("aaa") data2 := r.FormValue("bbb") // テンプレート tmpl := template.Must(template.New("save").ParseFiles("templates/save.html")) err := tmpl.Execute(w, struct { Data1 string Data2 string }{ Data1: data1, Data2: data2, }) if err != nil { panic(err) } // logの代わり fmt.Print(time.Now()) fmt.Printf(" path: " + r.URL.Path + "\n") }).Methods("POST") // 可変URL1 r.HandleFunc("/test1/{sample1}/", func(w http.ResponseWriter, r *http.Request) { // 画面サンプル fmt.Fprintf(w, "sample1\n") // logの代わり fmt.Print(time.Now()) fmt.Printf(" path: " + r.URL.Path + "\n") }) // 可変URL2 r.HandleFunc("/test2/{sample1}/{id:[0-9]{1,6}}/", func(w http.ResponseWriter, r *http.Request) { // 画面サンプル fmt.Fprintf(w, "sample2\n") // logの代わり fmt.Print(time.Now()) fmt.Printf(" path: " + r.URL.Path + "\n") }) // handing http.Handle("/", r) // 設定 http.ListenAndServe(":9001", nil) }
※POST、GETだけを指定したい場合など、また一部のURLが可変になる場合は楽できます。
templates/index.html
{{ define "index" }} <!DOCType html> <html> <head> <meta charaset="utf-8" /> <title>websample1</title> </head> <body> <h3>なんかいれて送信してみて</h3> <form method="post" action="/save"> <input type="text" name="aaa" value="" /><br /> <input type="text" name="bbb" value="" /><br /> <input type="submit" value="送信" /> </form> </body> </html> {{ end }}
templates/save.html
{{ define "save" }} <!DOCType html> <html> <head> <meta charaset="utf-8" /> <title>websample1</title> </head> <body> <h3>送信されたものは以下</h3> <div> aaa = {{ .Data1 }}<br /> bbb = {{ .Data2 }}<br /> </div> <a href="/">top</a> </body> </html> {{ end }}
画面
↓
↓
所感
このツールキットを使用することでネットワーク関連のコードを書くのに結構便利になる感じかと
web アプリを作成するとしたらルーティングとセッションは必須なのできちんとやっておく必要がありそうです。
golangでtemplate(html)の確認
ページを表示する際はテンプレートを使用する
標準では"text/template"と"html/template"が存在する
※他にもあるかもしれないけどあとでやる
参考
Go言語でhttpサーバーを立ち上げてHello Worldをする - Qiita
template - The Go Programming Language
golang で html/template でのテンプレートの継承と、HTML エスケープしないで変数を出力する方法 (Django, Jinja みたいに) - Qiita
[Go言語] templateパッケージでtwigとかのextends的なあれをやるにはどうしようか - Qiita
シンプルなテンプレート
構造
$ tree . ├── main.go └── templates └── index.tpl $
templates/index.tpl
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>golang template test</title> </head> <body> <h1>Golang Template Sample</h1> <p>Title --[{{.Title}}]</p> <p>Message--[{{.Message}}] </p> <div> <h3>Items</h3> {{range .List}} <p>{{.}}</p> {{end}} </div> <div> Link: {{.Link}} </div> </body> </html>
※テンプレートは中括弧("{}")で挟むようです
main.go
package main import ( "fmt" "net/http" "html/template" "time" ) func main(){ http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { fmt.Println(time.Now().Format("2006/01/02 15:04:05") + " " + r.URL.Path) // テンプレート用のファイルを読み込む tpl, err1 := template.ParseFiles("templates/index.tpl") if err1 != nil { panic(err1) } // テンプレートを出力 err2 := tpl.Execute(w, struct { Title string Message string List []string Link string }{ Title: "Hello", Message: "World", List: []string{ "Item1", "Item2", "Item3", }, Link: "<a href=\"/\">hoge</a>", }) if err2 != nil { panic(err2) } }) http.ListenAndServe(":9001", nil) }
ページをひらくとこうなる
一部のデータを加工する
templates/index.tpl
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>golang template test</title> </head> <body> <h1>Golang Template Sample</h1> <p>Title --[{{.Title}}]</p> <p>Message--[{{.Message}}] </p> <div> <h3>Items</h3> {{range .List}} <p>{{.}}</p> {{end}} </div> <div> Link: {{.Link | safe}} </div> <div> Link: {{.Link | lock}} </div> </body> </html>
main.go
package main import ( "fmt" "net/http" "html/template" "time" ) func main(){ http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { fmt.Println(time.Now().Format("2006/01/02 15:04:05") + " " + r.URL.Path) // 独自関数でエスケープを解除 funcMap := template.FuncMap{ "safe": func(text string) template.HTML { return template.HTML(text) }, "lock": func(text string) string { return "@@[" + text + "]@@" }, } // テンプレート用のファイルを読み込む tpl, _:= template.New("index.tpl").Funcs(funcMap).ParseFiles("templates/index.tpl") // テンプレートを出力 err2 := tpl.Execute(w, struct { Title string Message string List []string Link string }{ Title: "Hello", Message: "World", List: []string{ "Item1", "Item2", "Item3", }, Link: "<a href=\"/\">hoge</a>", }) if err2 != nil { panic(err2) } }) http.ListenAndServe(":9001", nil) }
結果
複数のテンプレートをファイルを使用する
構成
. ├── main.go └── templates ├── base.tpl └── contents.tpl
templates/base.tpl
{{ define "base" }} <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>golang template test</title> </head> <body> <h1>Golang Template Sample</h1> <p>Title --[{{.Title}}]</p> <p>Message--[{{.Message}}] </p> <div> {{ template "contents" . }} </div> </body> </html> {{ end }}
templates/contents.tpl
{{ define "contents" }} <div> <h3>Items</h3> {{range .List}} <p>{{.}}</p> {{end}} </div> <div> Link: {{.Link | safe}} </div> <div> Link: {{.Link | lock}} </div> {{ end }}
main.go
package main import ( "fmt" "net/http" "html/template" "time" ) func main(){ http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { fmt.Println(time.Now().Format("2006/01/02 15:04:05") + " " + r.URL.Path) // 独自関数でエスケープを解除 funcMap := template.FuncMap{ "safe": func(text string) template.HTML { return template.HTML(text) }, "lock": func(text string) string { return "@@[" + text + "]@@" }, } // テンプレート用のファイルを読み込む tpl := template.Must(template.New("hoge").Funcs(funcMap).ParseFiles("templates/base.tpl", "templates/contents.tpl")) // テンプレートを出力 err2 := tpl.ExecuteTemplate(w, "base", struct { Title string Message string List []string Link string }{ Title: "Hello", Message: "World", List: []string{ "Item1", "Item2", "Item3", }, Link: "<a href=\"/\">hoge</a>", }) if err2 != nil { panic(err2) } }) http.ListenAndServe(":9001", nil) }
頭パンクしそう(´・ω・`)
所感
やり方自体はパターンがあるからそのうち理解出来ていくと思うけどgo言語の書き方に慣れていないことや日本語のマニュアルがないのかエラーの意味をうまく理解できていないことがある。
いろいろ参考になりそうなソースがネットで検索したら出てくるので参考にしながらやっていくしかない
golangで超簡単なサーバ
実装
sample
package main import ( "fmt" "net/http" ) func main(){ http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request){ fmt.Fprint(w, "Golang Http Server") }) http.ListenAndServe(":8080", nil) }
↓
こんだけ
所感
やり方はnodejsと同じイメージかな…
jsonとかを扱う方法とかもちょっと調べておく