Hashimoto   Baku

Hashimoto   Baku

garden.oooの情報設計

コンテンツパイプライン

ページの「本体」は Markdown のソースコードではなく、HTML の AST(抽象構文木)。

HTML の AST は現状は Nuxt MDC の MDCRoot を AST フォーマットとして使っているけれど、もう少し汎用的な表現にしたい。hastとか。unified エコシステムを使えば、Markdown に限らず HTML にパース可能な任意の軽量マークアップ言語をサポートできる。

サーバーに送信されるのは {source, ast, ...metadata} の組。AST の生成はクライアントサイドで責任をもつ。

この設計がもたらすもの:

  • Copy as Markdown: AST → Markdown の逆変換
  • PDF エクスポート: archival ページの永続的な文書化
  • カスタムパーサー: ユーザーが独自の記法を持ち込める

識別子の3層構造

ページには3種類の識別子がある。それぞれ異なる文脈で使う。

識別子用途
pathローカルのファイルパス。空白や記号をそのまま含むArticles/100% User Supported
uriURL として使える形式。空白→_、制御文字→エスケープArticles/100%25_User_Supported
slugDB 検索用の正規化キー。uri.toLowerCase()articles/100%25_user_supported

変換は path → uri → slug の一方向。逆変換は uri → path_ → 半角スペース)のみ可能。

slug が重複するページは作成できない。ローカルで衝突が起きた場合、後から検知された方はリネームされるまでリモートに同期されない。

関連コード:

  • utils/normalizeIdentifiers.ts — 識別子の変換
  • sanitizeTitleToPath — パスのサニタイズ
  • normalizeToSlug — slug の正規化

リンクとバックリンク

ページ同士の関連性はリンクで表現する。種類は2つ。

  • Tag linkA is B): frontmatter の tags や本文中の #tag_link 記法で表現。所属・包摂・共通性
  • Body linkA refers to B): 本文中のハイパーリンク。言及・参照

Tag link のほうが強い関連性を示す。

バックリンク

A → B のリンクがあるとき、B のページに「関連ページ」として A を自動表示する仕組み。有向グラフとしてのハイパーリンクを双方向にしている。

これで従来 CMS の「カテゴリ一覧」を代替できる。「チーム」というページに、メンバーの各ページから tag link を貼って、frontmatter で layout: grid を設定すれば、チームメンバー一覧ページになる。grid / table レイアウトでは body link のバックリンクが除外されるので、「チームについてはこちら!」みたいな無関係なページが混ざらない。

関連コード:

  • utils/markdown/collectOutlinksFromPage.ts — アウトリンク収集
  • types/page.tsLink{type: 'tag' | 'folder' | 'link', slug: string}

公開範囲

4段階ある。Frontmatterの visibility で設定可能。

  • public: 誰でも見える。リストに表示される
  • unlisted: URL直打ちか直リンクでのみ到達可能。リスト表示やバックリンクには現れない。「文脈を追わないとたどり着けない」状態を作る
  • protected: 認証(パスワード、OAuth 等)が必要。メンバーシップ制の限定コンテンツや有料配信(note/Substack 的な)を想定している。決済機能は未実装
  • private: 書き手だけが見える

関連コード: types/page.tsvisibilitySchema

Archival フラグ

公開範囲とは別軸で、すべてのページが持つフラグ。永続化したいものとエフェメラルなものを分ける。

  • Archivalarchival: true): 不変の URL で公開したいもの
  • Scratchpadarchival: false): 個人的なメモ。noindex, nofollowで検索エンジンにもインデックスされない。いつでも変更したり消せる

archival は明示的に true と書かなくても、layoutpage 以外だったり、特定のタグ(works, video 等)が付いていれば自動的に true に推定される(FrontmatterSchema の transform 参照)。