2022/11/27

WordPressサイトエディター対応のブロックテーマ開発(基本編)

WordPressのオリジナルテーマには大きく分けて2種類の作り方があります。PHPファイルを使ってサイトの各画面を実装するクラシックテーマと、サイトエディターを使って自由にサイトの構成要素を編集することができるブロックテーマです。

この記事では、ブロックテーマ開発の基本についてご紹介します。なお、この記事の内容はWordPress 6.1時点の内容をもとにしています。

ブロックテーマとは

ブロックテーマとは、WordPress 5.9にて導入された新しいWordPressテーマの形式です。相対的に、画面ごとにPHPファイルを用意する従来の形式はクラシックテーマと呼ばれています。

ブロックと呼ばれる部品を使ってサイト全体が構成されていることが特徴で、テーマを利用するユーザーがブロックをサイトエディターで組み替えることで、ヘッダーやフッターを含むサイトのあらゆる箇所の内容を編集できます(Full Site Editing = FSEとも呼ばれています)。

WordPress公式のテーマ Twenty Twenty-Three のサイトエディター画面

サイトエディターでは、記事編集画面(Gutenberg以降)と同じブロックエディター・ブロックを使えます。ブログ記事では普通使用しない、クエリした記事の繰り返しを表示するためのクエリーループ、記事画面で使用するコメントコメント投稿フォームなど、サイトを構成するために必要なブロックを使ってサイトを構築していきます。

普段の記事制作であまり使わない「テーマ」カテゴリーのブロック

ブロックテーマ開発について

サイトの構成要素をユーザーがカスタマイズできるブロックテーマにおいて、テーマ開発者が用意できるのは以下の内容です。

  • テーマを有効化した直後に適用される、テンプレートごとのデフォルトのブロックの組み合わせ
  • サイト全体や各ブロックに適用される、テキストの設定やカラーパレット、マージンやパディングなどのスタイルのデフォルト値
  • サイトエディターで呼び出すことができるテンプレートパーツのデフォルト設定
  • 開発者が作成したパターン
  • テーマの見た目や機能を実現するためのCSSやJavaScript、フォントなどのアセットファイル
  • functions.php
  • テーマ名およびテーマのメタ情報

ここで、いくつかブロックテーマ開発において知っておきたい用語が出てきたのでご紹介します。

テンプレート

テンプレートは「ホーム」「アーカイブ」「単一ページ」「404ページ」など、ブロックの表示設定を変える単位である画面のことを指します。クラシックテーマで画面ごとにPHPファイルを用意していた場合は、その分け方だと思っていただければ大丈夫です。

テンプレート一覧画面

WordPressで定義されたテンプレート種別のほか、開発者やユーザーが自由にテンプレートを追加する(カスタムテンプレート)ことも可能で、投稿や固定ページの設定で適用するテンプレートを選択できるようになっています。

テンプレートパーツ

テンプレートパーツは「ヘッダー」「フッター」など、各テンプレートから呼び出すことができる、ブロック定義をひとまとまりにしたものを指します。複数のテンプレートで一部の見た目やブロック構成を共通にしたい場合に使用します。

「ヘッダー」テンプレートパーツの編集画面

パーツという名前ですが、ブロックを使って定義するようになっており、ユーザーが編集することも可能です。「ヘッダー」「フッター」に加え、ヘッダーやフッターの別パターンを作成したり、開発者やユーザーが任意で作成することが可能です。

パターン

パターンも、ブロック定義をひとまとまりにしたものに名前をつけたものです。よく使うブロック定義をプリセットとして用意しておけると言い換えても良いと思います。テンプレートパーツと異なり、パターンは使用する際にコンテンツの内容を書き換えることが前提となります。

サイトエディターでのパターン追加

上のスクリーンショットでは「Call to action」や「3カラムのテキスト」などがパターンとして登録されています。WordPressにデフォルトで用意されているパターンもあり、記事や固定ページの編集画面でも呼び出すことができるので、使ったことがある人もいるかもしれません。

このパターンを、テーマ独自で追加することができます。特定のブロックに対してパターンを作成することもできます。ただし、パターンもブロック定義の組み合わせですので、独自のタグを含むなどカスタマイズされた内容を追加することはできません。

ブロックテーマ開発の最初の一歩

WordPress 6.1現在、ブロックテーマとしてテーマを認識させるには、以下のファイルが必要です。

  • style.css
  • templates/index.html
  • theme.json

style.cssはこれまでと同様にテーマに関する情報を記載します。

