このサイトは WordPress で運営していますが、WordPress の重さに辟易して、Jekyll を使いたい人も少なからずいると思います。そんな時に、WordPress から Jekyll に引っ越ししようと思ったら、かつての投稿データを、Jekyll で書き出すためにマークダウンで書き直したり、あるいは HTML のまま不要部分を消して、必要部分を書き足すような作業が必要になります。
今回のミッション
- Jekyll のテンプレートで正規表現置換を行う
設定環境
ruby 2.6.4p104 (2019-08-28 revision 67798) [x86_64-cygwin]
jekyll (4.1.0)
liquid (4.0.3)
Jekyll で正規表現を使いたい
もともとの WordPress の投稿データを HTML ファイル(あるいはマークダウン)にして Jekyll に食わせて、サイト全体を書き出す場合に、いくつか問題になることがあります。
次のような例をあげてみます。WordPressでよく出てくるショートコードを多用してページを書いている場合の例です。
_posts
<p>[itemlink post_id="1234"]</p>
_posts フォルダ(ディレクトリ)以下に置いた HTML もしくはマークダウンファイルの中身に、一部上のようなショートコードが残りました。これを速攻で消し去りたい場合は少し考えます。
まず、html タグを処理する
<p>や</p>を消し去る程度なら簡単です。トップページの index.html で投稿の抜粋を処理する場合は、以下のように "strip_html" で処理すれば、html タグはすべて無効にしてくれます。
_posts
{{ post.excerpt | strip_html }}
しかし、肝心の「[itemlink post_id="1234"]」がそのまま残ってしまい、消えてくれません。
Liquid の標準フィルタでは正規表現が使えない
とにかく、上のようなWordPress のショートコードが残ってしまい、速攻何とかしたいという場合、誰もが考えるのが、書き出し時に正規表現で一気にゴミ取したデータを出すという方法です。
単純な静的置換は以下のように簡単に処理できますが、
{{ '[itemlink post_id="1234"]' | replace:'itemlink post_id=','' }}
# これは '["1234"]' に置換される
id の部分が数字で埋まっている場合は、すべて消すというような処理ができません。
例えば、以下のように書いて一気に処理したくなります。
{{ '[itemlink post_id="1234"]' | regex_replace:'\[itemlink post_id="[0-9]+"\]','' }}
# これですべて消せる?
Jekyll と Ruby は密接なので、正規表現など当たり前のように使えそうに思いがちですが、意外とそうでもありません。
上の例のように便利なことはできません。
とにかく自分で正規表現置換を組み込む
実のところ、Liquid で正規表現がサポートされている説が 2015年ごろあったのですが、今現在でも自分の環境(最新モジュールにアップデート済み)ではうまくいっていません。やむを得ず、無理やり組み込んで正規表現置換を使用することにします。
よくある例になりますが、やってみたい例として、
{{ foobar | regex_replace: '(\S+)baz', 'qux\1' }}
{{ post.excerpt | regex_replace: '(\S+)baz', 'qux\1' }}
のような書き方が、すぐにサポートされるされることを期待していましたが、その気配もなく、今後どうなるか不明ですので、自分のローカル環境に組み入れてしまいます。
どこの standardfilters.rb を書き換える
Ruby の強力な正規表現を拝借するだけなので、大した処理でもく、自分の環境だけに組み込むなら簡単です。
ファイルを置いた vendor\bundle
フォルダ(ディレクトリ)だけを触るようにします。
私の場合は、Windows の場合、C ドライブの C:\Users\tester\Documents\myblog
以下に置いていますので、触るファイルは以下のようになります。
上の「2.6.0」や「4.0.3」は使用しているバージョンに合わせて解釈してください。
Cygwin を使用している人は、
C:\Cygwin64\home\tester\.gem\ruby\2.6.0\gems\liquid-4.0.3\lib\liquid\standardfilters.rb
にも、standardfilters.rb がありますが、こちらは手を付けないようにします。
standardfilters.rb をどう書き換える
standardfilters.rb そのものは見やすいので、書き換え方は簡単です。
エディタで開いて、21 行目あたり(意味が変わらなければどこでもよい)に以下の構文を足すだけです。
standardfilters.rb
def regex_replace(input, regex, replacement = '')
input.to_s.gsub(Regexp.new(regex), replacement.to_s)
end
以上の書き換えが完了したら、_layouts ファルダ以下のテンプレートを編集したり、index.html などを編集して、正規表現置換の処理を記述します。
Jekyll を実行します。
背的表現置換の処理がしっかり行えるか確認します。
_layouts
{{ post.excerpt | regex_replace: '\[itemlink post_id="\d+"\]', ''}}
{{ post.excerpt | regex_replace: '(\S+)baz', 'qux\1' }}
この処理で、_post 内ファイルに例のようなショートコードが残っていたら、
「[itemlink post_id="1531"]」も「[itemlink post_id="1234"]」もそのまま消去されます。
「foobaz」 は 「quxfoo」に書き換えられます。
ショートコードの置換と、よくある foo の置換を例に挙げましたが、URL の書き換えなどにも当然応用できます。
最後に
今回は私的なメモ書きを兼ねていますので、Jekyll を使わない人には大変わかりにく内容と書き方になっています(それは十分認識しています)が、後々書き加えたり、関連ページを増やして応用できるように改変していきます。
Jekyll の Liquid については、正式に普通に正規表現が使えるようなバージョンに進化してほしいというのが本音です。
とりあえず、ミッション完了です。