FC2ブログ

GoのHTMLテンプレートエンジン yosssi/ace の使い方

github.com/yosssi/ace の使い方について、あまり記事が無いので(特に日本語は)、まとめて置きたいと思います。

まずは、READMEを見ましょう。
基本的な使い方は以下に書いてありますが、順を追って補足していきたいと思います。
https://github.com/yosssi/ace/blob/master/documentation

Go上でのコード(APIの使い方)
以下のページのような使い方をします。
https://github.com/yosssi/ace/blob/master/documentation/getting-started.md
が単純な例しか載ってないので、ここでは私が今回Webアプリの開発に使ったフレームワーク Echo でのサンプルコードを紹介します。

WebフレームワークEchoでテンプレートエンジンAceを使う

上記のページで説明があるように、Ace-proxy というものもあります。なお、Load時のオプションとは、テンプレートのBaseのディレクトリや DynamicReload とかのことです。
https://github.com/yosssi/ace-proxy

APIの詳しい説明はGoDocに書かれています。
https://godoc.org/github.com/yosssi/ace


テンプレートの書き方
Example は Ace の使い方のほんの一部に過ぎません。

テンプレートの書き方については GitHub 上の Documentation に書かれています。 Ruby の Slim と Node の Jade に似た記法で書けます(完全に一緒じゃないです)。
https://github.com/yosssi/ace/blob/master/documentation/syntax.md
なお、上のページでは出てきませんが、

p <a href="https://github.com/">GitHub</a>

のように、タグで改行せずすぐ後ろに記述する場合は、HTML をそのまま書くことが出来ます。

ところで、上記のページを隈なく探しても、繰り返し出力の定義が出てきません。
出てきませんが、AceではGoの標準テンプレートエンジンである text/template (htmlの方ではない)の記法も含めることが出来ます(一番下のActionsのところで説明されています)。

よって、標準テンプレートには for 文が存在するので、繰り返し出力が可能です(実はこれを知らなくてずっとJavaScriptで書いてました…)。

ここからは、Goの標準テンプレートエンジンの説明になりますが、以下のように使います。
qiita.com/lanevok/items/dbf591a3916070fcba0d

また、for文は以下のように for range で記述してインデックス数を使うことも出来ます。
http://increment.hatenablog.com/entry/2016/04/27/203810


ただし、Goの標準テンプレートエンジンでもそのままでは四則演算出来ません。残念(なので、私は全てGoのコード内で計算させるようにしました)。一応関数を定義すればできるそうです。
http://asakandata.hatenablog.com/entry/2015/05/06/174952



注意点
ここまで、自分用のノートにリンクをまとめたものを書き起こしたものですが、結構自分で使ってて突っかかった部分があったので以下に書きたいと思います。
  • エラー
正直テンプレートのエラー自体がわかりにくいです。Goのコードに問題があるかと思いきやテンプレートのインデントの問題だったりして、意外と落とし穴です。ただし、panic()を使うと取り敢えずテンプレートの問題であること自体は把握できます。
  • =include
インクルードに指定したテンプレート内の{{}}は認識されずそのまま出力されてしまう。標準テンプレエンジンの記法で読み込めば解決するかもしれませんが未検証です。
  • インデント
インデントはスペースにします。タブにするとうまく動きませんでした。
  • コメント
コメントもインデントを意識して、必ずコメントアウトしたい行のコードの先頭に、スラッシュと一つ以上スペースを入れて書かないとエラーになります。


因みにこのAce、Hugoにも使われているそうです。Hugo使ってみたい。
https://github.com/yosssi/ace/blob/master/documentation/projects-using-ace.md

スポンサーサイト



よく考えることは重要

プログラミング作法という本をここ何ヶ月か掛けて少しずつ読んでるのですが、第5章のデバッグが結構面白いです。コードを読むのはちょっと時間が掛かるのですが、時間を決めててもこの章はどんどん先まで読んでしまっています。

そんな5章に「打つ前に読め」ということが書かれていて、「コードを舐めるように読んで、変更を施さずにしばらくよく考えてみること」がデバッグテクニックの一つとして紹介されていました。

私の場合、無駄に考えることが多いです。結局行き当たりばったりで編集して動いたところで、本当にバグの根源になってるところを取り除けたのか不安だし、実際結局バグが直ってなくて、デバッグを再開するハメになったことが何回かあるからなんですけど。
ただ、ひたすら考えるのは一番根本的な解決が出来る唯一の方法だと自分でも思うんですが、結構時間が掛るんですよね。