/*
Theme Name: Awesome wordpress theme
Theme URI: https://example.com
Author: xxx
Author URI: https://example.com
Description: Awesome wordpress theme
Version: 1.0
Requires at least: 6.1
*/

index.htmlは空のファイルでOKです。

theme.jsonにはテーマ全体のカスタマイズ設定を記載するのですが、最低限の内容としてJSONスキーマのバージョン(現在は固定値2)を記載しておきます。

{
    "version": 2
}

この状態でテーマを適用すると、以下のようなサイト表示になります(ログイン時)。

空のテンプレートのままサイトを表示した様子

また、外観 > エディター(またはテーマ一覧から「カスタマイズ」)を選択すると、サイトエディターが使用できるようになっています。

外観メニューの「エディター」、またはカスタマイズボタンからサイトエディターを開ける

サイトエディターでテンプレートを編集する

サイトエディターで「サイトのタイトル」と「クエリループ」を挿入してみました。この状態で保存すると、サイトがカスタマイズした通りに表示されるようになります。

「サイトのタイトル」ブロックと「クエリループ」(画像と概要が横並びのパターン)ブロックを適用したサイトエディター画面

テンプレートを追加する

インデックスのみの定義だと、記事のタイトルをクリックしても同じ見た目のページが表示されてしまいます。単一ページ用のテンプレートを作成しましょう。エディターのテンプレートページ「新規作成」ボタンから「単一」テンプレートを選択します。

適用先ごとにテンプレートを作成できます

単一テンプレートではブロックのうち「テンプレート」カテゴリーの投稿に関するブロックを主に使用します。「アイキャッチ画像」「投稿タイトル」「投稿コンテンツ」「区切り」「カテゴリー」「タグ」(カテゴリーとタグは2カラムブロックそれぞれのカラムに追加)を設定した様子が以下です。

投稿した内容を表示するテンプレートを制作

この状態で保存すると、記事の詳細ページではこのテンプレートが使われるようになります。

単一テンプレートを作成した後のテンプレート一覧画面が以下です。ユーザー自身が追加した単一テンプレートは、追加者がテーマではなくユーザー名になっています。

テーマに用意されていないテンプレートは追加者がユーザー名になるほか、
テーマのデフォルトからブロック構成が変更されている場合は追加者のアイコンに青い丸がつく

テンプレート情報の保存先

このような手順でユーザーが管理画面から編集した、インデックステンプレートや単一テンプレートの設定はすべてデータベース※に保存されます。最初に用意したHTMLファイルやJSONファイルなどに書き込まれるわけではありません。このように、同じテーマを有効化したであっても、エディターによって全く違う構成のサイトを作成できるのが、ブロックテーマの特徴です。

※実際はwp_template(テンプレートパーツはwp_template_part)というカスタム投稿タイプとして保存されます。

デフォルトのブロック設定を用意する

ユーザーに一からブロック設定をしてもらうのでは、テーマ利用までに時間がかかり、気軽にテーマを利用してもらうことができません。ブロックテーマでは、各テンプレートでのデフォルトのブロック設定を用意することができます。

試しに、カテゴリーページを作成してみましょう。templates/category.htmlを作成し、以下の内容を記載します。

<!-- wp:site-title /-->

<!-- wp:query-title {"type":"archive"} /-->

<!-- wp:term-description /-->

<!-- wp:query {"query":{"perPage":5,"pages":0,"offset":0,"postType":"post","order":"desc","orderBy":"date","author":"","search":"","exclude":[],"sticky":"","inherit":true}} -->
<div class="wp-block-query">
    <!-- wp:post-template -->
        <!-- wp:post-title {"isLink":true} /-->
        
        <!-- wp:post-featured-image {"isLink":true,"align":"wide"} /-->
        
        <!-- wp:post-excerpt /-->
        
        <!-- wp:separator {"opacity":"css"} -->
            <hr class="wp-block-separator has-css-opacity"/>
        <!-- /wp:separator -->
        
        <!-- wp:post-date /-->
    <!-- /wp:post-template -->
    
    <!-- wp:query-pagination -->
        <!-- wp:query-pagination-previous /-->
        
        <!-- wp:query-pagination-numbers /-->
        
        <!-- wp:query-pagination-next /-->
    <!-- /wp:query-pagination -->
</div>
<!-- /wp:query -->

このテンプレートを適用すると、以下のようなカテゴリーページが出来上がります。

Techカテゴリーのタイトルと説明、記事一覧が表示されている

