Hexo 備忘録 タグクラウドの見た目を変えたい

方針

tags.njkで使っているtagcloudは第一引数にtagsを取れるはずなので、そこでフィルタリングしたものを渡してみる

問題

{% set array = [] %}で配列を作って渡すとエラーを吐く。site.tagsと構造が違うのかもしれない
公式サイトではarrayと言っているんだけど、これがNunjacksで作れる配列とイコールかは不明。

解決策

enjine.jshelperとしてメソッドを追加する
hexo.extend.helper.registerを使えば、任意のJavaScript関数を埋め込むことができる。

1
2
3
4
5
6
7
8
// engine.js
hexo.extend.helper.register('filter_tag', function(tags, regTxt){
const regExp = new RegExp(regTxt);
return tags.filter(it => regExp.test(it.name));
});

// tags.njk
tagcloud(filter_tag(site.tags, "ここに正規表現"), ...

調査ログ

site.tags の出自

多分、hexo/lib/hexo/index.jsで作っているDatabaseからなんやかんや生成している気配を感じる
なお、内部的にはwarehouseDatabaseを使っている模様。
db.jsonTag以下にあるものをもとに引っ張りだしてくるgetter関数を定義して、それがLocales経由でobjectになっている。

実態としてはDatabaseに対してクエリを飛ばした結果であるdb.model('Tag').filter(tag => tag.length)であると思われる。

site.tags に上書きしてよいか

良くない。なぜならsite.tagsは共有化されたものなので

ではどうするか

site.tagsはこれまでの情報からwaterhouseQueryであることが分かっている
つまり、上記のゼロ参照タグをはじくためにも使っているfilterが使える
それを返せば、それは同じくQueryだし、破壊的変更にもならない

追加でやりたいこと

mapでタグ名を編集したかったんだけど、mapの返り値が配列なので使えない
なので、dataを直接いじってみる

以下だと、tagsに破壊的変更を加えることになる
多分そのページ単位で閉じるので影響は軽微だけど、何とかしたいところ

1
2
3
4
const regExp = new RegExp(regTxt);
let result = tags.filter(it => regExp.test(it.name));
result.forEach(it => it.name = it.name.replace(regExp, ""));
return result;

以下で一応回避できる。なんとなくまずい気もするけど、問題が起きてから考える。

1
2
3
4
5
6
7
8
9
let result = tags.filter(it => regExp.test(it.name));
result.data = result.data.map(it => {
let mapRet = {};
for (var elem in it) {
mapRet[elem] = it[elem];
}
return mapRet;
});
result.forEach(it => it.name = it.name.replace(regExp, ""));