昨日も研究の主題について、今まで文章に書き起こしてきた研究背景や方向性を洗いざらいチェックして、整理した上でこの研究で最も示すべきことはなんなのか(何を検証して示せばこの研究の背景に貢献できるのか)を丸一日掛けてひたすら考えていました。

今まで立ち止まって悩むのは時間の無駄に思えたり、取り敢えず動くようになればそのほうが早く次に進めるし良いと思ってしまって、結構後ろめたい気持ち(さっさと進めてしまえばいいのにとか、他の人なら同じ時間でももっと先に進めてるだろうにとか)が出てきて、毎回「考えるより手を動かせって」自分に言い聞かせてたんですよね。この本にも「効果的なわりに過小評価されているデバッグテクニック」なんて書かれてますけど。

でも結局自分のためにならないのが嫌だから、投げ出さずに悩んでるわけですし、適当やったってどうせ良いプロダクトなんて生まれないよなーと読んでて思えてきました。

よくTwitterとかで納期が迫ってるからって適当に行き当たりばったりのコードを書いて、取り敢えず問題になってた箇所は修正されたからってリリースしといて、後で痛い目に遭う、みたいな話とかよく見かけますけど、そういうのの原因の終着点って結局ここなんだろうなって思います。しかも、間違いに気づかないままどんどん次の仕事が舞い降りてくるから社員も成長しないという…。
世の中世知辛いですね。

あと、アジャイルが流行ってて、取り敢えずの修正でも完成ってことにしてしまえ、ってことだと思ってる人って結構居そうでそういうのが拍車を掛けてる現場とかあるのかなぁなんてちょっと心配です。

アジャイルは確かに段階を区切って製品をプロダクトしていくんだけど、ある機能を実装してみるってところまでやるってことだったら、そこまでの機能を完全に実装するってことなので、バグが残ったままを許容するなんて真似が決して現場で正当化されないことを切に願ってます(一体どこの誰に対する願いなんだか)。
良いプログラムを作れる現場は少なくともこういうバグをちゃんと直すことに(許容するって言い方は変なので)時間を惜しまない企業だと思います。
これだから日本はーとか、日本が日本がーっていうのはどうせ他の国だって駄目なところがあるだろうから嫌いなんですけど、他の国と比べないにしても、仕事をかき集めて短い時間で大量に製品を作ることが最も効率的で利益が上がると思ってる管理職だったり経営者だったりが日本には少なく無い数いると思います。
でも、プログラムの場合はバグの少ないプログラムこそが信頼できるし、安定した利益に繋がる筈なんです。逆にバグだらけのクソプログラムばかり生産する企業なんて信頼できないし、そういう会社は実際に叩かれまくってます。皮肉にも技術者が居ないから潰れるほど需要はなくならないのかもしれませんが。プログラムなんて幾らでも複製出来るんだから、圧倒的に量より質を重視すべきだと思うんですが。
そもそも問題箇所の修正だけしか確認出来てないのにそのままの製品プログラムなんて外面だけ綺麗にした欠陥商品と同じで、ハッキリ言って詐欺ですよ。完璧には無理でも余計なバグが出ないかぐらいはテストしてからリリースしないと許されないように世間の目も変わってくれると良いんですけど。

なんか書いてるうちに内容が濃くなっちゃいましたw

今までは、いずれはこれが仕事になるかもしれないわけだし、ずっと考え込むのは作業効率が悪くて良くないことだと思ってましたけど、寧ろいわゆる「クソコード」を製品に取り込まないためのプロセスとして「ちゃんとコードを直すこと」、そのために「よく考えてみること」は最重要なんじゃないかと思いました。

☆関連商品☆

DockerはVMと同列に比較できるものではない

この記事はブロとものみ閲覧できます

データ・ボリューム・コンテナは不要どころかもう使えない子

一つ前の記事の続き。
まずは更に踏み入ってボリュームだけでもコンテナ間で共有できるとか言われる所以について説明します。

前の記事で述べた通り、ボリュームとは単にコンテナ内にホスト(Docker コンテナを動かしてるOS上)のディレクトリをマウントさせたものでした。つまり、ホストの同じディレクトリをそれぞれのコンテナでマウントしてしまえば別にデータ・ボリューム・コンテナなんて無くても共有できるってことです。
Q.E.D.

証明は出来たかもしれないけどじゃあなんでデータ・ボリューム・コンテナでボリュームをマウントさせようとするのか?

それは上の方法だといちいち Docker コンテナを起動する(docker run)時にボリュームを指定する必要が生じて、環境をまとめるのが目的でDocker使ってんじゃないの?っていう本末転倒な状況に陥るためです。

