SSGとperlさえあればウェブサイトなどサクッと作れてしまうんじゃないのか？ (SSG side)

この記事は、
[Static Site Generator Advent Calendar 2020](https://qiita.com/advent-calendar/2020/static-site-generator)の17日目の記事です。
同時に、[Perl Advent Calendar 2020](https://qiita.com/advent-calendar/2020/perl)の [17日目の記事](https://qiita.com/doikoji/private/20c7078929f5a51a6183)の姉妹版でもあります。両記事の内容に一部重複があることをご了承ください。

# はじめに

## SSGが行なう仕事はperlが得意とする分野である

静的サイトジェネレータ(SSG)の役目は、煎じ詰めれば、HTML形式で書かれた型紙ファイルに別ファイルから供給されたデータをあてはめて成熟HTMLファイルを生成することです。要は、ファイルへのデータ入出力、文字列データの置換・加工。数あるプログラミング言語の中で、こうした作業をもっとも得意とするもののひとつがperlです。

perlに馴染みがない方のためにその特徴を列挙するとすれば以下のようになるでしょう。

* 「型」に固定されない変数とハッシュ（連想配列）・配列のサポートにより、複雑なデータ構造を柔軟に管理できる。
* 強力無比な正規表現のサポートにより、複雑な条件でのテキスト検索と置換が容易に実現できる。
* 様々な省略記法が使え、複雑な手順が驚くほど短い字数で書ける。
* 文字列の処理速度はスクリプト言語としては相当速い。
* 様々なライブラリが開発され公開されており、それらを使えば「何にでもなれる」。



# perlベース静的サイトジェネレータいろいろ

* Giblog
* Dapper
* Statocles
* templer
* Newcomen
* MovableType

詳細については[姉妹記事](https://qiita.com/doikoji/private/20c7078929f5a51a6183)に譲ります。

どのソフトも基本的な機能は実装されています。どれもSSGとしての運用実績を持ち、エンドユーザーとして利用するなら、細かな仕様にユーザの好みが合致するか否かだけの話。

プログラマ・エンジニアとして、一品もののユニークSSGを作りたいという願望を持っている人も居るのではないでしょうか。そういう人にはとりあえず[Dapper](https://jamstack.org/generators/dapper/)を触ってみることをお勧めします。

## MDwiki -- このシンプルだが魅力あるシステム

[MDwiki](http://dynalon.github.io/mdwiki/#!index.md)はユニークです。なにしろ本体はたった一つのhtmlファイルのみ。オプショナルなものを含めても、10に満たないファイルで完結しているシンプルなシステムです。markdownファイルをおいておけば、htmlファイル内に書かれているjavascriptによって、クライアント側のブラウザ内で都度コンテンツを作られる仕組みです。

本体htmlファイルの機能により、最低限の「サイト」としての体裁は作れます。とはいえ、用意したmarkdownファイルについて1:1対応のhtmlデータが入手できるだけで、一覧ページやカテゴリページなどのサポートもありません。

しかし、既存markdownファイル群を読んで、インデックスmdやカテゴリmdを自動生成できれば、ブログっぽいサイトを構築することもできそう。階層的カテゴリをサポートし、カテゴリごとに関連記事をまとめる仕組みを追加すれば、ウィキペディア的なサイトを作ることもできるでしょう。

MDwikiは階層的に作られたサブディレクト内に作られたmdファイルにも対応してくれるので、記事ファイルは作成日ごと・トピックごとのフォルダに作ることにすればいいでしょう。ブログなら前者、ウィキペディアなら後者の形式をフォローすればよい。

### perlをヘルパーとして活用

既存ファイル群から必要な情報を拾い集め、集約し、ファイルとして吐き出す。こういう作業こそ得意とするのがperl。そう、perlなのです。

たとえば、以下のようなperlスクリプトを実行すると、年・月ごとのサブディレクトリが出来て、その中にテンプレートが書き込まれ、現在時刻に基づくファイル名を持つmarkdownファイルが出来上がります。

```
use strict;
use warnings;
use utf8;
use File::Path;
use Time::Piece;

my $lt  = localtime;
my $dir = sprintf("%04d/%02d", $lt->year, $lt->mon);
(-d $dir) or mkpath($dir);
my $outfile = $lt->strftime("$dir/%Y%m%d_%H%M%S.md");
print STDERR "Create $outfile\n";
open(my $fho, '>:utf8', $outfile) or die "Failed to create $outfile";
print {$fho} << 'EOD';
# Title

## Summary

## Details

## Summary, again

EOD
```

このmdファイルの中身には`mdwiki.html#!2020/12/20201211_044355.md`のようなURLでアクセス可能になります。

### インデックスページは割と簡単に作れそうだ


さらに次のようなスクリプトを実行すると、各月のサブディレクトリ内に記事一覧ページ(index.md）ができます。

```
use strict;                                                                                                   
use warnings;                                                                                                   
use utf8;

foreach my $dir_year (grep {-d $_} <????>){
  foreach my $dir_month (grep {-d $_} <${dir_year}/*>){
    print STDERR "${dir_month}\n";
    open(my $fho, '>:utf8', "${dir_month}/index.md");
    print {$fho} "記事一覧 （${dir_month}）\n\n";
    foreach my $file (<${dir_month}/*.md>){
      print {$fho} "* [$file](mdwiki.html#!$file)\n";
    }
    close $fho;
  }
}
```
いちおうブログっぽいものが作れてしまいました。これを作りこめば……。

# まとめ

公開されているSSGを概観すると、基盤となる言語やライブラリやOSには確かにある程度のバリエーションがあるし、性能面でも違いがあるのでしょう。けれども、機能面では大きな違いはないように思えます。

一方で、ウェブで訴えたいことは千差万別のはず。特定機能に激しく特化した、尖ったSSGがもっと存在していてよいのではないでしょうか。

そこでperlなのです。テキストベースの仕事であれば、細かいことを気にせず超短期間で何とか動くものが作れてしまうのがperlの魅力。斬新な発想でユニークなサイト構築を考えた時、perlの長所は大いに活かせるのではないでしょうか。もっとみんなでゲリラ的にいろんなSSGを作って見せ合おうじゃありませんか。