ぽよメモ

レガシーシステム考古学専攻

Entrykitのrenderで遊ぶ -後編-

頑張りすぎじゃ無いか感が溢れてきます.

発展的な記法

環境変数からの値の取得しか存在しないわけでは無く,色々できます.

include

これは比較的便利に扱えるのでは無いでしょうか,templateのモジュール化ができます.また,第二引数以降に"VAR=VALUE"の形で渡すと,includeするtemplateの中からvar "VAR"などとして値を取り出すことが出来ます.

ここではecho '{{ var "INCLUDED" }}' > include_test.tmplとしてincludeするtemplateを作成しておきます.

{{ include "include_test.tmpl" "INCLUDED=True" }} # -> True

file, text

ファイルの中身を読みとって文字列として展開します.例えばecho "hello world" > hello.txtとしてテンプレートと同じ階層に置いたとします.

# file
{{ file "hello.txt" }} # -> hello world

# text
{{ text "hello.txt" }} # -> hello world

ソースを読む限りこの二つの内部的な実装は全く同じに見えます*1

dir, dirs, files

引数として任意のディレクトリへのパスを渡します.文字列を返すわけでは無いことに注意してください.

# 指定されたディレクトリ中のディレクトリ・ファイルの名称の配列を返す
{{ dir "./" }}

# 指定されたディレクトリ中のディレクトリのみの名称の配列を返す
{{ dirs "./" }}

# 指定されたディレクトリ中のファイルのみの名称の配列を返す
{{ files "./" }}

存在しないディレクトリを参照しようとするとnot foundなエラーを発して中断します.

httpget, urlquery

APIリクエストしたりすることができます*2ca-certificatesをインストールしていないとエラーを吐いて死にます.

{{ httpget "http://search.twitter.com/search.json?lang=ja&rpp=20&q=%23poyo" }}

注意すべきなのは,返すオブジェクトが文字列では無いことでしょう.Goのオブジェクトが返却されるため,htmlがそのまま出力されるわけではありません.

json, tojson

ではAPIリクエストしたところでどうするんだという話ですが,これでjsonオブジェクトに変換できます.

{{ httpget "http://search.twitter.com/search.json?lang=ja&rpp=20&q=%23poyo" | json }}

これもまた返り値はGoのオブジェクトなのでノイズが混ざっています.純粋にレスポンスを記述するだけなら以下の様にします.

{{ httpget "http://search.twitter.com/search.json?lang=ja&rpp=20&q=%23poyo" | json | tojson }}

tojsonはgoのオブジェクトを受取り,jsonをstringにして返します.

yaml, toyaml

jsontojsonyaml版です.

split, join

stringから配列を生成することができます.

# 配列の生成
{{ split "a,b,c,d" }} # -> [a, b, c, d]

# 任意のセパレータで区切った文字列に変換
{{ split "a,b,c,d" | join ":" }} # -> a:b:c:d

splitkv, joinkv

少し難解で使いどころがよく分からないですが,splitjoinが配列を扱うのに対してmapを扱います.

# mapの生成
{{ split "\n" "a=A,b=B,c=C" | splitkv "=" }} # -> [a=A b=B c=C] 

# mapの値へアクセス
## mapを変数へ代入
{{ $map_var := (split "\n" "a=A,b=B,c=C" | splitkv "=") }}
 ## アクセス
{{ $map_var.a }} # -> A
{{ $map_var.d }} # -> <no value>
## 代入はできないようでエラーを吐く
{{ $map_var.d := "D" }} # -> unexpected ":=" in operand

# 任意のセパレータで文字列にする
{{ joinkv ":" $map_var }} # -> [a:A b:B c:C]

joinkvは直接文字列を返すわけではなく,key{{任意のセパレータ}}valueの形で文字列化し,その配列を返します.全体を文字列にするにはさらにjoinをはさむ必要があります,

seq

数値の配列を作成します.引数に数字(intまたはstring)をとり,0からその値までの配列を作って返します.

{{ seq 10 }} # -> [0 1 2 3 4 5 6 7 8 9 10]

append, drop

配列のへの値の追加,削除ができます.

# 数値でも
{{ seq 10 | append 11 | drop 1 }} #-> [0 2 3 4 5 6 7 8 9 10 11]

# 文字列でも
{{ split "," "a,b,c,d" | append "e" | drop "a" }} # -> [b c d e]

index

配列への添字アクセスができます.

{{ index (seq 5) 1 }} # -> 1

第一引数に配列を取ることに注意が必要です.また,index {{任意の多次元配列}} 1 2 3などは{{任意の多次元配列}}[1][2][3]と同義になります.

sh

もはやなんでもありですが任意のコマンド実行が出来ます.出力された値が文字列として取得できます.

{{ sh "ping -c 1 www.google.com" }}

sigilにはあるが使えなかったもの

  • jmespath

jsonからクエリを使って値を取り出すことができるようなのですが,renderではnot definedと言われてしまいました.

組み合わせる

ファイル一覧でループ

配列の生成ができることから,色々なループ処理が可能になります.例えば任意のディレクトリ内のファイル一覧に対して,*.logの場合には監視対象に加える,などといった処理が可能になります.

{{ range $index, $f := (files "/path/to/log") }}
{{ if match $f "*.log" }}
    something $f to do
{{ end }}

環境変数を判定

()を用いるとだいたいなんでもできるので,例えば環境変数も(どっかのQiitaではできないとか書いてましたが)ifで用いることが出来ます

{{ if eq "test" (var "TEST") }}
  This is test.
{{ else }}
  This is not test.
{{ end }}

まとめ

もっと色々やろうかと思ったけど力尽きた.

*1:textの方は何かエラー処理のコードが入っていますが,エラーがnilかどうかを判定して受け流しているだけのように思います.

*2:例ではTwitter API 1.0を使用しているので普通にエラーメッセージが返ってきます