このページで分かること

  • 管理画面の「設定」にある3つのページ(「一般」、「Social」、「SEO」)で設定できる値
  • getSiteSettings()getSiteSetting() でレイアウトやコンポーネントから設定を読み込む方法と、EmDashHead の役割
  • ソーシャルのプロフィールをURLに組み立てる方法と、ロゴ・ファビコン・既定のソーシャル画像などメディアを参照する設定の扱い
難易度
実践
読む時間
3分
前提知識
Astroとは
このページの目次

サイト設定は、サイト全体に適用される値を保持します。テンプレートは、サイトの基本情報、ページ分割、日付の扱い、ソーシャルのプロフィール、検索用のメタデータにこれらの値を使えます。

設定の構成

EmDashの管理画面で「設定」を開き、必要な値があるページを選びます。

  • 「一般」には、サイトのタイトル、キャッチフレーズ、ロゴ、ファビコン、公開URL、1ページあたりの投稿数、日付の形式、タイムゾーンがあります。
  • 「Social」には、対応しているソーシャルサービスのプロフィールのハンドルがあります。
  • 「SEO」には、タイトルの区切り文字、既定のソーシャル画像、所有権の確認用の値、robots.txt の内容があります。
  1. 該当する設定ページを開きます。

  2. サイトのテンプレートとメタデータで使う値を入力します。

  3. ページを保存し、その設定を描画する公開ページを再読み込みします。

設定は、入力するまでは空のままです。テンプレートは、必要とする値について、それぞれ適切な代わりの値を用意しておく必要があります。

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

WordPressの「設定」→「一般」でサイトのタイトルやキャッチフレーズを入力するのと同じように、EmDashでも管理画面の「設定」でサイト全体の値を入力します。違うのは、入力した値がサイトに自動では表示されない点です。WordPressではテーマが表示を受け持ちますが、EmDashでは自分のAstroのテンプレートで値を読み込んで表示します。値が未入力のときに表示が崩れないよう、テンプレート側で代わりの値(例:"My site")を用意しておきます。

レイアウトでの設定の読み込み

レイアウトで複数の値が必要な場合は、getSiteSettings() を使います。この関数は、設定済みのキーを一部だけを持つオブジェクトとして返し、メディアの参照は返す前に解決します。

次のベースレイアウトは、サイトの基本情報の設定を使い、設定済みのファビコン、既定のソーシャル画像、サイト全体の所有権確認用のメタデータの適用を EmDashHead に任せます。

src/layouts/Base.astro
---
import { getSiteSettings } from "emdash";
import { createPublicPageContext } from "emdash/page";
import { EmDashHead } from "emdash/ui";

interface Props {
  title?: string;
  description?: string;
}

const { title, description } = Astro.props;
const settings = await getSiteSettings();
const siteTitle = settings.title ?? "My site";
const fullTitle = title ? `${title} — ${siteTitle}` : siteTitle;
const pageDescription = description ?? settings.tagline;

const page = createPublicPageContext({
  Astro,
  kind: "custom",
  pageType: "website",
  title: fullTitle,
  pageTitle: title ?? siteTitle,
  description: pageDescription,
  siteName: siteTitle,
});
---

<!doctype html>
<html lang={Astro.currentLocale ?? "en"}>
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width" />
    <title>{fullTitle}</title>
    <EmDashHead page={page} />
  </head>
  <body>
    <header>
      <a href="/" aria-label={siteTitle}>
        {settings.logo?.url ? (
          <img
            src={settings.logo.url}
            alt={settings.logo.alt ?? siteTitle}
            width={settings.logo.width}
            height={settings.logo.height}
          />
        ) : (
          siteTitle
        )}
      </a>
      {settings.tagline && <p>{settings.tagline}</p>}
    </header>

    <main>
      <slot />
    </main>
  </body>
</html>

EmDashHeadgetSiteSettings() を呼び出します。リクエスト単位のキャッシュにより、この呼び出しは設定のクエリをもう一度実行せず、レイアウトの結果を再利用します。