データ・ボリューム・コンテナだとボリュームの設定をデータ・ボリューム・コンテナの立ち上げ時のみで済ませることが出来ます。その他のコンテナを起動時に --volumes-from でデータ・ボリューム・コンテナを指定するだけで良い。つまり、他のコンテナでは起動時にボリュームの場所を入力しなくて良いのです。

また、これにはさらなる利点があり、コンテナを立ち上げるホストが変わって、ボリュームをマウントしたいホストの場所が変わっても一ヶ所の変更のみで対応することが出来るんです。

でも、このままだとボリュームのディレクトリをいちいちデータ・ボリューム・コンテナ起動時に指定しないといけません。

そこで Docker Compose の登場

Docker Compose には複数のコンテナの設定を纏めて一つのファイルに書けるというメリットの他に、起動時のコマンドオプションを記述できるメリットがあります。よって、ボリュームのディレクトリを記述すれば、起動時の場所の指定も必要なくなります。
さらに、コンテナ間の通信時に docker-compose.yml 内で指定したコンテナ名をホスト名と置き換えられるので、コンテナ名を短くすればコンテナ内アプリのコーディングも楽になります。

しかし、ここで終わらなかった。

Docker Compose Version 3 での volumes_from 削除により無能と化す

平成29年5月31日時点で最新のDocker Compose Version 3 では、ボリュームに関する記述が変更され、よりシンプルになりました。
シンプルになったのは良いですが、結論を言うと同一ホスト上でのボリューム共有を目的にデータ・ボリューム・コンテナを利用する意義が無くなりました。つまり実はもうデータ・ボリューム・コンテナは要らない子。

まず、この件を説明するにはボリュームのマウント方式について説明する必要があります。
今まで、ボリュームについてホストのディレクトリを指定できることを当たり前のように説明していました。しかし、実はボリュームはホストのディレクトリを指定しなくとも作ることが出来るのです(詳しくは以下を参照)。
https://docs.docker.com/compose/compose-file/#volumes
コンテナ内のマウント先は必ず指定しなければなりません。
また、ボリュームには名前を付けることも出来ます(名前付きボリューム)。名前を付けると何が嬉しいかというと、Compose 内で定義しているコンテナ間でボリュームを共有することが出来るのです。Compose Version 2 から登場したトップレベルの volumes オプションで設定できます。

じゃあデータ・ボリューム・コンテナ要らないのか、となるのは早計で実はボリューム名を定義するとホストの場所を指定できなくなります。これだと自分で任意の場所を指定できないため、問題というか不便が生じます。なので、今迄はデータ・ボリューム・コンテナでホストの場所を指定した上で、他のコンテナでは volumes_from オプションでデータ・ボリューム・コンテナを指定することで共有していました。

しかし、なんとあろうことか Docker Compose Version 3 では volumes_from オプションを削除してしまいました。
https://docs.docker.com/compose/compose-file/compose-versioning/#version-3
しかももう更新から半年くらいは経ってる筈なのにたちの悪いことに日本語のページでこの件に触れられてる記事が殆ど無い。

でも、焦る必要はありません。(Apple風)
そもそもボリュームのホストの場所を指定できないことによる問題の根源は、好きな場所にボリュームを作れないことにありました。しかし、ホストの場所を指定しない場合にボリュームを作るディレクトリの場所は実は決まっています(/var/lib/docker/volumes/以下)。
問題はディレクトリの名前ですが、実は名前付きボリュームならボリューム名を含んだディレクトリ名となっているので、探してアクセスすることは出来ます。さらに、名前付きボリュームは名前を指定することでマウントが可能なので、再利用が可能です(永続化されている)。
※因みにコンテナ内のマウント先のみ指定した場合は適当な名前のボリュームになり、コンテナを削除した時点でコンテナから接続はできなくなりますが、データは/var/lib/docker/volumes/以下に残ります。

よって、別にデータ・ボリューム・コンテナを使えなくても不自由なく使用が可能です。

また、ボリュームを別に作る必要はありますが、実は docker volume create コマンドを使えばボリュームのホスト上での場所も指定することが出来ます。 できそうな雰囲気でしたが執筆時点では出来ませんでした。。
https://docs.docker.com/engine/reference/commandline/volume_create/
プラグインを使えば出来るというような話もありますが試してみない以上は真偽は不明。

これで作ったボリュームはトップレベルの volumes オプションで external: true すれば、マウントすることが出来ます。
https://docs.docker.com/compose/compose-file/#external

ホストに対して、ボリュームを作るのは一回で良いのでこれで無駄にデータ・ボリューム・コンテナを立ち上げなくても不便なく作業できます。

え、別に Version 2 で書けばよくね?

