コンテンツにスキップ

シードファイル形式

シードファイルは、EmDashサイトをブートストラップするJSONドキュメントです。コレクション、フィールド、タクソノミー、メニュー、リダイレクト、ウィジェットエリア、サイト設定、およびオプションのサンプルコンテンツを定義します。

{
"$schema": "https://emdashcms.com/seed.schema.json",
"version": "1",
"meta": {},
"settings": {},
"collections": [],
"taxonomies": [],
"bylines": [],
"menus": [],
"redirects": [],
"widgetAreas": [],
"sections": [],
"content": {}
}
フィールドタイプ必須説明
$schemastringいいえエディタ検証用のJSONスキーマURL
version"1"はいシードフォーマットバージョン
metaobjectいいえシードに関するメタデータ
settingsobjectいいえサイト設定
collectionsarrayいいえコレクション定義
taxonomiesarrayいいえタクソノミー定義
bylinesarrayいいえバイラインプロフィール定義
menusarrayいいえナビゲーションメニュー
redirectsarrayいいえリダイレクトルール
widgetAreasarrayいいえウィジェットエリア定義
sectionsarrayいいえ再利用可能なコンテンツブロック
contentobjectいいえサンプルコンテンツエントリー

シードに関するオプションのメタデータ:

{
"meta": {
"name": "Blog Starter",
"description": "A simple blog with posts, pages, and categories",
"author": "EmDash"
}
}

サイト全体の設定値:

{
"settings": {
"title": "私のサイト",
"tagline": "モダンなCMS",
"postsPerPage": 10,
"dateFormat": "MMMM d, yyyy"
}
}

設定は site: プレフィックス付きで options テーブルに適用されます。セットアップウィザードでは、ユーザーが title と tagline を上書きできます。

コレクション定義は、データベース内にコンテンツタイプを作成します:

{
"collections": [
{
"slug": "posts",
"label": "Posts",
"labelSingular": "Post",
"description": "Blog posts",
"icon": "file-text",
"supports": ["drafts", "revisions"],
"fields": [
{
"slug": "title",
"label": "Title",
"type": "string",
"required": true
},
{
"slug": "content",
"label": "Content",
"type": "portableText"
},
{
"slug": "featured_image",
"label": "Featured Image",
"type": "image"
}
]
}
]
}
プロパティタイプ必須説明
slugstringはいURLセーフな識別子(小文字、アンダースコア)
labelstringはい複数形の表示名
labelSingularstringいいえ単数形の表示名
descriptionstringいいえ管理UIでの説明
iconstringいいえLucideアイコン名
supportsarrayいいえ機能: "drafts", "revisions"
fieldsarrayはいフィールド定義
プロパティタイプ必須説明
slugstringはいカラム名(小文字、アンダースコア)
labelstringはい表示名
typestringはいフィールドタイプ
requiredbooleanいいえバリデーション: フィールドは値を持たなければならない
uniquebooleanいいえバリデーション: 値は一意でなければならない
defaultValueanyいいえ新規エントリーのデフォルト値
validationobjectいいえ追加のバリデーションルール
widgetstringいいえ管理UIウィジェットのオーバーライド
optionsobjectいいえウィジェット固有の設定
タイプ説明保存形式
string短いテキストTEXT
text長いテキスト(テキストエリア)TEXT
number数値REAL
integer整数INTEGER
boolean真/偽INTEGER
date日付値TEXT (ISO 8601)
datetime日付と時刻TEXT (ISO 8601)
emailメールアドレスTEXT
urlURLTEXT
slugURLセーフな文字列TEXT
portableTextリッチテキストコンテンツJSON
image画像参照JSON
fileファイル参照JSON
json任意のJSONJSON
reference他のエントリーへの参照TEXT

コンテンツの分類システム:

{
"taxonomies": [
{
"name": "category",
"label": "カテゴリー",
"labelSingular": "カテゴリー",
"hierarchical": true,
"collections": ["posts"],
"terms": [
{ "slug": "news", "label": "ニュース" },
{ "slug": "tutorials", "label": "チュートリアル" },
{
"slug": "advanced",
"label": "上級チュートリアル",
"parent": "tutorials"
}
]
},
{
"name": "tag",
"label": "Tags",
"labelSingular": "Tag",
"hierarchical": false,
"collections": ["posts"]
}
]
}
プロパティタイプ必須説明
namestringはい一意の識別子
labelstringはい複数形の表示名
labelSingularstringいいえ単数形の表示名
hierarchicalbooleanはいネストされた用語を許可するか(カテゴリー)またはフラット(タグ)
collectionsarrayはいこのタクソノミーが適用されるコレクション
termsarrayいいえ事前定義された用語
プロパティタイプ必須説明
slugstringはいURLセーフな識別子
labelstringはい表示名
descriptionstringいいえ用語の説明
parentstringいいえ親用語のスラッグ(階層型のみ)

管理パネルから編集可能なナビゲーションメニュー:

