Chienomi

新サイト Signal & Marginalia

開発::website

新しいウェブサイト、Signal & Marginaliaをオープンした。主にオーディオの話をするためのブログだ。

オーディオの話、Chienomiでもしたことがあるし、Piecesでもしたことがあるのだけど、色々なことを考えた結果、別サイトとして独立させることにした。

今回は専用のドメインを取って専用のアイコンを購入、かなり気合が入っているが、なにせデバイスを買わないと基本的に新しい記事が書けないので、そんなに頻繁に更新されるものでもない。

が、気合が入っているので私のサイトとしては新世代のお披露目となっている。

動的要素は動的に

これまでの話

前提として、PureBuilderはSSR的な世界観をもとに作られている。

初期ACCSなんかはHTML手打ちしていた時代に「テンプレートが欲しい」と思って始めているから違うけれど、PureBuilderシリーズになったときには基本的にWordPressを意識したものになっていた。

つまり、PureBuilderの根本的な世界観はSSR vs SSGである。 これはPureBuilder Simplyにも継承され、強力なfrontmatterとテンプレートの組み合わせで動的要素も予め生成してしまうことに重きを置いている。

しかし私はアプリケーションではSPAが好きだ。 より正確にはMPA/マイクロフロントエンド的アプローチを好む。 どちらにせよ、ガワとデータが分離している形式だ。

イニシャルロードにおいては、ページの構成要素とページの骨格、そしてロード操作を行うためのスクリプトをダウンロードする。 コンテンツはスクリプトの制御によってロードされる。

モダンウェブブラウザを想定する場合、この仕組みは非常に美しい。 その考えのもと作られたのがはるらぼである。

だが現実は非情。 はるらぼは検索インデックスの問題に阻まれてしまい、結果的にイニシャルページにコンテンツを含む形式とするハイブリッドSPA形式に変更された。

これはMewductでも同じようなことになっていて、ウェブサイトをSPAで構成するのはあまり良くない気がする、という結論に達した。 いや、良くないわけではないのだが、検索エンジンやソーシャルシェアのことを考えると好まれないのだ。

PureBuilder Simplyの弱みと進化

ところでPureBuilder Simplyを運用していて面倒な点は何かというと、リビルドである。

PureBuilder SimplyはjekyllやHugoと異なり、差分ビルドを重視している。 これにより、非常に記事数が多いウェブサイトも運用可能だ。

これは明確な強みなのだが、この強みが活かせないケースがテンプレートの更新だ。

「そもそもあまりテンプレートをいじることはないのだから、テンプレート更新によるリビルドは許容できる」という考え方も普通にあるのだけど、これは「テンプレートに依存しているので頻繁に(あるいはリアルタイムに)変わる要素を組み込みにくい」という、一種の制限になっていた。

これについては「必要であればJavaScriptを使うことで越えられる」としてきたが、あくまでJavaScriptをoptionalにしたい私からすれば例外的な運用であるというスタンスだった。

しかし、JavaScriptの発展は、これを例外的な運用とするよりも、PureBuilder Simplyのスタイルを拡張するように使うほうが良い、と私は考えた。

事前ビルドにJavaScriptによる動的更新要素を埋め込むという方式はすでにいくつか試しているし、Chienomiでも部分的に採用されている。 だが、私の文章系ウェブサイトで採用されているのは、既存のアプローチの置き換えである。 それを最初から設計として組み込んだ最初の例が、Signal & Marginaliaだ。

Signal & MarginaliaにおけるJavaScript

もっと凝った方式をとったウェブサイトも準備中だが、Signal & Marginaliaではかなり小さなスクリプトをロードしている。

これはChienomiでも採用されているアクセシビリティスクリプトに属するものだが、さらに加え動的コンテンツのロードという役割も持っている。

非常に限定的な話だが、「最近の記事」がそうだ。

PureBuilder Simplyの場合、基本的にrecent articlesはページ側に持つのが基本だ。 テンプレート側に持ってしまうと、記事更新のためにリビルドが必要になるからだ。

だがページデザインとして、recent articlesはサイドバーに置きたいということは多々ある。 ユーザーに好まれる機能ではないが、検索エンジンへの依存度を下げるには必要だ。

Signal & MarginaliaではここがJavaScriptによってコンテンツをロードする方式になっている。 コンテンツはJSONで、シンプルなスクリプトで作られている。

#!/bin/env ruby
require 'date'
require 'json'
articles = []

%w:articles:.each do |i|
  data = Marshal.load File.read File.join(i, ".indexes.rbm")
  articles.concat data.values
end

File.open("../Build/meta/recent.json", "w") do |f|
  f.puts JSON.dump(articles.sort_by {|i| [i["date"], i["_mtime"]] }.reverse[0, 10].map {|i| {"title" => i["title"], "path" => i["page_url"], "date" => i["date"]} })
end

これがアップデートスクリプトから呼ばれることで自動的に更新される。

ページからはこのようになっている。

function getRecent() {
  const ul = document.getElementById("RecentArticles")
  fetch("/meta/recent.json").then(async res => {
    const data = await res.json()
    data.forEach(i => {
      const li = document.createElement("li")
      const a = document.createElement("a")
      a.href = i.path
      a.textContent = `${i.title} (${i.date})`
      li.appendChild(a)
      ul.appendChild(li)
    })
  })
}

極力簡潔にした形だ。

ナチュラルメイク的デザイン

Signal & MarginaliaはPureBuilder Simplyの公式テーマであるpandoc/paperをベースにしたデザインとなっている。

非常にシンプルなデザインに見えるが、実は案外凝っている。

まず、全体はpaperテーマと同じように赤みがかっているのだが、この色味はpaperよりも白に近く調整されている。

その上でメインブロックの背景色は4段階グラデーションで、端は背景色と同じだが、内容はより白に近い。 コンテンツは場合によってはそれなりに色がつく(Signal & Marginaliaでは稀だが、特にコードブロックでは顕著)ことがあるため、白に近いほうが安定して見やすい。 ほかにもいくつかの理由があるが、グラデーションで内部は白に近づけるようにしている。

また、サイトタイトルの背景は白。タブは白に近い。

これもなかなかのトリック。 サイトタイトルは白なのだが、恐らく白に見えない。 これはタブの色と本文グラデの効果だ。

タブはアルファがついており、純粋に白ではない。 が、サイトタイトルが白に見えるとタブは白に見える。

ちゃんと背景を白にする効果は出ているのだけれど、注意深く見なければ気づかない。 けれど注意深く見ると明らかに意図的に加工されている。

言ってみればナチュラルメイク。

タブはFlex。 普通は数が増えたら……と考えるものだけど、このサイトはサイトの構造的にこれ以上増えないので、タブもこの構造固定でOK。

本文ブロックはGrid。 サイドバーが本文ブロックの中にある構造なのも今はそこまで珍しいことではないけれど、ちゃんとモダン。

フォント

引き続き欧文だけウェブフォントを採用。 サイトタイトルもウェブフォントによる表現。

見出しフォントは見栄え重視。 本文はserifで、サイトの性質上型番などを記載することが多いため、型番での可読性重視。

本文の和文は私イチオシのイワタUD明朝を指定。 おしゃれなかなCを優先で指定しているけど、ここは変更するかもしれない。

コンテンツ

冒頭で述べた通り、オーディオデバイスの話がメイン。

オカルトなし、サウンドディレクターの耳で正直に述べている。