サーバーで描画するコンテンツのページでは、コンテンツの参照を createPublicPageContext() に渡し、エントリーgetEmDashEntry() で取得します。すると EmDashHead は、サイトの既定値の上にエントリーのSEOパネルの値を適用します。コンテンツのページの完全な例はSEOパネルのデータの描画を参照してください。

1つの設定の読み込み

コンポーネントで値が1つだけ必要で、親がまだ設定のオブジェクトを取得していない場合は、getSiteSetting() を使います。

次のコンポーネントは、設定されたタイムゾーンでタイムスタンプを整形します。

src/components/PostDate.astro
---
import { getSiteSetting } from "emdash";

interface Props {
  date: Date;
}

const { date } = Astro.props;
const timezone = await getSiteSetting("timezone") ?? "UTC";
const formatted = new Intl.DateTimeFormat(Astro.currentLocale, {
  dateStyle: "long",
  timeZone: timezone,
}).format(date);
---

<time datetime={date.toISOString()}>{formatted}</time>

dateFormat 設定は、MMMM d, yyyy のようなパターン文字列です。Intl.DateTimeFormat はこの書式を解釈しません。テンプレートでこの形式をそのまま適用する必要がある場合は、パターン文字列に対応した整形ライブラリーを使います。

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

設定を読む関数は2つあります。getSiteSettings()(複数形)はすべての設定をまとめて取得し、getSiteSetting("timezone")(単数形)は1つの値だけを取得します。レイアウトのようにタイトル・ロゴ・キャッチフレーズなど複数の値を使う場所では複数形を使います。同じリクエストの中で何度呼び出しても結果は再利用されるため、データベースへの問い合わせが増えることはありません。

ソーシャルのプロフィールの描画

ソーシャルの設定には、完全なリンクではなく、ハンドルやユーザー名が保存されます。どのプロフィールを表示するかはテンプレートが決め、設定された各値をそのサービスのURLに組み立てます。

次のコンポーネントは、設定されたXとGitHubのプロフィールを描画します。

src/components/SocialLinks.astro
---
import { getSiteSetting } from "emdash";

const social = await getSiteSetting("social");
const xHandle = social?.twitter?.replace(/^@/, "");
---

{(xHandle || social?.github) && (
  <nav aria-label="Social profiles">
    <ul>
      {xHandle && (
        <li>
          <a href={`https://x.com/${xHandle}`} rel="me noopener" target="_blank">
            X
          </a>
        </li>
      )}
      {social?.github && (
        <li>
          <a
            href={`https://github.com/${social.github}`}
            rel="me noopener"
            target="_blank"
          >
            GitHub
          </a>
        </li>
      )}
    </ul>
  </nav>
)}

Facebook、Instagram、LinkedIn、YouTubeの設定値にも、同じ方法を使います。これらのフィールドには、管理画面で入力したページ、プロフィール、チャンネル、ハンドルの値が保存されます。公開URLの形式は、引き続きテーマ側が受け持ちます。

メディアの設定の使用

ロゴ、ファビコン、既定のソーシャル画像は、メディアの参照として保存されます。読み込むとき、EmDashは現在のURLと、判明しているコンテンツタイプ、幅、高さを追加します。参照先のメディアが削除されている場合、これらの解決済みの値がないことがあるため、画像を描画する前に url を確認します。

サイト設定が持つロゴとファビコンは1つずつです。ダークモード用の画像はEmDashの画像フィールドの機能で、編集者は対になる画像を選べ、Image コンポーネントが2つを切り替えます。その方法はダークモードを参照してください。

設定のキーとクエリの戻り値の型はランタイムAPIリファレンスで説明しています。プログラムから変更する場合は、Bearerトークンで認証し、状態を変更するすべてのリクエストに X-EmDash-Request: 1 を付けます。リクエストの本文とレスポンスは設定のエンドポイントを参照してください。