NKSSG
NakaKen Static Site Generator

内部リンクを使おう

🔗

ここでは、記事内から別の記事へリンクを貼る方法を見ていきます。内部リンクを簡単に扱えるプラグインを使います。

内部リンクに関する問題点

記事を書いているときに、他の記事へリンクを貼りたいこともあるでしょう。ところが、ここで少し問題が起きます。リンク先の指定をどうするか、が難しいのです。

例えば、次のような構成になっていたとします。

docs
└── post
    └── 2021
        ├── 20210401.html
        └── 20210402.html

一方、URL を反映した構成が次のようになっていたとします。パーマリンク を /%Y/%m/%d/ に設定した前提です。

public
└── post
    └── 2021
        └── 04
            ├── 01
            │   └── index.html
            └── 02
                └── index.html

このとき、docs 内の 20210401.html で <a href="./20210402.html">リンク先</a> と書いていても、リンクは正しく処理されません。docs 内と public 内の構造が異なるためです。この場合、何も対策をしないなら<a href="../02/">リンク先</a>などと書いておく必要があります。

つまり、「リンク元とリンク先のファイルがどのような URL に変換されるかを把握しないとリンクが貼れない」ということです。これはかなり面倒です。

内部リンク管理プラグイン

ファイル出力後の構造を想像しながらリンクを設定するのは大変です。それに、パーマリンクを変えるたびに、リンクタグもすべて見直さないといけません。パーマリンクを変える機会は少ないかもしれませんが、もし変えたくなったら大変です。

そこで、NKSSG では、内部リンクを簡単に管理できるプラグインを用意しています。nkssg.ymlのプラグインの設定(plugins のところ)を見てみると、awesome-page-linkがリストに入っているはずです。これが内部リンク管理プラグインです。デフォルトでは有効になっています。

これを使うとどのように管理が楽になるのか、見てみましょう。

file_idを使う方法

一番簡単な方法は、記事にfile_idをつける方法です。file_id の設定は、フロントマター で次のように行います。

file_id: sample

file_idは数字である必要はなく、文字でも構いません。ただし、このfile_idは、サイト内で重複してはいけません。複数の記事で同じ値の file_id を設定すると、エラーになります。

file_idを設定すると、他の記事から次のように呼び出すことができます。

【HTML の場合】
<a href=":sample?">リンク先</a>

【Markdown の場合】
[](:sample?)

リンクの部分を「:」からはじめ、最後を「?」にします。この間の部分に、file_idを入れます。このように書くと、NKSSG は、この値をfile_idに設定している記事を探します。そして、この記事へのリンクに変換されます。

先ほどの例であれば、20210402.html のフロントマターで file_id: 20210402 とし、20210401.html の内部で次のように書いたとします。

<a href=":20210402?">リンク先</a>

こうすると、20210402.html がどのような URL に変換されても、20210401.html 内のこのリンクは、正しい URL に変換されるようになります。

相対パスを使う方法

file_idを設定するのが面倒だ、という人には、ファイルの相対パスを使う方法もあります。例えば、次のようにします。

【HTML の場合】
<a href="./20210402.html?">リンク先</a>

【Markdown の場合】
[](./20210402.html?)

最後を「?」にする点は同じです。これが変換対象であることの証になっています。

docs 内のフォルダ構成を変えるとリンクも変える必要が出てきますが、file_id を設定しなくても使えるので楽です。

絶対パスを使う方法

相対パスではなく、絶対パスを使う方法もあります。docs からのパスを指定します。例えば、次のようにします。

<a href="/post/2021/20210402.html?">リンク先</a>

ただ、例えば、VSCode でリンクを入力するときに補完を使う場合、"/" を入力したら、ワークスペースからの絶対パスになってしまいます。これをわざわざ docs フォルダからのパスにするのは面倒ですね。そこで、次のような機能が入っています。

  - awesome-page-link:
      strip_paths:
        - /docs

この strip_paths は、絶対パスで内部ページリンクを入力したときに、頭の部分からパスを削除してくれる機能です。この設定では、/docs が頭に着いていれば、それを削除してから、変換処理を行います。このパスは、リスト形式で複数追加できます。上から順番に削除処理が行われます。

このような機能を用意していますが、絶対パスは docs フォルダ内の構造が変わったときに変更しないといけない部分が多くなるので、あまりオススメはしません。

どんな処理が行われている?

参考までに、この内部リンクプラグインで、どのような処理が行われているかを説明します。コードはコチラにあります

まず、各記事ページ・アーカイブページに対して、aタグのhrefをすべてチェックします。このとき、最後に「?」があれば、変換対象だと認識します。

変換対象のものに対して、リンクを計算します。「:」から始まっているなら、file_idを検索します。「:」から始まっていない場合は、strip_pathsで設定したテキストを削除してファイルを探します。

対象のファイルが見つかれば、それがどんな URL に変換されるかを特定します。そして、もとの href を書き換えます。

このようにして、内部リンクの書き換え処理が行われています。