{
"menus": [
{
"name": "primary",
"label": "メインナビゲーション",
"items": [
{ "type": "custom", "label": "ホーム", "url": "/" },
{ "type": "page", "ref": "about" },
{ "type": "custom", "label": "Blog", "url": "/posts" },
{
"type": "custom",
"label": "External",
"url": "https://example.com",
"target": "_blank"
}
]
}
]
}
タイプ説明必須フィールド
customカスタムURLurl
pageページエントリへのリンクref
post投稿エントリへのリンクref
taxonomyタクソノミーアーカイブへのリンクref, collection
collectionコレクションアーカイブへのリンクcollection
プロパティタイプ説明
typestring項目タイプ (上記参照)
labelstring表示テキスト (ページ/投稿参照の場合は自動生成)
urlstringカスタムURL (custom タイプ用)
refstringシード内のコンテンツID (page/post タイプ用)
collectionstringコレクションスラッグ
targetstring"_blank" で新しいウィンドウを開く
titleAttrstringHTML title属性
cssClassesstringカスタムCSSクラス
childrenarrayネストされたメニュー項目

バイラインプロファイルは所有権 (author_id) とは別です。再利用可能なバイラインIDを一度定義し、コンテンツエントリから参照します。

{
"bylines": [
{
"id": "editorial",
"slug": "emdash-editorial",
"displayName": "EmDash Editorial"
},
{
"id": "guest",
"slug": "guest-contributor",
"displayName": "Guest Contributor",
"isGuest": true
}
]
}
プロパティタイプ必須説明
idstringはいcontent[].bylines で使用されるシードローカルID
slugstringはいURLセーフなバイラインスラッグ
displayNamestringはいテンプレートやAPIで表示される名前
biostringいいえオプションのプロフィール文
websiteUrlstringいいえオプションのウェブサイトURL
isGuestbooleanいいえバイラインをゲストプロファイルとしてマーク

移行後にレガシーURLを維持するためのリダイレクトルール:

{
"redirects": [
{ "source": "/old-about", "destination": "/about" },
{ "source": "/legacy-feed", "destination": "/rss.xml", "type": 308 },
{
"source": "/category/news",
"destination": "/categories/news",
"groupName": "migration"
}
]
}
プロパティタイプ必須説明
sourcestringはいソースパス (/ で始まる必要あり)
destinationstringはい宛先パス (/ で始まる必要あり)
typenumberいいえHTTPステータス: 301, 302, 307, または 308
enabledbooleanいいえリダイレクトが有効かどうか (デフォルト: true)
groupNamestringいいえ管理パネルでのフィルタリング/検索用のオプションのグループラベル

設定可能なコンテンツ領域:

{
"widgetAreas": [
{
"name": "sidebar",
"label": "メインサイドバー",
"description": "ブログ記事と固定ページに表示されます",
"widgets": [
{
"type": "component",
"title": "最近の投稿",
"componentId": "core:recent-posts",
"props": { "count": 5 }
},
{
"type": "menu",
"title": "クイックリンク",
"menuName": "footer"
},
{
"type": "content",
"title": "このサイトについて",
"content": [
{
"_type": "block",
"style": "normal",
"children": [{ "_type": "span", "text": "私たちのサイトへようこそ!" }]
}
]
}
]
}
]
}
タイプ説明必須フィールド
contentリッチテキストコンテンツcontent (Portable Text)
menuメニューをレンダリングmenuName
component登録済みコンポーネントcomponentId
コンポーネントID説明
core:recent-posts最近の投稿一覧
core:categoriesカテゴリー一覧
core:tagsタグクラウド
core:search検索フォーム
core:archives月別アーカイブ

編集者が /section スラッシュコマンドを介してPortable Textフィールドに挿入できる再利用可能なコンテンツブロック:

{
"sections": [
{
"slug": "hero-centered",
"title": "Centered Hero",
"description": "Full-width hero with centered heading and CTA button",
"keywords": ["hero", "banner", "header", "landing"],
"content": [
{
"_type": "block",
"style": "h1",
"children": [{ "_type": "span", "text": "私たちのサイトへようこそ" }]
},
{
"_type": "block",
"children": [
{ "_type": "span", "text": "Your compelling tagline goes here." }
]
}
]
}
]
}
プロパティタイプ必須説明
slugstringはいURLセーフな識別子
titlestringはいセクションピッカーに表示される名前
descriptionstringいいえこのセクションを使用するタイミングの説明
keywordsarrayいいえセクションを検索するためのキーワード
contentarrayはいPortable Textブロック
sourcestringいいえ"theme" (シードのデフォルト) または "import"

シードファイルからのセクションは source: "theme" とマークされ、管理UIから削除できません。編集者は独自のセクション (source: "user") を作成でき、コンテンツ編集時に任意のセクションタイプを挿入できます。

コレクション別に整理されたサンプルコンテンツ:

{
"content": {
"posts": [
{
"id": "hello-world",
"slug": "hello-world",
"status": "published",
"bylines": [
{ "byline": "editorial" },
{ "byline": "guest", "roleLabel": "Guest essay" }
],
"data": {
"title": "はじめまして",
"content": [
{
"_type": "block",
"style": "normal",
"children": [{ "_type": "span", "text": "ようこそ!" }]
}
],
"excerpt": "最初の投稿です。"
},
"taxonomies": {
"category": ["news"],
"tag": ["welcome", "first-post"]
}
}
],
"pages": [
{
"id": "about",
"slug": "about",
"status": "published",
"data": {
"title": "About Us",
"content": [
{
"_type": "block",
"style": "normal",
"children": [{ "_type": "span", "text": "About page content." }]
}
]
}
}
]
}
}

