なんでこういう状況に遭遇したか
JBake のテンプレートをFTLで書いていたのです。JBake なんて使っている人いないですよね、そうですよね。
まあそれは良いとして、その中でサイト内の記事で使われている全てのタグ一覧なんていう情報がありまして、これがどうやらJBakeが処理対象となる記事データをクロールして見つけた順に並んでいるらしいのです。並び順がばらばらです。
このまま出したら見た目悪いなあ。どんな順番でもいいから規則性のある並べ方にしとくか。
とか思って、FTLのビルドインを調べたのがことのはじまり。
え、なんでこれエラーなのさ?
というわけで、FreeMarkerのサイトを見るわけです。そうするとあるじゃないですかお目当てのビルドインが。
<#assign ls = ["whale", "Barbara", "zeppelin", "aardvark", "beetroot"]?sort>
<#list ls as i>${i} </#list>
aardvark Barbara beetroot whale zeppelin
数値、文字列、日付、ブール値ならソートしてやるぜ、?reverseもあるぜよ(意訳)。
そうそう、こういうのでいいんです。FTLは知らないナニカがたくさん隠れているので油断なりません。誰かドキュメント翻訳してくれませんかね。英語だと読めなくはないけれど目が滑るので。
というわけでスピード解決だぜと思って、以下のような記述をしてBakeするわけです(JBakeではサイトコンテンツの変換・生成処理のことをBakeすると呼称します)。
<#-- ソートして出力(?sort足しただけ) -->
<#list alltags?sort as tag>
<span>${tag}</tag>
</#list>
そしたら思わぬ例外メッセージですよ奥さん。
Failed to render file. Cause:
freemarker.core.NonSequenceException:
For "?sort" left-hand operand:
Expected a sequence, but this has evaluated to a collection
(適当に略)
要するに「それSequenceじゃないから?sortとか使えないし?(意訳)」って言いやがるわけですね。なんだよそれ、ソートが実装されてるのにCollectionで使えないとか意味わからないよ!?
まあこうすれば動きますが
<#-- Sequencesに入れ直し -->
<#assign seq=[]/>
<#list alltags as tag>
<#assign seq=seq+[tag]/>
</#list>
<#-- ソートして出力 -->
<#list seq?sort as tag>
<span>${tag}</tag>
</#list>
リスト、配列要素なんて<#list>で回すくらいしかしていなかったので、まさかSequenceとCollectionにこんな差異があるなんて思ってませんでした。
っていうか?sort、実装おざなりだと思うの。