21
Help us understand the problem. What are the problem?

posted at

updated at

【WordPress5.9】theme.json 全解説

はじめに

WordPress5.8で、新しいツールである theme.json をテーマ開発に利用出来るようになりました。

これにより、テーマやブロックがサポートする機能・レイアウト・スタイルなどの多くを、このファイル一つで一元的にコントロール出来るようになりました。

この theme.json は、WordPress5.9で搭載されるFull Site Editing(フルサイト編集)と密接に関係しており、フルサイト編集に対応していないテーマを「クラシックテーマ」、フルサイト編集に対応しているテーマを「ブロックテーマ」と呼びます。

クラシックテーマでも theme.json を導入する事が出来ますが、その機能をフル活用するためには、ブロックテーマである必要があります。

ブロックテーマについての前提知識やブロックテーマの作り方については、ブロックエディターハンドブックの「ブロックテーマの作成」を見ていただくとして、この記事では「ブロックテーマにおけるtheme.jsonで何が出来るか」を全て検証してみたいと思います。

実は、 theme.json(と block.json )はデータ構造がJSONスキーマとして定義されており、gutenbergリポジトリ上で最新の定義を確認する事が出来ます。

このJSONスキーマを元にして、各プロパティの意味、具体的な使い方等を説明していきたいと思います。

かなり長尺な記事となりますが、 theme.json を中心としたブロックテーマ開発ではいずれも重要な項目となりますので、ぜひ最後まで読んでいただけたら幸いです。