同じテンプレートをサイトエディターで開いたところです。サイト名、アーカイブタイトル(カテゴリーの名前)、説明、記事クエリのブロックが順に並んでいます。

カテゴリーテンプレートの編集画面

このように、各ブロックを配置するためのコード(ブロックマークアップ)をHTMLファイルに記載することで、デフォルトのブロックを設定することができます。

最初に作成したインデックステンプレートについても、空だったindex.htmlにブロックの設定を書き込んでみましょう。インデックステンプレートをサイトエディターで開き「コードエディター」を表示します。

サイトエディターのメニューからコードエディターに切り替えることができる

以下のように、設定済みブロックを構成するためのブロックマークアップが表示されます。

ブログ記事の投稿画面でもコードエディターで似たような表示を見たことがある人もいるかもしれません

スクリーンショットの内容を整形したものが以下の通りです。
wp:queryの属性として記載されていたqueryIdは環境によって異なるため削除しています)

<!-- wp:site-title /-->

<!-- wp:query {"query":{"perPage":3,"pages":0,"offset":0,"postType":"post","order":"desc","orderBy":"date","author":"","search":"","exclude":[],"sticky":"","inherit":true}} -->
<div class="wp-block-query">
    <!-- wp:post-template -->
        <!-- wp:columns {"align":"wide"} -->
        <div class="wp-block-columns alignwide">
            <!-- wp:column {"width":"66.66%"} -->
            <div class="wp-block-column" style="flex-basis:66.66%">
                <!-- wp:post-featured-image {"isLink":true} /-->
            </div>
            <!-- /wp:column -->
    
            <!-- wp:column {"width":"33.33%"} -->
            <div class="wp-block-column" style="flex-basis:33.33%">
                <!-- wp:post-title {"isLink":true} /-->
                <!-- wp:post-excerpt /-->
            </div>
            <!-- /wp:column -->
        </div>
        <!-- /wp:columns -->
    <!-- /wp:post-template -->
</div>
<!-- /wp:query -->

これをindex.htmlに書き込んで保存します。

最後に、データベースに保存しているインデックステンプレートのブロック設定を削除します。テンプレート一覧から該当テンプレートの「カスタマイズをクリア」することで、HTMLファイルで定義した内容が使われるようになります。

テンプレート一覧画面のほか、テンプレート編集画面からでもカスタマイズをクリアできます

ブロックマークアップの記述仕様

ブロックマークアップについて、公式ドキュメントに記載されている仕様を確認してみましょう。

テンプレート(およびテンプレートパーツ)では、ブロックを配置するためのブロックマークアップを使用します。ブロックマークアップから生成されたブロックは、bodyタグの内部に出力されます。

ブロックマークアップはHTMLコメントで記述し、「プレフィックス」「ブロック名」「属性」を含みます。例えば、これまでの例にも登場した、サイトタイトルを表示するマークアップは以下の通りです。wp:が接頭辞、site-titleがブロック名です。

<!-- wp:site-title /-->

属性はブロック名の後に、JSON形式で続けます。以下の例は、サイトタイトルをデフォルトのH1タグではなくH2タグで出力するためのマークアップです。

<!-- wp:site-title {"level":2} /-->

ユーザーによる入力を含む場合など、ブロックによって複数行にまたがる記述をする場合もあります。例えば、H3の見出しを定義するためのマークアップは以下の通りです。

<!-- wp:heading {"level":3} -->
<h3>Hello world</h3>
<!-- /wp:heading -->

ここでの注意点として、ブロックの属性とその結果生成されるHTMLの両方を記述する必要があります。

例えば、この見出しの色を#ff7e7eに変更する設定をする場合を考えます。

サイトエディターで、H3見出しのテキスト色を変更する操作にあたります

見出しを表すwp:headingの属性で色を設定する場合、"style":{"color":{"text":"#ff7e7e"}}という記述を追加します。加えて、このスタイル設定を行なった場合、WordPress側でH3タグを生成する際に以下のような変化が生じます。

  • style属性で文字色が設定される
  • .has-text-colorというクラスが設定される

結果として、以下のようなブロックマークアップを記述する必要があります。HTMLコメント内のJSONと生成されたHTML、どちらか片方だけを変更しても、正しく反映されません。

<!-- wp:heading {"level":3,"style":{"color":{"text":"#ff7e7e"}}} -->
<h3 class="has-text-color" style="color:#ff7e7e">コメント</h3>
<!-- /wp:heading -->

ブロックマークアップを実装する

