WordPress 開発者向け EmDash

このページ

EmDash は、投稿、ページ、タクソノミー、メニュー、ウィジェット、メディアライブラリといった WordPress のなじみ深い概念を、モダンな Astro スタックに取り込みます。コンテンツ管理の知識はそのまま活かせます。

なじみ深いまま変わらないもの

WordPress で知っている概念は、EmDash でもファーストクラス機能です:

  • Collections はカスタム投稿タイプのように機能します—コンテンツ構造を定義し、テンプレートでクエリできます
  • タクソノミー も同じように機能します—階層型(カテゴリーのような)とフラット型(タグのような)
  • メニュー はドラッグアンドドロップの並び替えとネストされた要素に対応
  • ウィジェットエリア はサイドバーや動的なコンテンツ領域に使用
  • メディアライブラリ はアップロード、整理、画像管理に対応
  • 管理UI はコンテンツ編集者がコードに触れずに使用できます

異なる点

実装は変わりますが、メンタルモデルは同じです:

PHP ではなく TypeScript

テンプレートは Astro コンポーネントです。構文はよりクリーンですが、概念は同じです:HTML を 出力するサーバーコードです。

WP_Query ではなくコンテンツ API

getEmDashCollection() のようなクエリ関数が WP_Query に代わります。SQL は不要で、関数呼び出しだけです。

ファイルベースのルーティング

src/pages/ 内のファイルが URL になります。リライトルールやテンプレート階層を覚える必要はありません。

テンプレートパーツではなくコンポーネント

コンポーネントをインポートして使用します。get_template_part() と同じアイデアで、より良い組織化です。

クイックリファレンス

WordPressEmDash備考
カスタム投稿タイプCollections管理 UI または API で定義
WP_QuerygetEmDashCollection()フィルター、制限、タクソノミークエリ
get_post()getEmDashEntry()エントリまたは null を返す
カテゴリー/タグタクソノミー階層サポートが保持される
register_nav_menus()getMenu()ファーストクラスのメニューサポート
register_sidebar()getWidgetArea()ファーストクラスのウィジェットエリア
bloginfo('name')getSiteSetting("title")サイト設定 API
the_content()<PortableText />構造化コンテンツのレンダリング
ショートコードPortable Text ブロックカスタムコンポーネント
add_action/filter()プラグインフックcontent:beforeSave など
wp_optionsctx.kvキーバリューストレージ
テーマディレクトリsrc/ ディレクトリコンポーネント、レイアウト、ページ
functions.phpastro.config.mjs + EmDash 設定ビルドとランタイム設定

コンテンツ API

Collections のクエリ

WordPress のクエリは WP_Query またはヘルパー関数を使用します。EmDash は型付きクエリ関数を使用します。

WordPress

<?php
$posts = new WP_Query([
  'post_type' => 'post',
  'posts_per_page' => 10,
  'post_status' => 'publish',
  'category_name' => 'news',
]);

while ($posts->have_posts()) :
$posts->the_post();
?>

  <h2><?php the_title(); ?></h2>
  <?php the_excerpt(); ?>
<?php endwhile; ?>

EmDash

---
import { getEmDashCollection } from "emdash";

const { entries: posts } = await getEmDashCollection("posts", {
status: "published",
limit: 10,
where: { category: "news" },
});

---

{posts.map((post) => (

  <article>
    <h2>{post.data.title}</h2>
    <p>{post.data.excerpt}</p>
  </article>
))}

単一エントリの取得

次の例では、識別子でエントリを取得してレンダリングします。WordPress と EmDash での方法:

WordPress

<?php
$post = get_post($id);
?>
<article>
  <h1><?php echo $post->post_title; ?></h1>
  <?php echo apply_filters('the_content', $post->post_content); ?>
</article>

EmDash

---
import { getEmDashEntry } from "emdash";
import { PortableText } from "emdash/ui";

const { slug } = Astro.params;
const { entry: post } = await getEmDashEntry("posts", slug);

if (!post) return Astro.redirect("/404");
---

<article>
  <h1>{post.data.title}</h1>
  <PortableText value={post.data.content} />
</article>

テンプレート階層

WordPress はテンプレート階層を使用して、どのファイルがページをレンダリングするかを選択します。Astro は明示的なファイルベースのルーティングを使用します。

WordPress テンプレートEmDash の同等機能
index.phpsrc/pages/index.astro
single.phpsrc/pages/posts/[slug].astro
single-{type}.phpsrc/pages/{type}/[slug].astro
page.phpsrc/pages/pages/[slug].astro
archive.phpsrc/pages/posts/index.astro
archive-{type}.phpsrc/pages/{type}/index.astro
category.phpsrc/pages/categories/[slug].astro
tag.phpsrc/pages/tags/[slug].astro
search.phpsrc/pages/search.astro
404.phpsrc/pages/404.astro
header.php / footer.phpsrc/layouts/Base.astro
sidebar.phpsrc/components/Sidebar.astro

テンプレートパーツ → コンポーネント

WordPress のテンプレートパーツは Astro コンポーネントになります:

WordPress

// テンプレート内:
get_template_part('template-parts/content', 'post');

// template-parts/content-post.php:

<article class="post">
  <h2><?php the_title(); ?></h2>
  <?php the_excerpt(); ?>
</article>

EmDash

---
const { post } = Astro.props;
---