古いバージョンは廃止されることが宣言されてる。
せっかく環境依存性を抑えるためのツールなのに、時期が来たら使えなくなるとか意味が無い。
ということで、解決策がある以上皆さんこれからは Version 3 で書きませう φ(・∀・)

データ・ボリューム・コンテナはデータを保存するためのコンテナでは無い

あと1日で6月になってしまうので更新。今回も Docker ネタ。

ここ1ヶ月半近くずっと Docker を弄くり続けています。本当にやりたいことは Docker を使ったアプリ開発の更に先にあるんだけど、せっかくの機会、ということで Docker を自主的に使って少々時間が掛かってます(でも環境に依存しないようにしたい意図があるし今後のことを考えると今勉強しといたほうが良いって思ってる)。

ちょっと無駄話になってしまうので、読み飛ばしてもらったほうが良いかもしれませんが、一ヶ月半使った感想を書きます。
最初は結構動作にわからない部分が多く、また特に Docker Compose、コンテナ間の組み合わせなどすんなり分かんない部分もあったけどわかってしまえば結構簡単です。ボリュームなど実装がどういうものかわかってしまえば、書き方自体はシンプルで使うのは意外と楽です。

ただ、データの扱いについては非常に混乱したというかややこしいと思いました。


ここから本題。
まず、ボリュームについて理解しなければいけませんでしたが、こっちに関しては比較的シンプルで、各所の説明通りホストのディレクトリを各々の Docker コンテナでマウントして共有してるだけでした。
しかし、データ・ボリューム・コンテナはずっとデータを格納するコンテナ機能があるんだろうと思っていました。でもこれが超越的解釈で全くイメージとは異なる機能でした。
これから Docker を使い始めようと思ってあちこち見て回ってある程度情報を掴んできた人だと丁度こんな勘違いをしていると思います。

結論から言うとデータ・ボリューム・コンテナは単なるコンテナ。
これにボリュームとするホストのディレクトリをマウントさせた上で、ボリュームをコンテナ間で共有するためのいわゆるハブとして、各アプリ用コンテナと通信するようにしたのがこれの正体です。

データ・ボリューム・コンテナはデータを格納するんじゃなくて、あるボリュームを複数コンテナからアクセス出来るようにするためのコンテナです。

そして、こういう機能が Docker に備わっているわけではありません。
ボリュームをマウントさせた通常のコンテナを、ボリュームへのアクセス用ハブとして使っているものをこう呼んでるだけです。

ただし、通常 Docker のコンテナは何らかの個別のアプリを格納し、実行していますが、データ・ボリューム・コンテナでは BusyBox コンテナという最低限の Linux のコマンドのみを備えたコンテナを使用することが多いです(BusyBox は多くのコマンドを持ったツールでこれを格納したコンテナ)。
これが何故かは簡単で、データ・ボリューム・コンテナは単なるアクセスポートとしてしか使わないので容量・動作を軽くするためです。でもこれってなんか勿体なくない?

データ・ボリューム・コンテナはボリュームをコンテナ間で共有するためのものです。
というのが多くのサイトで目にする説明ですが、明らかに言葉不足です。こんな説明じゃ実体なんて分かるはずもなく生き殺し。
こうなる最大の理由はボリュームをコンテナ間で共有できないということが説明されてないことに尽きると思います(図があると尚良し ←)。

そもそも

Dockerは環境を持ち運べるようにしたものであって、データを移動できるようにしたものでは無い。
別にデータ・ボリューム・コンテナ経由でデータを格納したからって、結局データはホストに保存されるので ADD に対して可搬性は高くならない。

これで話は終わり。。

ところが、私を更に混乱させたのが、ボリュームだけでもコンテナ間で共有できるという情報だった。
じゃあなんでデータ・ボリューム・コンテナなんて使うんだ?
ますます理解できなくなってきた。

この後いろいろ調べた末、記事投稿時点でデータ・ボリューム・コンテナは不要だと判明しました。
続く

スポンサードリンク

ブログ内検索

プロフィール

ふじこlp

Author:ふじこlp
はてなブログへ移行しました。https://higechira.hatenablog.com/

ゆとりの大学生です。どれくらいゆとりかというと土曜日に通常授業を受けたことがただの一度もありません。

IBM時代のT43は観賞用となりましたが、X61は現役。
スクエアThinkPad X Series 最高です。
MacBook Pro 始めました。がやはりThinkPadに勝る打ち心地は存在しませんね。

カレンダー

10 | 2019/11 | 12
- - - - - 1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30

天気予報


-天気予報コム- -FC2-

フリーエリア

ブロとも申請フォーム

QRコード

QR

アクセスカウンター