現在、それぞれのブロックを実現するためのブロックマークアップについては、公式リファレンスが存在しません。また、属性のJSONだけならまだしも、その出力結果のHTMLも正しく記述しないといけないため、これらを覚えたり調べながら実装するのは難しいです。

そのため、以下のいずれかの手順を使うのが現実的です。

  • サイトエディターでブロックを実装した後、コードエディターに切り替えてマークアップを確認する
  • サイトエディターでブロックを実装した後、オプションメニューから「ブロックをコピー」を選択する(マークアップがコピーされます)
  • サイトエディターで一通りのブロックの実装を終えた後、サイトエディターメニューの「エクスポート」から一括でテーマをエクスポートする

特に3つ目のエクスポート機能は強力で、データベースに保存されているカスタマイズを含むすべての設定をテーマファイルの形で一括ダウンロードすることが可能です。これまでのコーディングによる実装とはかなり方法が異なりますが、サイトエディターを活用することで、ノーコードでテーマ制作できる範囲が広がったと言えます。

なお、各ブロックの実装についてはGitHubで閲覧することができ(wp-includes/blocks/)、各ブロックのblock.jsonを見ることで、ブロック属性として指定可能なパラメーターなどを確認できます。フォント設定や色設定など、ブロック共通項目についての各ブロックの対応状況は公式ブログにもまとめられています(一覧 / 項目ごとのリスト)。

ページの横幅を変更する

最後に、theme.jsonを使ったカスタマイズ例として、ページ全体の横幅を設定してみたいと思います。現在のテーマでは、画面の横幅いっぱいに要素が表示されます。スマートフォンであれば良いですが、PCではページが見づらくなってしまうため、横幅の最大値を指定してみましょう。

theme.jsonを以下のように変更し、コンテンツの横幅を指定します。

{
    "version": 2,
    "settings": {
        "layout": {
            "contentSize": "42rem"
        }
    }
}

続いて、各パーツで「コンテンツ幅を使用する」設定をオンにします。

インデックステンプレートなどで使用したクエリループブロックには、レイアウトの設定の中で切り替えができるようになっています。

クエリループブロックを選択し、ブロック設定から「コンテント幅を使用するレイアウト」にチェックを入れる

単一ページテンプレートで使用した「投稿タイトル」「投稿日」などのブロックにはレイアウト設定がありません。この場合は、コンテンツ幅を適用できる「グループ」ブロックに内包するように各ブロックを配置します。

「グループ」ブロックを使うと複数のブロックをまとめることができる

グループブロックのマークアップは以下の通りです。layout.type: constrainedという設定が、コンテンツ幅を使用する設定を表しています。

<!-- wp:group {"layout":{"type":"constrained"}} -->
<div class="wp-block-group">
    <!-- ここに内包するブロックを定義 -->
</div>
<!-- /wp:group -->

この記事で紹介できなかった要素

この記事では、ブロックテーマ開発のさわりの部分をご紹介しました。

  • ヘッダー、フッターなどのテンプレートパーツ
  • theme.jsonに指定できるテーマ全体の見た目に関する設定
  • ブロック別CSSを使ったスタイルの変更
  • パターンの定義

など、より便利なテーマにするための機能がまだまだあるので、それらについてもまたご紹介できればなと思っています。

2022/12/3公開: テンプレートパーツ、ブロック別CSS、パターンについて以下の記事で紹介しています

2022/12/5公開: theme.jsonについて以下の記事で紹介しています

まとめ

クラシックテーマとは開発の流れが全く異なるブロックテーマについて、その開発の概要をご紹介しました。このブログをWordPressテーマで制作しなおすにあたり、ブロックテーマ方式で途中まで実装した際に調べた内容をまとめたものです。従来のクラシックテーマと概念がかなり異なっており、理解するのに時間がかかりました。この記事が、ブロックテーマ開発の一助となれば幸いです。

なお、ブロックテーマ開発に際しては、公式ドキュメントが最も確かな情報源となります。記事に記載の情報は記事執筆時点の情報であり、最新情報を確認しながら実装いただければと思います。

ブロックエディターについてのリファレンスもあります。theme.jsonのリファレンスなどはこちらを参照してください。また、サポート記事も掲載されています。

なお、この記事の執筆および最初のテーマ作成にあたっては、フルサイト編集に対応したブロックテーマを作ってみるを参考にさせていただきました。こちらの記事は環境が5.8 RC1のため現行仕様と異なる部分もありますが、こちらもあわせてご参照いただければと思います。

参考リンク

Share with Hatena Bookmark

関連記事