<article class="post">
	<h2>{post.data.title}</h2>
	<p>{post.data.excerpt}</p>
</article>

次のページはそのコンポーネントをインポートし、各投稿に対してレンダリングします:

---
import PostCard from "../components/PostCard.astro";
import { getEmDashCollection } from "emdash";

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

{posts.map((post) => <PostCard {post} />)}

メニュー

EmDash には自動 URL 解決機能を備えたファーストクラスのメニューサポートがあります:

WordPress

<?php
wp_nav_menu([
  'theme_location' => 'primary',
  'container' => 'nav',
]);
?>

EmDash

---
import { getMenu } from "emdash";

const menu = await getMenu("primary");
---

<nav>
  <ul>
    {menu?.items.map((item) => (
      <li>
        <a href={item.url}>{item.label}</a>
      </li>
    ))}
  </ul>
</nav>

メニューは、管理 UI、シードファイル、または WordPress インポートを通じて作成されます。

ウィジェットエリア

ウィジェットエリアは WordPress のサイドバーのように機能します:

WordPress

<?php if (is_active_sidebar('sidebar-1')) : ?>
  <aside>
    <?php dynamic_sidebar('sidebar-1'); ?>
  </aside>
<?php endif; ?>

EmDash

---
import { getWidgetArea } from "emdash";
import { PortableText } from "emdash/ui";

const sidebar = await getWidgetArea("sidebar");
---

{sidebar && (

  <aside>
    {sidebar.widgets.map((widget) => {
      if (widget.type === "content") {
        return <PortableText value={widget.content} />;
      }
      // 他のウィジェットタイプを処理
    })}
  </aside>
)}

サイト設定

サイトオプションとカスタマイザー設定は getSiteSetting() にマップされます:

WordPressEmDash
bloginfo('name')getSiteSetting("title")
bloginfo('description')getSiteSetting("tagline")
get_custom_logo()getSiteSetting("logo")
get_option('date_format')getSiteSetting("dateFormat")
home_url()Astro.site

次の例は getSiteSetting() で個別の設定を読み取ります:

import { getSiteSetting } from "emdash";

const title = await getSiteSetting("title");
const logo = await getSiteSetting("logo"); // { mediaId, alt, url } を返す

タクソノミー

タクソノミーは概念的に同じように機能します—階層型(カテゴリーのような)またはフラット型(タグのような):

import { getTaxonomyTerms, getEntryTerms, getTerm } from "emdash";

// すべてのカテゴリーを取得
const categories = await getTaxonomyTerms("categories");

// 特定のタームを取得
const news = await getTerm("categories", "news");

// 投稿のタームを取得
const postCategories = await getEntryTerms("posts", postId, "categories");

フック → プラグインシステム

WordPress のフック(add_actionadd_filter)は EmDash のプラグインフックになります:

WordPress フックEmDash フック目的
save_postcontent:beforeSave保存前にコンテンツを変更
the_contentPortableText コンポーネントレンダリングされたコンテンツを変換
pre_get_postsクエリオプションクエリをフィルター
wp_headレイアウト <head>head コンテンツを追加
wp_footerレイアウト </body> の前footer コンテンツを追加

EmDash の優れた点

型安全性

全体で TypeScript。Collections、クエリ、コンポーネントは完全に型付けされているため、フィールド名と 戻り値の型が自動補完され、ビルド時にチェックされます。

パフォーマンス

デフォルトで静的生成、必要に応じてサーバーレンダリング。エッジデプロイ対応。

モダンな DX

Hot Module Replacement。コンポーネントベースのアーキテクチャ。モダンなツーリング(Vite、TypeScript、ESLint)。

Git ベースのデプロイ

コードとテンプレートは git に保存され、コンテンツはデータベースに保存されます。コードをプッシュしてデプロイ。

プレビューリンク

EmDash は HMAC 署名トークンを使用して安全なプレビュー URL を生成します。コンテンツ編集者はプレビューリンクを共有して下書きを表示できるため、レビュアーは本番ログインなしで確認できます。

分離されたプラグイン

EmDash プラグインは明示的な API を持つ分離されたコンテキストで実行されます。各プラグインは宣言した API のみにアクセスできるため、プラグインがお互いのグローバル状態を共有したり上書きしたりすることはありません。

コンテンツ編集者の体験

コンテンツ編集者は、wp-admin に似た EmDash 管理パネルを使用します:

  • 最近のアクティビティを表示する ダッシュボード
  • 検索、フィルター、一括アクションを備えた Collection リスト
  • コンテンツ用の リッチエディター(Gutenberg ではなく Portable Text)
  • ドラッグアンドドロップアップロード対応の メディアライブラリ
  • ドラッグアンドドロップ並び替え対応の メニュービルダー
  • サイドバーコンテンツ用の ウィジェットエリアエディター

編集体験はなじみ深いものです。基礎技術はモダンです。

移行パス

EmDash は WordPress コンテンツを直接インポートします:

  1. WordPress からエクスポート(ツール → エクスポート)
  2. EmDash の管理画面で .xml ファイルをアップロード
  3. 投稿タイプを Collections にマッピング
  4. コンテンツとメディアをインポート

投稿、ページ、タクソノミー、メニュー、メディアが転送されます。Gutenberg ブロックは Portable Text に変換されます。カスタムフィールドは分析されマッピングされます。

完全な手順については、WordPress 移行ガイドを参照してください。

次のステップ