SQLite
sqlite({ url: "file:./data.db" })によるローカル開発
EmDashはAstroと深く統合し、完全なCMS体験を提供します。このページでは、主要なアーキテクチャ上の決定と、各要素がどのように連携するかを説明します。
┌──────────────────────────────────────────────────────────────────┐│ あなたのAstroサイト ││ ││ ┌────────────────────────────────────────────────────────────┐ ││ │ EmDash統合 │ ││ │ │ ││ │ ┌──────────────┐ ┌──────────────┐ ┌───────────────┐ │ ││ │ │ コンテンツAPI │ │ 管理 │ │ プラグイン │ │ ││ │ │ │ │ パネル │ │ │ │ ││ │ └──────────────┘ └──────────────┘ └───────────────┘ │ ││ │ │ ││ │ ┌──────────────────────────────────────────────────────┐ │ ││ │ │ データ層 │ │ ││ │ │ データベース (D1/SQLite) + ストレージ (R2/S3) │ │ ││ │ └──────────────────────────────────────────────────────┘ │ ││ └────────────────────────────────────────────────────────────┘ ││ ││ ┌────────────────────────────────────────────────────────────┐ ││ │ Astroフレームワーク │ ││ │ Live Collections · Middleware · Sessions │ ││ └────────────────────────────────────────────────────────────┘ │└──────────────────────────────────────────────────────────────────┘EmDashはAstro統合として動作します。管理パネルとREST APIのルートを注入し、ライブコレクション用のコンテンツローダーを提供し、データベースマイグレーションとストレージ接続を管理します。
コード内でスキーマを定義する従来のCMSとは異なり、EmDashはスキーマ定義をデータベース自体に保存します。2つのシステムテーブルがコンテンツ構造を追跡します:
_emdash_collections — コレクションメタデータ(スラッグ、ラベル、機能)_emdash_fields — 各コレクションのフィールド定義管理UI経由でタイトルと価格フィールドを持つ「products」コレクションを作成すると、EmDashは:
_emdash_collectionsと_emdash_fieldsにレコードを挿入ec_productsを作成するためにALTER TABLEを実行この設計により以下が可能になります:
各コレクションはec_プレフィックスを持つ独自のSQLiteテーブルを取得します:
-- Created when "posts" collection is addedCREATE TABLE ec_posts ( -- System columns (always present) id TEXT PRIMARY KEY, slug TEXT UNIQUE, status TEXT DEFAULT 'draft', -- draft, published, scheduled author_id TEXT, created_at TEXT DEFAULT (datetime('now')), updated_at TEXT DEFAULT (datetime('now')), published_at TEXT, deleted_at TEXT, -- Soft delete version INTEGER DEFAULT 1, -- Optimistic locking
-- コンテンツカラム(フィールド定義から) title TEXT NOT NULL, content JSON, -- Portable Text excerpt TEXT);単一のJSONコンテンツテーブルではなく、コレクションごとのテーブルを採用する理由は?
EmDashはAstro 6のライブコレクションを使用して、ランタイムでコンテンツを提供します。コンテンツ変更は静的リビルドなしですぐに利用可能になります。
emdashLoader()はAstroのLiveLoaderインターフェースを実装します:
import { defineLiveCollection } from "astro:content";import { emdashLoader } from "emdash/runtime";
export const collections = { _emdash: defineLiveCollection({ loader: emdashLoader() }),};提供されたラッパー関数を使用してコンテンツをクエリします:
import { getEmDashCollection, getEmDashEntry } from "emdash";
// 公開済み投稿をすべて取得const { entries: posts } = await getEmDashCollection("posts");
// 下書きを取得const { entries: drafts } = await getEmDashCollection("posts", { status: "draft",});
// スラッグで単一エントリを取得const { entry: post } = await getEmDashEntry("posts", "my-post-slug");EmDash統合はAstroのinjectRoute APIを使用して管理およびAPIルートを追加します:
| パスパターン | 目的 |
|---|---|
/_emdash/admin/[...path] | 管理パネルSPA |
/_emdash/api/manifest | 管理マニフェスト(コレクション、プラグイン) |
/_emdash/api/content/[collection] | コンテンツエントリのCRUD |
/_emdash/api/media/* | メディアライブラリ操作 |
/_emdash/api/schema/* | スキーマ管理 |
/_emdash/api/settings | サイト設定 |
/_emdash/api/menus/* | ナビゲーションメニュー |
/_emdash/api/taxonomies/* | カテゴリ、タグ、カスタム分類 |
ルートはemdashパッケージから注入され、プロジェクト内には何もコピーされません。
EmDashはサポート対象のすべてのデータベースで型安全なSQLクエリを行うためにKyselyを使用します:
SQLite
sqlite({ url: "file:./data.db" })によるローカル開発
D1
d1({ binding: "DB" })によるCloudflareのサーバーレスSQL
libSQL
libsql({ url: "...", authToken: "..." })によるリモートSQLite
データベース設定はastro.config.mjsで統合に渡されます:
import { defineConfig } from "astro/config";import emdash from "emdash/astro";import { sqlite } from "emdash/db";import { local } from "emdash/storage";
export default defineConfig({ integrations: [ emdash({ database: sqlite({ url: "file:./data.db" }), storage: local({ directory: "./uploads", baseUrl: "/_emdash/api/media/file", }), }), ],});メディアファイルはデータベースとは別に保存されます。EmDashは以下をサポートします:
アップロードは署名付きURLを使用して、クライアントからストレージへの直接アップロードを行い、Workersのボディサイズ制限を回避します。
プラグインはWordPressにインスパイアされたフックシステムを通じてEmDashを拡張します:
content:beforeSave、content:afterSave、content:beforeDelete、content:afterDeletemedia:beforeUpload、media:afterUploadプラグインは2つのモードで実行できます:
import { seoPlugin } from "@emdash-cms/plugin-seo";
emdash({ plugins: [seoPlugin({ maxTitleLength: 60 })],});典型的なコンテンツリクエストは以下の経路をたどります:
getEmDashCollection()がAstroのgetLiveCollection()を呼び出し 3. ローダー実行 —
emdashLoaderがKysely経由で適切なec_*テーブルをクエリ 4. データ返却 — エントリが
id、slug、dataを持つAstroのエントリ形式にマッピング 5. ページレンダリング — コンポーネントが
コンテンツを受け取りHTMLをレンダリング管理リクエストの場合:
beforeCreate、afterUpdateなど 4. データベース
更新 — KyselyがSQLを実行 5. レスポンス返却 — 管理SPAへのJSONレスポンスEmDashはビルド時に仮想モジュールを生成し、ランタイムを設定します:
| モジュール | 目的 |
|---|---|
virtual:emdash/config | データベースとストレージの設定 |
virtual:emdash/dialect | データベース方言ファクトリ |
virtual:emdash/plugin-admins | プラグイン管理UIの静的インポート |
このアプローチにより、バンドラーはプラグインコードを適切に解決し、ツリーシェイクできます。
コレクション
コンテンツコレクションとフィールドタイプについて学びます。
コンテンツモデル
データベースファーストのコンテンツモデルを理解します。
管理パネル
管理パネルのアーキテクチャを探索します。