備考・注意点

  • この記事は、2021年12月14日時点のJSONスキーマをもとにしており、検証したWordPressのバージョンは5.9 Beta 3です。
    WordPress5.9正式リリース前のため、仕様が若干変わる可能性があります。(正式リリースは2022年1月25日の予定
    最新の定義や仕様は、上記gutenbergリポジトリ上のtheme.jsonのスキーマ、またはWordPress.orgのリリースニュース(Make WordPress Core)などで確認してください。

  • WordPress5.8で搭載された theme.jsonバージョン1ですが、WordPress5.9ではバージョン2が搭載され、前述のJSONスキーマもバージョン2に更新されています。
    そのため、この記事でもバージョン2のJSONスキーマをもとにしています。

  • 説明のためにサンプルコード内にコメントを記載していますが、JSONファイルにはコメントを記入出来ないため、動作検証の際は適宜コメントを削除してください。

前準備

この記事の内容を実践するためのオリジナルテーマを用意したいという方は、作成したテーマフォルダに以下ファイルを用意してください。
ブロックテーマとして認識させるために必要な最低限のファイルです。

  • style.css
style.css
  /*
  Theme Name: My Theme
  Text Domain: mytheme
  */
  • index.php (空ファイルでOK)

  • templates/index.html (空ファイルでOK)

  • theme.json (空ファイルでOK。必須ではないが、今回の記事の検証のために作成)

全体図

各プロパティの解説に入る前に、theme.json のルートレベル(第一階層)に指定出来るプロパティ一覧と、それぞれの役割を記載します。

  1. $schemaどのJSONスキーマを参照するかを設定する
  2. version使用する theme.json のバージョンを指定する
  3. settingsブロックエディター全体・ブロック個別の機能の有効化・無効化、および機能の設定をするセクション
  4. stylesサイト、要素、ブロックにスタイルを適用する
  5. customTemplatesカスタムテンプレートにメタデータを追加する
  6. templatePartsテンプレートパーツにメタデータを追加する

以上のうち肝となるのは、3.の settings と 4.の styles です。
この二つのプロパティはネストも深く、理解に時間がかかる所ですが、「今はどの階層の事を解説しているのか」を意識しながら読み進めていただければと思います。

$schema

どのJSONスキーマを参照するかを設定します。

この記事は、公開されている theme.json のJSONスキーマを元にしていると書きましたが、そもそもJSONスキーマを定義する主な目的はJSONデータの構造を検証する事です。

JSONファイル上の $schema プロパティでスキーマの仕様を指定する事で、多くのコードエディタで、その定義を参照してバリデーション・自動補完を効かせる事が出来ます。

theme.json
{
    "$schema": "https://raw.githubusercontent.com/WordPress/gutenberg/trunk/schemas/json/theme.json"
}

例えばVS Codeであれば、以下のように自動補完・バリデーションがかかります。

schema_1.png
schema_2.png

theme.json の定義は今後大きく変わっていく可能性もあるため、まずはこのプロパティを追加しておく事をお勧めします。

version

使用する theme.json のバージョンを指定します。
WordPress5.8ではバージョン1でしたが、WordPress5.9ではバージョン2が搭載されるため、ここは固定値で2となります。

theme.json
{
    "$schema": "https://raw.githubusercontent.com/WordPress/gutenberg/trunk/schemas/json/theme.json",
    "version": 2
}

settings

ブロックエディター全体・ブロック個別の機能の有効化・無効化、および機能の設定を行うセクションですが、注意点が2つあります。

  • いくつかの項目は add_theme_support の宣言に相当するものとなっており、add_theme_support による宣言、かつ theme.json に相当する設定が記述されていた場合、theme.json の設定が優先されます。
  • ブロックがその機能をサポートしていない場合は、theme.json を介して有効化する事は出来ません。 例えば、ドロップキャップ(settings.typography.dropCap)を有効化しても、そもそも見出しブロック( core/heading )側でドロップキャップをサポートしていないので、機能が有効になる事はありません。

また、以下記述する settings.color / settings.spacing / settings.border / settings.custom の設定は、その機能をサポートした全ブロックに反映されます。
ブロック個別に設定を上書きする場合は、後述の settings.blocks プロパティで定義していきます。

settings.color

色に関する設定です。
このプロパティの全体図とデフォルト値は以下となります。

theme.json
{
    "$schema": "https://raw.githubusercontent.com/WordPress/gutenberg/trunk/schemas/json/theme.json",
    "version": 2,
    "settings": {
        "color": {
            "background": true,
            "text": true,
            "link": false,
            "custom": true,
            "defaultPalette": true,
            "palette": [],
            "customGradient": true,
            "defaultGradients": true,
            "gradients": [],
            "duotone": [],
            "customDuotone": true
        }
    }
}

settings.color.background / settings.color.text / settings.color.link

settings.color.background.png

背景色、テキスト色、リンク色をそれぞれ設定出来るようにします。

※デフォルト値:backgroundtexttruelinkfalse

link については、この値を true に設定した場合は、 add_theme_support( 'experimental-link-color' ) を使用した事と同じです。

settings.custom

settings.custom.png

カスタムカラーを選択出来るようにします。

※デフォルト値:true

この値を false に設定した場合は、 add_theme_support( 'disable-custom-colors' ) を使用した事と同じです。

settings.color.defaultPalette

settings.color.defaultPalette.png

(デフォルトの)カラーパレットから、色を選択出来るようにします。

※デフォルト値:true

settings.color.palette

カラーパレットのプリセットを設定します。
add_theme_support( 'editor-color-palette', $args ) に相当します。

slug / color / name プロパティを持ったオブジェクトを配列内に指定します。

  • slug:一意の識別子。ケバブケース(単語をハイフンでつなげる)で定義する
  • color:色を表す16進数またはrgb(a)文字列
  • name:プリセットの名前
theme.json
{
    "$schema": "https://raw.githubusercontent.com/WordPress/gutenberg/trunk/schemas/json/theme.json",
    "version": 2,
    "settings": {
        "color": {
            "palette": [
                {
                    "slug": "white",
                    "color": "#fff",
                    "name": "White"
                },
                {
                    "slug": "blue",
                    "color": "rgb(0,0,255)",
                    "name": "Blue"
                },
                {
                    "slug": "transparent-red",
                    "color": "rgba(255,0,0,0.5)",
                    "name": "Transparent Red"
                }
            ]
        }
    }
}

settings.color.palette.png

theme.json で指定しているはずの「White」が表示されていませんが、デフォルトのプリセットで同名のスラッグ(white)が存在するためです。

注意点として、デフォルトのプリセットを上書きするのではなく、「テーマのカラープリセット」として別途追加されるという事です。

また、クラシックテーマの場合、フロントエンド側でスタイルを反映させるためにCSSを記述していたと思いますが、ブロックテーマの theme.json でプリセットを指定した場合は、以下のように1つのCSSカスタムプロパティと3つのスタイルが自動生成されます。

/* CSSカスタムプロパティ(フロントエンド側) */
body {
    --wp--preset--color--{slug}: {color};
}
/* テキスト色用クラス(フロントエンド側) */
.has-{slug}-color {
    color: var(--wp--preset--color--{slug}) !important;
}
/* 背景色用クラス(フロントエンド側) */
.has-{slug}-background-color {
    background-color: var(--wp--preset--color--{slug}) !important;
}
/* ボーダー色用クラス(フロントエンド側) */
.has-{slug}-border-color {
    border-color: var(--wp--preset--color--{slug}) !important;
}

/* CSSカスタムプロパティ(エディター側) ​*/
.editor-styles-wrapper {
    --wp--preset--color--{slug}: {color};
}
/* テキスト色用クラス(エディター側) */
.editor-styles-wrapper .has-{slug}-color {
    color: var(--wp--preset--color--{slug}) !important;
}
/* 背景色用クラス(エディター側) */
.editor-styles-wrapper .has-{slug}-background-color {
    background-color: var(--wp--preset--color--{slug}) !important;
}
/* ボーダー色用クラス(エディター側) */
.editor-styles-wrapper .has-{slug}-border-color {
    border-color: var(--wp--preset--color--{slug}) !important;
}

settings.color.customGradient

settings.color.customGradient.png

カスタムグラデーションカラーを選択出来るようにします。

※デフォルト値:true

この値を false に設定した場合は、 add_theme_support( 'disable-custom-gradients' ) を使用した事と同じです。

settings.color.defaultGradients

settings.color.defaultGradients.png

(デフォルトの)グラデーションカラーパレットから、色を選択出来るようにします。

※デフォルト値:true

settings.color.gradients

グラデーションカラーパレットのプリセットを設定します。
add_theme_support( 'editor-gradient-presets', $args ) に相当します。

slug / gradient / name プロパティを持ったオブジェクトを配列内に指定します。

  • slug:一意の識別子。ケバブケース(単語をハイフンでつなげる)で定義する
  • gradient:グラデーションカラーを表すCSS値の文字列
  • name:プリセットの名前
theme.json
{
    "$schema": "https://raw.githubusercontent.com/WordPress/gutenberg/trunk/schemas/json/theme.json",
    "version": 2,
    "settings": {
        "color": {
            "gradients": [
                {
                    "slug": "blue-red",
                    "gradient": "linear-gradient(135deg, #0000ff 0%, #ff0000 100%)",
                    "name": "Blue Red"
                },
                {
                    "slug": "blue-yellow-red",
                    "gradient": "linear-gradient(to right, rgb(0,0,255) 1%, rgb(255,255,0) 50%, rgb(255,0,0) 100%)",
                    "name": "Blue Yellow Red"
                }
            ]
        }
    }
}

settings.color.gradients.png

注意点として、setting.color.palette の設定同様、デフォルトのプリセットを上書きするのではなく、「テーマのグラデーションカラープリセット」として別途追加されるという事です。

また、ブロックテーマの theme.json でプリセットを指定した場合は、以下のようにCSSカスタムプロパティとスタイルが自動生成されます。

/* CSSカスタムプロパティ(フロントエンド側) */
body {
    --wp--preset--gradient--{slug}: {gradient};
}
/* グラデーション用クラス(フロントエンド側) */
.has-{slug}-gradient-background {
    background: var(--wp--preset--gradient--{slug}) !important;
}

/* CSSカスタムプロパティ(エディター側) ​*/
.editor-styles-wrapper {
    --wp--preset--gradient--{slug}: {gradient};
}
/* グラデーション用クラス(エディター側) */
.editor-styles-wrapper .has-{slug}-gradient-background {
    background: var(--wp--preset--gradient--{slug}) !important;
}

settings.color.customDuotone

settings.color.customDuotone.png

カスタムデュオトーンフィルターを選択出来るようにします。

※デフォルト値:true

デュオトーンフィルターは、WordPress5.8で搭載された機能で、メディアライブラリの画像・動画を変更する事なく、SVG / CSSフィルターを使ってメディアの色を変更する事が出来ます。

settings.color.duotone

デュオトーンフィルターのパレットのプリセットを設定します。

colors / slug / name プロパティを持ったオブジェクトを配列内に指定します。

  • colors:色を表す16進数またはrgb(a)文字列を、配列内に2つ指定する
  • slug:一意の識別子。ケバブケース(単語をハイフンでつなげる)で定義する
  • name:プリセットの名前
theme.json
{
    "$schema": "https://raw.githubusercontent.com/WordPress/gutenberg/trunk/schemas/json/theme.json",
    "version": 2,
    "settings": {
        "color": {
            "duotone": [
                {
                    "colors": [ "#000", "#FFF" ],
                    "slug": "black-and-white",
                    "name": "Black and White"
                }
            ]
        }
    }
}

settings.color.duotone.png

settings.color.palette または settings.color.gradients でプリセットを設定した場合は、「テーマのカラープリセット」として別途追加されますが、このプロパティを使うと、デフォルトのプリセットを上書きします。

settings.spacing

スペースに関する設定です。
このプロパティの全体図とデフォルト値は以下となります。

theme.json
{
    "$schema": "https://raw.githubusercontent.com/WordPress/gutenberg/trunk/schemas/json/theme.json",
    "version": 2,
    "settings": {
        "spacing": {
            "blockGap": null,
            "margin": false,
            "padding": false,
            "units": [ "px", "em", "rem", "vh", "vw", "%" ]
        },
        "styles": {
            "blockGap": "3em",
        }
    }
}

settings.spacing.blockGap

gapプロパティを、styles.spacing.blocGap から生成するかどうかを設定します。

※デフォルト値:null

ボタンブロック(button)、カラムブロック(columns)等では、子要素のレイアウトにフレックスボックスレイアウトが用いられています。

子要素の余白調整には gap プロパティが使われており、その値はCSSカスタムプロパティ(--wp-style--block-gap)で定義されています。

blockGap プロパティでは、このCSSカスタムプロパティを生成するかどうかを設定する事ができ、styles.spacing.blockGap プロパティとの組み合わせによって振る舞いが変わります。

以下3つの設定例で、どのようなスタイルが生成されるかを確認してみます。

  • settings.spacing.blockGapnullstyles.spacing.blockGap指定しない
theme.json
{
  "$schema": "https://raw.githubusercontent.com/WordPress/gutenberg/trunk/schemas/json/theme.json",
  "version": 2,
  "settings": {
      "spacing": {
          "blockGap": null
      }
  }
}

CSSカスタムプロパティ(--wp-style--block-gap)が生成されません。
また、フレックスボックスレイアウトが用いられるブロックには、gap プロパティの値が固定値(0.5em)となります。

/* フロントエンド側*/
.wp-container-XXXXXXXXXXXXX {
    display: flex;
    gap: 0.5em;
}

/* エディター側 */
.editor-styles-wrapper .wp-container-xxx {
    display: flex;
    gap: 0.5em;
}
  • settings.spacing.blockGaptruestyles.spacing.blockGap指定しない
theme.json
{
    "$schema": "https://raw.githubusercontent.com/WordPress/gutenberg/trunk/schemas/json/theme.json",
    "version": 2,
    "settings": {
        "spacing": {
            "blockGap": true
        }
    }
}

CSSカスタムプロパティ(--wp-style--block-gap)が生成され、その値はデフォルト値の24pxとなります。
また、フレックスボックスレイアウトが用いられるブロックでは、gap プロパティの値にCSSカスタムプロパティが適用されます。

/* フロントエンド側*/
body {
    --wp--style--block-gap: 24px;
}
.wp-container-XXXXXXXXXXXXX {
    display: flex;
    gap: var( --wp--style--block-gap, 0.5em );
}

/* エディター側 */
.editor-styles-wrapper {
    --wp--style--block-gap: 24px;
}
.editor-styles-wrapper .wp-container-xxx {
    gap: var( --wp--style--block-gap, 0.5em );
}
  • settings.spacing.blockGaptruestyles.spacing.blockGap指定する
theme.json
{
    "$schema": "https://raw.githubusercontent.com/WordPress/gutenberg/trunk/schemas/json/theme.json",
    "version": 2,
    "settings": {
        "spacing": {
            "blockGap": true
        }
    },
    "styles": {
        "spacing": {
            // blockGapの指定あり
            "blockGap": "48px"
        }
    }
}

CSSカスタムプロパティ(--wp-style--block-gap)が生成され、その値は styles.spacing.blockGap の値の48pxとなります。
また、フレックスボックスレイアウトが用いられるブロックでは、gap プロパティの値にCSSカスタムプロパティが適用されます。

/* フロントエンド側*/
body {
    --wp--style--block-gap: 48px;
}
.wp-container-XXXXXXXXXXXXX {
    display: flex;
    gap: var( --wp--style--block-gap, 0.5em );
}

/* エディター側 */
.editor-styles-wrapper {
    --wp--style--block-gap: 48px;
}
.editor-styles-wrapper .wp-container-xxx {
    gap: var( --wp--style--block-gap, 0.5em );
}

settings.spacing.margin / settings.spacing.padding

カスタムマージン、カスタムパディングを設定出来るようにします。

※デフォルト値:どちらもfalse

padding については、この値を true に設定した場合は、 add_theme_support( 'custom-spacing' ) を使用した事と同じです。

theme.json
{
    "$schema": "https://raw.githubusercontent.com/WordPress/gutenberg/trunk/schemas/json/theme.json",
    "version": 2,
    "settings": {
        "spacing": {
            "margin": true,
            "padding": true
        }
    }
}

上記のようにmargin / padding の両方を有効にし、かつ両方の機能をサポートしている「サイトのタイトル」ブロックで確認してみると、「サイズ」パネルに以下のように表示されます。

settings.spacing.margin.png

また、上下左右どの方向が設定可能となるかは、ブロックのサポートにより異なります。
※例えばボタン(buttons)ブロックであれば、margin は上方向(top)と下方向(bottom)しかサポートされていません。

settings.spacing.units

blopGap / margin / padding プロパティにおいて、どの単位を使用するかを設定します。

add_theme_support( 'custom-units', ...$args ) に相当します。

theme.json
{
    "$schema": "https://raw.githubusercontent.com/WordPress/gutenberg/trunk/schemas/json/theme.json",
    "version": 2,
    "settings": {
        "spacing": {
            // margin の有効化
            "margin": true,
            // 単位は px  em しかつかえないようにする
            "units": [ "px", "em" ]
        }
    }
}

settings.spacing.units.png

settings.typography

タイポグラフィ(文字)に関する設定です。
このプロパティの全体図とデフォルト値は以下となります。

theme.json
{
    "$schema": "https://raw.githubusercontent.com/WordPress/gutenberg/trunk/schemas/json/theme.json",
    "version": 2,
    "settings": {
        "typography": {
            "dropCap": true,
            "fontStyle": true,
            "fontWeight": true,
            "letterSpacing": true,
            "lineHeight": false,
            "textDecoration": true,
            "textTransform": true,
            "customFontSize": true,
            "fontSizes": [],
            "fontFamilies": []
        }
    }
}

settings.typography.dropCap

settings.typography.dropCap.png

ドロップキャップ(先頭の文字を大きく表示する)を有効にします。

※デフォルト値:true

この設定をサポートしているコアブロックは、段落(paragraph)ブロックのみです。

settings.typography.fontStyle / settings.typography.fontWeight / settings.typography.letterSpacing / settings.typography.lineHeight / settings.typography.textDecoration / settings.typography.textTransform

以下をそれぞれ設定出来るようにします。

  • fontStyle:フォントスタイル(font-style
  • fontWeight:外観(font-weight
  • letterSpacing:Letter-spacing(letter-spacing
  • lineHeight:行の高さ(line-height
  • textDecoration:装飾(text-decoration
  • textTransform:大文字小文字(text-transform

※デフォルト値:lineHeightfalse、 それ以外は true

lineHeight については、この値を true に設定した場合は、 add_theme_support( 'custom-line-height' ) を使用した事と同じです。

これらを全てサポートしているコアブロックは現状ありませんが、もし6つ全ての設定をブロック側でサポートしていた場合、タイポグラフィパネルに以下のように表示されます。

settings.typography.png

ちなみに、fontStylefontWeight の両方をブロックがサポートしていた場合は、「外観」プルダウンにバリエーションの組み合わせとして表示されます。
fontStyle をサポートし、fontWeight をサポートしていない場合は、「フォントスタイル」というプルダウンにバリエーションが表示されます。

settings.typography.customFontSize

settings.typography.customFontSize.png

カスタムフォントサイズを設定出来るようにします。
この値を false に設定した場合は、 add_theme_support( 'disable-custom-font-sizes' ) を使用した事と同じです。

※デフォルト値:true

settings.typography.fontSizes

フォントサイズのプリセットを設定します。
add_theme_support( 'editor-font-sizes', $args ) に相当します。

name / slug / size プロパティを持ったオブジェクトを配列内に指定します。

  • name:プリセットの名前
  • slug:一意の識別子。ケバブケース(単語をハイフンでつなげる)で定義する
  • size:フォントサイズの値(単位含む)
theme.json
{
    "$schema": "https://raw.githubusercontent.com/WordPress/gutenberg/trunk/schemas/json/theme.json",
    "version": 2,
    "settings": {
        "typography": {
            "fontSizes": [
                {
                    "name": "小",
                    "slug": "small",
                    "size": "10px"
                },
                {
                    "name": "中",
                    "slug": "medium",
                    "size": "14px"
                },
                {
                    "name": "大",
                    "slug": "large",
                    "size": "2vw"
                }
            ]
        }
    }
}

settings.typography.fontSizes_1.png

選択肢が数字の表示だけで、単位が表示されていないので、分かりづらいですね。。

選択肢が6つ以上になると、自動的に以下のようにプルダウンに変わります。

settings.typography.fontSizes_2.png

クラシックテーマの場合、フロントエンド側でスタイルを反映させるためにCSSを記述していたと思いますが、ブロックテーマの theme.json でプリセットを指定した場合は、以下のようにCSSカスタムプロパティとスタイルが自動生成されます。

/* CSSカスタムプロパティ(フロントエンド側) */
body {
    --wp--preset--font-size--{slug}: {size};
}
/* フォントサイズ用クラス(フロントエンド側) */
.has-{slug}-font-size {
    font-size: var(--wp--preset--font-size--{slug}) !important;
}

/* CSSカスタムプロパティ(エディター側) ​*/
.editor-styles-wrapper {
    --wp--preset--font-size--{slug}: {size};
}
/* フォントサイズ用クラス(エディター側) */
.editor-styles-wrapper .has-{slug}-font-size {
    font-size: var(--wp--preset--font-size--{slug}) !important;
}

settings.typography.fontFamilies

フォントファミリーのプリセットを設定します。

name / slug / fontFamily プロパティを持ったオブジェクトを配列内に指定します。

  • name:プリセットの名前
  • slug:一意の識別子。ケバブケース(単語をハイフンでつなげる)で定義する
  • fontFamily:フォントファミリーの値(単位含む)
theme.json
{
    "$schema": "https://raw.githubusercontent.com/WordPress/gutenberg/trunk/schemas/json/theme.json",
    "version": 2,
    "settings": {
        "typography": {
            "fontWeight": false,
            "fontFamilies": [
                {
                    "slug": "system-font",
                    "name": "System Font",
                    "fontFamily": "-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,Oxygen-Sans,Ubuntu,Cantarell, \"Helvetica Neue\",sans-serif"
                },
                {
                    "slug": "helvetica-arial",
                    "name": "Helvetica or Arial",
                    "fontFamily": "Helvetica Neue, Helvetica, Arial, sans-serif"
                }
            ]
        }
    }
}

settings.typography.fontFamilies.png

フォントサイズのプリセット同様、以下のようにCSSカスタムプロパティとスタイルが自動生成されます。

/* CSSカスタムプロパティ(フロントエンド側) */
body {
    --wp--preset--font-family--{slug}: {fontFamily};
}

/* フォントファミリー用クラス(フロントエンド側) */
.has-{slug}-font-family {
    font-family: var(--wp--preset--font-family--{slug}) !important;
}

/* CSSカスタムプロパティ(エディター側) ​*/
.editor-styles-wrapper {
    --wp--preset--font-family--{slug}: {fontFamily};
}

/* フォントファミリー用クラス(エディター側) ​*/
.editor-styles-wrapper .has-{slug}-font-family {
    font-family: var(--wp--preset--font-family--{slug}) !important;
}

settings.border

ボーダーに関する設定です。
このプロパティの全体図とデフォルト値は以下となります。

theme.json
{
    "$schema": "https://raw.githubusercontent.com/WordPress/gutenberg/trunk/schemas/json/theme.json",
    "version": 2,
    "settings": {
        "border": {
            "color": false,
            "radius": false,
            "style": false,
            "width": false
        }
    }
}

settings.border.color / settings.border.radius / settings.border.style / settings.border.width

以下をそれぞれ設定出来るようにします。

  • color:色(border-color
  • radius:Radius(border-radius
  • style:Style(border-style
  • width:幅(border-width

※デフォルト値:全て false

theme.json
{
    "$schema": "https://raw.githubusercontent.com/WordPress/gutenberg/trunk/schemas/json/theme.json",
    "version": 2,
    "settings": {
        "border": {
            "color": true,
            "radius": true,
            "style": true,
            "width": true
        }
    }
}

上記のように全ての設定を有効にし、かつこれらを全てサポートしているグループブロックで確認してみると、Borderパネルに以下のように表示されます。

settings.border.png

settings.custom

CSSカスタムプロパティを生成します。
生成されたカスタムプロパティは、フロントエンド・エディター両方にエンキューされます。

デフォルトテーマのTwenty Twenty Twoでは、以下のようなプロパティが定義されています。

theme.json
{
    "version": 2,
    "settings": {
        "custom": {
            "spacing": {
                "small": "max(1.25rem, 5vw)",
                "medium": "clamp(2rem, 8vw, calc(4 * var(--wp--style--block-gap)))",
                "large": "clamp(4rem, 10vw, 8rem)"
            },
            "typography": {
                "font-size": {
                    "gigantic": "clamp(3rem, 6vw, 4rem)",
                    "colossal": "clamp(4rem, 8vw, 6.25rem)"
                },
                "line-height": {
                    "tiny": 1.15,
                    "small": 1.2,
                    "medium": 1.4,
                    "normal": 1.6
                }
            }
        }
    }
}

生成されるCSSカスタムプロパティの命名規則、およびルールは以下の通りです。

  • プレフィックスとして --wp--custom が付与される
  • 各階層のキーが -- で連結される
  • キーはキャメルケース(単語の先頭の文字が大文字)からケバブケース(単語をハイフンでつなげる)に変換される
  • キー名に -- を含めてはいけない
  • CSSカスタムプロパティは、フロントエンド側ではbody タグに、エディター側では .editor-styles-wraper クラスに付与される

そのため、Twenty Twenty Two の settings.custom の設定から生成されるCSSプロパティは以下のようになります。

/* フロントエンド側 */
body {
    /* settings.custom.spacingから生成 */
    --wp--custom--spacing--small: max(1.25rem, 5vw);
    --wp--custom--spacing--medium: clamp(2rem, 8vw, calc(4 * var(--wp--style--block-gap)));
    --wp--custom--spacing--large: clamp(4rem, 10vw, 8rem);

    /* settings.custom.typographyから生成 */
    --wp--custom--typography--font-size--gigantic: clamp(3rem, 6vw, 4rem);
    --wp--custom--typography--font-size--colossal: clamp(4rem, 8vw, 6.25rem);

    /* settings.custom.line-heightから生成 */
    --wp--custom--typography--line-height--tiny: 1.15;
    --wp--custom--typography--line-height--small: 1.2;
    --wp--custom--typography--line-height--medium: 1.4;
    --wp--custom--typography--line-height--normal: 1.6;
}

/* エディター側 */
.editor-styles-wrapper {
    /* フロントエンド側と同じ */
}
  • 「どのようなCSSカスタムプロパティを生成するか」
  • 「生成したCSSカスタムプロパティをどこで使うか」

ですが、最も重要なのは「エディターやブロックのデフォルトスタイルを決定するためのカスタムプロパティを定義しておく」事ではないかと思います。

Twenty Twenty Twoでは、上記で生成したCSSカスタムプロパティを使って、後述の styles.blocks / styles.elements / styles.typography プロパティ等で、以下のように各ブロック(+各要素)にスタイルを当てています。(一部のみ抜粋)

theme.json
{
    "version": 2,
    "styles": {
        // ブロックのスタイル
        "blocks": {
            "core/site-title": {
                "typography": {
                    "lineHeight": "var(--wp--custom--typography--line-height--normal)",
                }
            }
        },
        // カラー
        "color": {
            "background": "var(--wp--preset--color--background)",
            "text": "var(--wp--preset--color--foreground)"
        },
        // 要素のスタイル
        "elements": {
            "h1": {
                "typography": {
                    "fontFamily": "var(--wp--preset--font-family--source-serif-pro)",
                    "lineHeight": "var(--wp--custom--typography--line-height--tiny)",
                    "fontSize": "var(--wp--custom--typography--font-size--colossal)"
                }
            }
        },
        // 文字のスタイル
        "typography": {
            "fontFamily": "var(--wp--preset--font-family--system-font)",
            "lineHeight": "var(--wp--custom--typography--line-height--normal)",
            "fontSize": "var(--wp--preset--font-size--normal)"
        }
    }
}

ご覧の通り、このプロパティから生成された --wp--custom--{key}--{nested-key}--{nested-key}というCSSカスタムプロパティを使って、ブロックや要素にスタイルをあてています。

同時に、

などのCSSカスタムプロパティが使用されています。

さらに、テーマのテンプレートおよびテンプレートパーツ内でも、このCSSカスタムプロパティが使われています。

parts/header.html
<!-- 一部抜粋 -->
<div class="wp-block-group alignwide" style="padding-top:var(--wp--custom--spacing--small, 1.25rem);padding-bottom:var(--wp--custom--spacing--large, 8rem)"><!-- wp:group {"layout":{"type":"flex"}} -->
<div class="wp-block-group"><!-- wp:site-logo {"width":64} /-->

このように、

  • theme.json の設定で適切なCSSカスタムプロパティを出力する
  • 出力されたCSSカスタムプロパティを使って、theme.json およびテンプレート・テンプレートパーツ内でスタイリングを行う

という手法でテーマを設計・開発する事が出来ます。

settings.appearanceTools

settings プロパティにおける全ての設定項目をオプトインします。

※デフォルト値:false

theme.json
{
    "$schema": "https://raw.githubusercontent.com/WordPress/gutenberg/trunk/schemas/json/theme.json",
    "version": 2,
    'settings': {
        'appearanceTools': true
    }
}

つまり、デフォルト値が false の項目を全て true とした、以下の記述と同じ意味となります。

theme.json
{
    "$schema": "https://raw.githubusercontent.com/WordPress/gutenberg/trunk/schemas/json/theme.json",
    "version": 2,
    "settings": {
        "border": {
            "color": true,
            "radius": true,
            "style": true,
            "width": true
        },
        "color": {
            "link": true
        },
        "spacing": {
            "blockGap": true,
            "margin": true,
            "padding": true
        },
        "typography": {
            "lineHeight": true
        }
    }
}

appearanceToolstrue にした場合は、使わない設定・機能を個別にオプトアウトしていく事になります。
appearanceToolsfalse にした場合は、デフォルトの設定を個別にオプトインまたはオプトアウトしていく事になります。

開発するテーマの要件にあわせて、どちらの方針を取るかを検討すると良いと思います。

また、「ブロックがサポートしている機能を全て見てみたい」という場合に、一旦 true に設定してみるという方法も使えると思います。

settings.blocks

ブロック個別に機能の有効化 / 無効化をコントロールするセクションです。

settings プロパティでこれまで説明してきた、トップレベルで宣言されるブロック設定( color / layout / spacing / typography / border / custom )は、(その機能をサポートしている)すべてのブロックに反映されます。

この blocks プロパティでは、上記6つの設定をブロック単位で上書きする事が出来ます。
ただし、もちろんブロックがその機能をサポートしていない場合は、上書きしても機能が有効にはなりません。

各ブロック内で指定出来る設定は、トップレベルで宣言される設定と同じであるため、ここではいくつか具体例を挙げるにとどめたいと思います。

theme.json
{
    "$schema": "https://raw.githubusercontent.com/WordPress/gutenberg/trunk/schemas/json/theme.json",
    "version": 2,
    "settings": {
        // ※検証のために、一旦全ての機能をオプトインする
        "appearanceTools": true,
        "blocks": {
            // 見出しブロック
            "core/heading": {
                // 背景色の設定を無効にする
                "color": {
                    "background": false
                }
            },
            // 段落ブロック
            "core/paragraph": {
                "color": {
                    // カラーパレットのプリセットを上書きする
                    "palette": [
                        {
                            "slug": "yellow",
                            "color": "#ff0",
                            "name": "Yellow"
                        }
                    ]
                }
            },
            // ボタンブロック
            "core/buttons": {
                "spacing": {
                    // 余白(=ブロックの余白 / blocGap)をpx単位でしか指定できないようにする
                    "units": [ "px" ]
                }
            },
            // グループブロック
            "core/group": {
                "custom": {
                    // 専用のCSSカスタムプロパティを生成する
                    "spacing": {
                        "group-sm": "1em",
                        "group-md": "2em",
                        "group-lg": "3em"
                    }
                }
            }
        }
    }
}

上記のうちcustom プロパティのみ少し特殊で、body タグではなく、以下のようにブロック専用のクラス内にCSSカスタムプロパティが付与されます。

.wp-block-group {
    --wp--custom--spacing--group-sm: 1em;
    --wp--custom--spacing--group-md: 2em;
    --wp--custom--spacing--group-lg: 3em;
}

settings.layout

コンテンツ幅を設定します。

settings.layout.contentSize / settings.layout.wideSize

コンテンツの最大幅( contentSize )、および幅広コンテンツの最大幅( wideSizeを設定します。

theme.json
{
    "$schema": "https://raw.githubusercontent.com/WordPress/gutenberg/trunk/schemas/json/theme.json",
    "version": 2,
    "settings": {
        "layout": {
            // コンテンツの最大幅を650pxに設定
            "contentSize": "650px",
            // 幅広コンテンツの最大幅を1000pxに設定
            "wideSize": "1000px"
        }
    }
}

これは、ブロックテーマにおいてエディター側、フロントエンド側両方に影響する重要な設定です。

まずエディター側では、この定義が入っていないと、全てのブロックがエディターコンテンツの幅一杯に広がってしまいます。

settings.layout_1.png

contentSize プロパティを設定すると、以下のように左右中央に配置されるCSSが、ルート階層に配置された各ブロックにあたるようになります。

settings.layout_2.png

フロントエンド側はもう少しややこしく、例え contentSize プロパティが定義されていたとしても、各ブロックに最大幅が自動的に設定されるわけではありません。

例えば、グループブロックを挿入すると、サイドバーに「レイアウト」というパネルが表示されます。
このレイアウトパネルでコンテンツ幅を定義すると、その子ブロック(いわゆるInnerBlocks)に最大幅が設定されます。

settings.layout_3.png

「デフォルトレイアウトの継承」をONにすると、 contentSize の値が最大幅として子ブロックに適用されます。
「デフォルトレイアウトの継承」をOFFにした場合は、「コンテンツ」に明示的に幅を指定する事で、その最大幅が子ブロックに適用されます。

settings.layout_4.png

今までのテーマ設計では、

  • コンテンツエリア(ブロック全体)を囲うラッパー要素に幅を設定する
  • ブロックには幅を設定しない(親要素の幅一杯に広げる)
  • 幅広・全幅レイアウトの場合は、ブロックの左右にマイナスマージンを指定する

という手法が多かったのではないかと思います。

ブロックテーマにおいては、デフォルトテーマ(Twenty Twenty Two)のテンプレートを見ても分かる通り、以下のように theme.json の設定を中心として、各セクションにコンテンツ幅を設定する事になるのではないかと思います。

  • theme.jsonsettings.layout.contentSize (+ settings.layout.contentSize)で、コンテンツ幅を決定する
  • ヘッダー・メイン・フッターエリアそれぞれに、ラッパー要素としてまずグループブロックを挿入する
  • ラッパー要素のグループブロックで、 「デフォルトレイアウトの継承」をONにして、子ブロックにコンテンツ最大幅を適用させる(もしくは、コンテンツ幅を値で指定する)

styles

サイト、要素、ブロックにスタイルを適用します。
定義したプロパティのキー、階層、値をもとにインラインCSSを出力します。

このプロパティはかなりややこしいのですが、定義出来る6つのプロパティは役割によって以下3つに分類されます。

  1. border / color / spacing / typographyスタイルを定義する
  2. blocks特定のブロックにスタイルを適用する
  3. elements特定の要素(h1 ~ h6、aタグ)にスタイルを適用する

上記プロパティを組み合わせる事で、柔軟にスタイルを定義する事が出来ます。

styles.border / styles.color / styles.spacing / styles.typography

スタイルを適用します。
適用出来るプロパティは以下の通りです。

theme.json
{
    "$schema": "https://raw.githubusercontent.com/WordPress/gutenberg/trunk/schemas/json/theme.json",
    "version": 2,
    "styles": {
        "border": {
            "color": "value",
            "radius": "value",
            "style": "value",
            "width": "value"
        },
        "color": {
            "background": "value",
            "gradient": "value",
            "text": "value"
        },
        "spacing": {
            "blockGap": "value",
            "margin": {
                "top": "value",
                "right": "value",
                "bottom": "value",
                "left": "value"
            },
            "padding": {
                "top": "value",
                "right": "value",
                "bottom": "value",
                "left": "value"
            }
        },
        "typography": {
            "fontFamily": "value",
            "fontSize": "value",
            "fontStyle": "value",
            "fontWeight": "value",
            "letterSpacing": "value",
            "lineHeight": "value",
            "textDecoration": "value",
            "textTransform": "value"
        }
    }
}

例として、以下のような theme.json を適用したとします。

theme.json
{
    "$schema": "https://raw.githubusercontent.com/WordPress/gutenberg/trunk/schemas/json/theme.json",
    "version": 2,
    "styles": {
        "color": {
            "text": "red"
        },
        "typography": {
            "lineHeight": 1.5
        }
    }
}

以上の定義から、フロントエンド側・エディター側では、以下のようなスタイルが適用されます。

/* フロントエンド側 */
body {
    color: red;
    line-height: 1.5;
}
/* エディター側 */
.editor-styles-wrapper {
    color: red;
    line-height: 1.5;
}

このように、 styles プロパティ直下(ルートレベル)でスタイルを定義した場合は、サイト全体body.editor-styles-wrapper)にスタイルが適用されます。

また、ここでは固定値を設定していますが、settings プロパティで説明した通り、「settingsプロパティの定義から生成されたCSSカスタムプロパティを値に使う」という方法が良いのではないかと思います。

以下、Twenty Twenty Twoの theme.json の一部抜粋です。

theme.json
{
    "version": 2,
    "settings": {
        "custom": {
            "typography": {
                "line-height": {
                    "normal": 1.6
                    //  "--wp--custom--typography--line-height--normal" が生成される
                }
            }
        },
        "color": {
            "palette": [
                {
                    "slug": "foreground",
                    "color": "#000000",
                    "name": "Foreground"
                    //  "--wp--preset--color--foreground" が生成される
                }
            ]
        },
        "typography": {
            "fontSizes": [
                {
                    "name": "Normal",
                    "size": "1.125rem",
                    "slug": "normal"
                    //  "--wp--preset--font-size--normal" が生成される
                }
            ]
        }
    },
    // 生成されたCSSカスタムプロパティを使ってスタイルを適用する
    "styles": {
        "color": {
            "text": "var(--wp--preset--color--foreground)"
        },
        "typography": {
            "lineHeight": "var(--wp--custom--typography--line-height--normal)",
            "fontSize": "var(--wp--preset--font-size--normal)"
        }
    }
}

styles.blocks

特定のブロックにスタイルを適用します。

前述の通り、サイト全体にスタイルを適用する場合は styles プロパティ直下(ルートレベル)で border / color / spacing / typography を定義します。

ブロック個別にスタイルを適用するには、styles 直下にまず blocks プロパティ、さらにその下にブロック名を定義します。

例えば、

  • サイト全体のテキスト色は赤で
  • 見出しブロックのみテキスト色を青にする
  • カスタムブロック( myplugin/myblock )のみテキスト色を黄にする

という場合は、以下のようになります。

theme.json
{
    "$schema": "https://raw.githubusercontent.com/WordPress/gutenberg/trunk/schemas/json/theme.json",
    "version": 2,
    "styles": {
        "color": {
            "text": "red"
        },
        "blocks": {
            "core/heading": {
                "color": {
                    "text": "blue"
                }
            },
            "myplugin/myblock": {
                "color": {
                    "text": "yellow"
                }
            }
        }
    }
}

この定義から生成されるCSSは以下のようになります。

/* フロントエンド側 */
body {
    color: red;
    line-height: 1.5;
}
h1,
h2,
h3,
h4,
h5,
h6 {
    color: blue;
}
.wp-block-myplugin-myblock {
    color: yellow;
}

/* エディター側 */
.editor-styles-wrapper {
    color: red;
}
.editor-styles-wrapper h1,
.editor-styles-wrapper h2,
.editor-styles-wrapper h3,
.editor-styles-wrapper h4,
.editor-styles-wrapper h5,
.editor-styles-wrapper h6 {
    color: blue;
}
.editor-styles-wrapper .wp-block-myplugin-myblock {
    color: yellow;
}

styles.elements

特定の要素にスタイルを適用します。

「特定の要素」と言っても、指定出来る要素は以下に限られます。

  • h1 / h2 / h3 / h4 / h5 / h6
  • link ( a )

styles.blocks プロパティ同様、styles 直下にまず elements プロパティ、さらにその下に要素名を定義します。

例えば、

  • 見出しブロックのうち、h2 タグのみテキスト色を青にする
  • リンクテキストの色を赤にする

という場合は、以下のようになります。

theme.json
{
    "$schema": "https://raw.githubusercontent.com/WordPress/gutenberg/trunk/schemas/json/theme.json",
    "version": 2,
    "styles": {
        "elements": {
            "h2": {
                "color": {
                    "text": "blue"
                }
            },
            "link": {
                "color": {
                    "text": "red"
                }
            }
        }
    }
}

この定義から生成されるCSSは以下のようになります。

/* フロントエンド側 */
h2 {
    color: blue;
}
a {
    color: red;
}

/* エディター側 */
.editor-styles-wrapper h2 {
    color: blue;
}
.editor-styles-wrapper a {
    color: red;
}

ここまでの styles プロパティの定義を応用すると、以下のようにネストする事でCSSセレクタを細かくコントロールする事も出来ます。

theme.json
{
    "$schema": "https://raw.githubusercontent.com/WordPress/gutenberg/trunk/schemas/json/theme.json",
    "version": 2,
    "styles": {
        "blocks": {
            "core/group": {
                "elements": {
                    "h2": {
                        "typography": {
                            // グループブロックの中のh2要素のみ、フォントサイズを30pxにする
                            "fontSize": "30px"
                        }
                    }
                }
            }
        }
    }
}

生成されるCSS

/* フロントエンド側 */
.wp-block-group h2 {
    font-size: 30px;
}

/* エディター側 */
.editor-styles-wrapper .wp-block-group h2 {
    font-size: 30px;
}

customTemplates

templates フォルダに配置したカスタムテンプレートにメタデータを追加します。

ブロックテーマでは、templates フォルダにテンプレートとなるhtmlファイルを設置すると、管理画面の「サイトエディター > Templates」ページでリスト表示されます。

例えば、templates フォルダに以下のようなテンプレートを配置したとします。

my-theme/
    └ templates/
        ├ archive.html
        ├ header-large.html
        ├ header-small.html
        └ index.html

そうすると、管理画面の「サイトエディター > Templates」ページでは、以下のように表示されます。

customTemplates_1.png

デフォルトテンプレートである「Archive」「Index」などは、(最初の文字が大文字の)テンプレートラベルが表示されますが、カスタムテンプレートに関しては、「テンプレートファイル名から拡張子を除いたもの」がテンプレートラベルとして表示されます。

customTemplates プロパティで、name / title / postTypes プロパティを持ったオブジェクトを配列内に指定する事で、このテンプレートラベルの表示を分かりやすいものに変更する事が出来ます。

  • name:(必須)ファイル名(テンプレートファイル名から拡張子を除いたもの)
  • title:(必須)管理画面の「サイトエディター > Templates」ページで表示するテンプレートラベル
  • postTypes:(任意)どの投稿タイプに適用するかを配列で指定(デフォルトは [ "page" ]
theme.json
{
    "$schema": "https://raw.githubusercontent.com/WordPress/gutenberg/trunk/schemas/json/theme.json",
    "version": 2,
    "customTemplates": [
        {
            "name": "header-large",
            "title": "大きいヘッダーのテンプレート",
            "postTypes": [
                "post"
            ]
        },
        {
            "name": "header-small",
            "title": "小さいヘッダーのテンプレート",
            "postTypes": [
                "page"
            ]
        }
    ]
}

上記のように定義すると、表示が以下のようになります。

customTemplates_2.png

templateParts

parts フォルダに配置したテンプレートパーツにメタデータを追加します。

ブロックテーマでは、parts フォルダにテンプレートとなるhtmlファイルを設置すると、管理画面の「サイトエディター > Template Parts」ページでリスト表示され、テンプレートまたは投稿内でそのテンプレートパーツを使用する事が出来ます。

例えば、parts フォルダに以下のようなテンプレートを配置したとします。

my-theme/
    └ parts/
        ├ banner1.html
        ├ banner2.html
        ├ header.html
        └ footer.html

そうすると、管理画面の「サイトエディター > Templates」ページでは、以下のように表示されます。

templateParts_1.png

templateParts プロパティで、name / title / area プロパティを持ったオブジェクトを配列内に指定する事で、このテンプレートラベルの表示を分かりやすいものに変更する事が出来ます。

  • name:(必須)ファイル名(テンプレートパーツファイル名から拡張子を除いたもの)
  • title:(任意)管理画面の「サイトエディター > Template Parts」ページ等で表示するテンプレートラベル
  • area:(任意)テンプレートパーツを使用するエリア(header or footer
theme.json
{
    "$schema": "https://raw.githubusercontent.com/WordPress/gutenberg/trunk/schemas/json/theme.json",
    "version": 2,
    "templateParts": [
        {
            "name": "header",
            "title": "ヘッダーパーツ",
            "area": "header"
        },
        {
            "name": "footer",
            "title": "フッターパーツ",
            "area": "footer"
        },
        {
            "name": "banner1",
            "title": "バナーパーツ1"
        },
        {
            "name": "banner2",
            "title": "バナーパーツ2"
        }
    ]
}

area プロパティについては、「テンプレートパーツをどのエリアに割り当てるか」を指定します。
ヘッダーエリアの場合は header、フッターエリアの場合は footer を指定し、それ以外に分類される共通のテンプレートパーツの場合は area プロパティを指定しません。

上記のように定義すると、以下のようにtitleプロパティで定義した値が表示されます。

templateParts_2.png

また、テンプレートにテンプレートパーツを配置した時に、左側のリストビューのブロックアイコンがエリアに応じたものとなり、また右サイドバーの「テンプレート」タブで「どのエリアに属するパーツか」が示されるようになります。
※area を指定していない場合は、「一般」に分類される

templateParts.png

さらに、テンプレートパーツを挿入する時に、エリアごとにパーツがグルーピングされて表示されます。

templateParts_4.png

さいごに

theme.json とフルサイト編集(ブロックテーマ)の登場により、ブロックエディターに対応したテーマでさえも「クラシック」テーマとして扱われるようになりました。

テーマのファイル構造も一新されたため、今後のテーマ開発・設計手法にも大きく影響が出ると思いますが、この記事が新たなるテーマ開発の一助になれば幸いです。

参考資料・記事執筆にあたっての引用資料

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
21
Help us understand the problem. What are the problem?