このサイトは非公式の日本語訳です。Cloudflare・EmDashプロジェクトが運営するサイトではありません。

このページで分かること

  • EmDashのサイトを構成する部分(管理画面、Astroのページとコンポーネント、EmDashのランタイム、SQLデータベース、メディアストレージ)と、それぞれのつながり
  • Astroで必要な設定(output: "server"、アダプター、ReactとEmDashのインテグレーション)と、ページがコンテンツを取得する仕組み
  • コンテンツモデルの変わり方と、プラグインがランタイムを拡張する方法
難易度
基礎
読む時間
3分
前提知識
AstroとはCMSとは
このページの目次

EmDashは、Astroのアプリケーションの中で動きます。公開ページと管理画面は、EmDashのランタイム、データベース、メディアストレージを共有します。フロントエンドと別のCMSサービスという関係ではなく、1つのデプロイされたアプリケーションの一部です。

EmDashのサイトを構成する部分

次の表は、各部分がEmDashのランタイムを通じてどのようにつながるかを示します。

部分 役割 つながり
管理画面 エントリーとメディアを保存する 変更をEmDashのランタイムに送る
Astroのページとコンポーネント 公開サイト用にエントリーを取得する EmDashのランタイムを通じてコンテンツを読み込む
EmDashのランタイム コンテンツモデル、公開のルール、取得、プラグイン、APIの動作を適用する データベースとメディアストレージを読み書きする
SQLデータベース コンテンツモデル、エントリー、ユーザー、設定、そのほかのレコードを保存する EmDashのランタイムが使う
メディアストレージ アップロードされたファイルを保存する EmDashのランタイムが使う

編集者は、管理画面でコンテンツを扱います。サイトの開発者は、Astroのページとコンポーネントを書いて、そのコンテンツの見せ方を決めます。どちらも同じコンテンツモデルを使います。コンテンツモデルとは、各エントリーを表すコレクションフィールドの定義です。

データベースには、コンテンツモデル、エントリー、ユーザー、設定、そのほかのCMSのレコードが保存されます。アップロードされたファイルは、メディアストレージのアダプターが保持します。エントリーのメディアフィールドは、ファイルのデータそのものをコンテンツのテーブルに入れるのではなく、保存されたメディアの項目を参照します。

本サイトの補足 やさしい解説

WordPressでは、PHPのテーマと管理画面(wp-admin)が1つのWordPressの中で動き、同じデータベースを使います。EmDashも同じく、公開ページと管理画面が1つのアプリケーションの中にあり、同じデータベースとメディアストレージを使います。違うのは、公開ページを作るのがPHPのテーマではなく、Astroのページとコンポーネントである点です。管理画面で保存した内容も、Astroのページが読み込む内容も、すべて「EmDashのランタイム」を通ります。

Astroで設定すること

管理画面、APIのルート、最新のコンテンツは実行時に配信されるため、EmDashのサイトにはサーバーでの描画(サーバーレンダリング)が必要です。Astroに output: "server" と、デプロイ先のプラットフォーム用のアダプターを設定します。

Astroの integrations の配列に、ReactとEmDashの両方を登録します。Reactは管理画面をハイドレーションします。@astrojs/react をインストールしていても、配列に react() がない場合、管理画面のページは Loading EmDash... のまま止まります。

次のNode.jsの例では、SQLiteのデータベースとローカルのメディアストレージを指定しています。

astro.config.mjs
import node from "@astrojs/node";
import react from "@astrojs/react";
import { defineConfig } from "astro/config";
import emdash, { local } from "emdash/astro";
import { sqlite } from "emdash/db";

export default defineConfig({
	output: "server",
	adapter: node({ mode: "standalone" }),
	integrations: [
		react(),
		emdash({
			database: sqlite({ url: "file:./data.db" }),
			storage: local({
				directory: "./uploads",
				baseUrl: "/_emdash/api/media/file",
			}),
		}),
	],
});

このインテグレーションでは、ほかの対応済みのデータベースやストレージのアダプターも使えます。storage を省略した場合はローカルのストレージのアダプターがデフォルトになりますが、本番環境では、アプリケーションのリリースやインスタンスをまたいで保持されるストレージが必要です。使えるアダプターとオプションは、設定リファレンスを参照してください。

ページがコンテンツを取得する仕組み

src/live.config.ts は、EmDashのローダーをAstroのライブコンテンツコレクション(Live Content Collection)として登録します。

src/live.config.ts
import { defineLiveCollection } from "astro:content";
import { emdashLoader } from "emdash/runtime";

export const collections = {
	_emdash: defineLiveCollection({ loader: emdashLoader() }),
};

ページは、一覧の取得には getEmDashCollection() を、1件のエントリーの取得には getEmDashEntry() を呼び出します。次のクエリは、ページの描画時に投稿を読み込みます。

src/pages/posts/index.astro
---
import { getEmDashCollection } from "emdash";

const { entries: posts, error } = await getEmDashCollection("posts");

if (error) throw error;
---

<ul>{posts.map((post) => <li>{post.data.title}</li>)}</ul>

サーバーで描画するページは、設定したキャッシュの影響を受けつつ、リクエストが来るたびにこのクエリを実行します。事前に描画するページ(プリレンダリング)はビルド中にクエリを実行するため、次にビルドするまで、あとからの編集は表示されません。

本サイトの補足 やさしい解説

WordPressのテーマでは、WP_Query などで投稿を取り出してテンプレートに表示します。EmDashでは、Astroのページの中で getEmDashCollection()(一覧)や getEmDashEntry()(1件)を呼び出して、コンテンツを取り出します。サーバーで描画するページは、アクセスがあるたびに取り出すため、管理画面で公開した変更がすぐに表示されます。事前に描画したページは、もう一度ビルドするまで変わりません。

モデルの変わり方

管理者は、管理画面でコレクションとフィールドを作成できます。EmDashはデータベースのスキーマを変更し、以降のエントリーと取得が新しいモデルを使うようにします。シードファイルは、別の環境で使う初期のモデルを、バージョン管理できる形で記述する手段です。生成されるTypeScriptの型宣言は、開発者がコードの中で現在のモデルを使うのに役立ちます。

これらのツールは、同じモデルを記述・変更するもので、並行する別のコピーを作るものではありません。作業の流れと、データを安全に保つための境界については、コンテンツモデルを参照してください。

プラグインによるランタイムの拡張

プラグインは、コンテンツやメディアのイベントに反応したり、APIのルート、設定、管理画面の画面を追加したりできます。ネイティブ型プラグインは、ホストのアプリケーションと同じアクセス権を持って動きます。標準形式のプラグインは、サイトがサンドボックスランナーを設定し、権限(Capability)を付与している場合、隔離されたランタイムで動かせます。プラグインをインストールしたり作ったりする前に、プラグイン形式の選び方を読んでください。