コンテンツエントリのプロパティ

Section titled “コンテンツエントリのプロパティ”
プロパティタイプ必須説明
idstringはい参照用のシードローカルID
slugstringはいURLスラッグ
statusstringいいえ"published" または "draft" (デフォルト: "published")
dataobjectはいフィールド値
bylinesarrayいいえ順序付きバイラインクレジット (byline, オプションの roleLabel)
taxonomiesobjectいいえタクソノミー名別のターム割り当て

$ref: プレフィックスを使用して他のコンテンツエントリを参照:

{
"data": {
"related_posts": ["$ref:another-post", "$ref:third-post"]
}
}

$ref: プレフィックスは、シード中にシードIDをデータベースIDに解決します。

URLから画像を含める:

{
"data": {
"featured_image": {
"$media": {
"url": "https://images.unsplash.com/photo-xxx",
"alt": "Description of the image",
"filename": "hero.jpg",
"caption": "Photo by Someone"
}
}
}
}

.emdash/media/ からローカル画像を含める:

{
"data": {
"featured_image": {
"$media": {
"file": "hero.jpg",
"alt": "Description of the image"
}
}
}
}
プロパティ型必須説明
urlstringはい*ダウンロードするリモートURL
filestringはい*.emdash/media/ 内のローカルファイル名
altstringいいえアクセシビリティのための代替テキスト
filenamestringいいえファイル名を上書きする
captionstringいいえメディアのキャプション

*url または file のいずれかが必須です。両方は必要ありません。

プログラムによるシードの適用

Section titled “プログラムによるシードの適用”

CLIツールやスクリプトでシードAPIを使用する:

import { applySeed, validateSeed } from "emdash/seed";
import seedData from "../../themes/.emdash/seed.json";
// 最初に検証する
const validation = validateSeed(seedData);
if (!validation.valid) {
console.error(validation.errors);
process.exit(1);
}
// シードを適用する
const result = await applySeed(db, seedData, {
includeContent: true,
onConflict: "skip",
storage: myStorage,
baseUrl: "http://localhost:4321",
});
console.log(result);
// {
// collections: { created: 2, skipped: 0 },
// fields: { created: 8, skipped: 0 },
// taxonomies: { created: 2, terms: 5 },
// bylines: { created: 2, skipped: 0 },
// menus: { created: 1, items: 4 },
// redirects: { created: 3, skipped: 0 },
// widgetAreas: { created: 1, widgets: 3 },
// settings: { applied: 3 },
// content: { created: 3, skipped: 0 },
// media: { created: 2, skipped: 0 }
// }
オプション型デフォルト説明
includeContentbooleanfalseサンプルコンテンツエントリを作成する
onConflictstring"skip""skip", "update", または "error"
mediaBasePathstring—ローカルメディアファイルのベースパス
storageStorage—メディアアップロード用のストレージアダプター
baseUrlstring—メディアURLのベースURL

シーディングは複数回実行しても安全です。エンティティタイプごとの競合時の動作:

エンティティ動作
コレクションスラッグが存在する場合はスキップ
フィールドコレクション + スラッグが存在する場合はスキップ
タクソノミー定義名前が存在する場合はスキップ
タクソノミーターム名前 + スラッグが存在する場合はスキップ
バイラインプロファイルスラッグが存在する場合はスキップ
メニュー名前が存在する場合はスキップ
メニュー項目すべて置き換える (メニューは再作成される)
リダイレクトソースが存在する場合はスキップ
ウィジェットエリア名前が存在する場合はスキップ
ウィジェットすべて置き換える (エリアは再作成される)
セクションスラッグが存在する場合はスキップ
設定更新する (設定は変更されることを意図している)
コンテンツコレクション内でスラッグが存在する場合はスキップ

シードファイルは適用前に検証されます:

import { validateSeed } from "emdash/seed";
const { valid, errors, warnings } = validateSeed(seedData);
if (!valid) {
errors.forEach((e) => console.error(e));
}
warnings.forEach((w) => console.warn(w));

検証チェック:

  • 必須フィールドが存在する
  • スラッグが命名規則に従っている (小文字、アンダースコア)
  • フィールドタイプが有効である
  • 参照が既存のコンテンツを指している
  • 階層的なタームの親が存在する
  • リダイレクトパスが安全なローカルURLである
  • リダイレクトソースが一意である
  • コレクション内に重複するスラッグがない
Terminal window
# Apply seed file
npx emdash seed .emdash/seed.json
# サンプルコンテンツなしで適用
npx emdash seed .emdash/seed.json --no-content
# 検証のみ実行
npx emdash seed .emdash/seed.json --validate
# 現在のスキーマをシードとしてエクスポート
npx emdash export-seed > seed.json
# コンテンツを含めてエクスポート
npx emdash export-seed --with-content > seed.json