2026年6月21日
2026年6月21日
WordPressのテーマにウィジェットエリアを追加する手順(register_sidebarと表示コード)
テーマに新しいウィジェットエリアを追加するには、子テーマの functions.php で register_sidebar() を使ってエリアを登録し、表示したい場所で dynamic_sidebar() を呼び出します。この記事では、登録から表示、記事下への差し込み、ブロックテーマでの代替策までを順に説明し、作業後にどこを見れば正しく動いているか判断できるようにします。
作業の前に確認しておくこと
ウィジェットエリアの仕組みは、主にクラシックテーマ(PHPテンプレートで作られたテーマ)のためのものです。Twenty Twenty-Four や Twenty Twenty-Five のようなブロックテーマでは、管理画面の「外観」に「ウィジェット」メニューがなく、サイトエディターでテンプレートパーツを編集する方式が基本になります。ブロックテーマを使っている場合は、後半の「ブロックテーマでの代替策」を先に読んでください。
作業に入る前に、次の2点を用意します。
- 子テーマ:親テーマの functions.php やテンプレートを直接書き換えると、テーマ更新で変更が消えます。追加コードは子テーマに書きます。
- バックアップ:functions.php の書き間違いは画面が真っ白になる原因になります。編集前にファイルを手元に保存し、できればFTPやファイルマネージャーで元に戻せる状態にしておきます。管理画面のテーマファイルエディターだけで作業すると、エラー時に戻す手段がなくなるので避けたほうが安全です。
ステップ1:register_sidebar でエリアを登録する
ウィジェットエリアの登録は widgets_init フックの中で行います。このフックより早いタイミングで register_sidebar() を呼ぶと、ウィジェットの仕組みがまだ準備できていないため正しく登録されません。
<?php
// 子テーマの functions.php に追記
add_action( 'widgets_init', 'mychild_register_widget_areas' );
function mychild_register_widget_areas() {
register_sidebar(
array(
'name' => '記事下エリア',
'id' => 'after-post-content',
'description' => '投稿本文の直後に表示されます。',
'before_widget' => '<section id="%1$s" class="widget %2$s">',
'after_widget' => '</section>',
'before_title' => '<h2 class="widget-title">',
'after_title' => '</h2>',
)
);
}
各引数の役割は次のとおりです。
name:管理画面に表示される名前です。日本語で構いません。id:エリアを識別する文字列です。半角の小文字・数字・ハイフンで付けます。大文字や空白を含めると、表示側の指定と一致しないなどの不具合のもとになります。before_widget/after_widget:ウィジェット1つ分を囲むHTMLです。%1$sにはウィジェット固有のID、%2$sにはウィジェットの種類を示すクラスが入るので、CSSでの調整に使えます。before_title/after_title:ウィジェットのタイトルを囲むHTMLです。ページ内の見出し階層に合わせて h2 や h3 を選びます。
ここでつまずきやすいのが id の変更です。ウィジェットの配置は「どのIDのエリアに何が入っているか」という形で保存されるため、運用開始後にIDを変えると、入れていたウィジェットが「使用停止中のウィジェット」側に移ってしまいます。IDは最初に決めたら変えない前提で付けてください。
同じ形のエリアを複数まとめて作りたい場合は register_sidebars() も使えますが、名前やIDが連番になるため、管理画面で区別しにくくなります。数が少ないなら register_sidebar() を必要な回数呼ぶほうが分かりやすいです。
ステップ2:管理画面で登録を確認する
コードを保存したら、「外観」→「ウィジェット」を開きます。WordPress 5.8 以降はブロックベースのウィジェット画面になっており、登録したエリアが「記事下エリア」というパネルとして並んでいれば登録は成功です。カスタマイザーの「ウィジェット」からも同じエリアを編集できます。
ここで試しに段落ブロックなどを1つ入れておくと、次の表示確認がしやすくなります。ブロック形式のウィジェット画面が使いにくい場合は、公式の「Classic Widgets」プラグインで従来の画面に戻す方法もあります。
エリアが表示されないときは、次の順に確認します。
- 編集したのが有効化中の子テーマの functions.php か
add_action( 'widgets_init', ... )の関数名と、実際の関数名が一致しているか- 使っているのがブロックテーマではないか
ステップ3:テンプレートに dynamic_sidebar を書いて表示する
登録しただけではサイトには何も出ません。表示したい場所で dynamic_sidebar() を呼びます。そのとき is_active_sidebar() で「ウィジェットが1つ以上入っているか」を先に調べると、空のエリアのために余計な外枠のHTMLが出力されるのを防げます。
<?php if ( is_active_sidebar( 'after-post-content' ) ) : ?>
<aside class="after-post-widgets">
<?php dynamic_sidebar( 'after-post-content' ); ?>
</aside>
<?php endif; ?>
このコードを置く場所は、親テーマのテンプレート構成によって異なります。投稿ページなら single.php や、そこから読み込まれる template-parts 内のファイル、全ページのフッターなら footer.php が一般的です。親テーマの該当ファイルを子テーマの同じ階層にコピーし、コピーした側に追記すれば、子テーマのファイルが優先して使われます。
ただし、テンプレートを丸ごとコピーすると、親テーマの更新で元ファイルが改善されても子テーマ側には反映されません。コピーするファイルは必要最小限にとどめてください。
ステップ4:テンプレートをコピーせずに記事下へ差し込む
「投稿本文の直後」に表示したいだけなら、the_content フィルターで本文の後ろにエリアを付け足す方法もあります。テンプレートをコピーしないので、親テーマの更新の影響を受けにくいのが利点です。
<?php
// 子テーマの functions.php に追記
add_filter( 'the_content', 'mychild_append_widget_area', 20 );
function mychild_append_widget_area( $content ) {
// 投稿の詳細ページ、かつメインループの本文だけに限定する
if ( ! is_singular( 'post' ) || ! in_the_loop() || ! is_main_query() ) {
return $content;
}
if ( ! is_active_sidebar( 'after-post-content' ) ) {
return $content;
}
ob_start();
echo '<aside class="after-post-widgets">';
dynamic_sidebar( 'after-post-content' );
echo '</aside>';
return $content . ob_get_clean();
}
dynamic_sidebar() は戻り値ではなく直接HTMLを出力する関数なので、ob_start() と ob_get_clean() で出力を文字列として受け取り、本文に連結しています。条件分岐を省くと、関連記事の抜粋やウィジェット内の投稿表示など、本文が使われるあらゆる場所にエリアが出てしまうため、in_the_loop() と is_main_query() での限定は外さないでください。
ステップ5:表示を確認してCSSを整える
投稿ページを開き、ブラウザの開発者ツールで after-post-widgets クラスの要素があるか、その中に widget クラスの section が並んでいるかを確認します。キャッシュ系プラグインを使っている場合は、変更が反映されないときにキャッシュを削除してから見直します。
見た目の調整は子テーマの style.css で行います。
.after-post-widgets {
margin-top: 3rem;
padding-top: 2rem;
border-top: 1px solid #ddd;
}
.after-post-widgets .widget + .widget {
margin-top: 2rem;
}
親テーマが .widget に対してサイドバー前提の幅や余白を指定していることがあります。思ったより狭く表示される場合は、開発者ツールで親テーマのどのCSSが効いているかを確認し、.after-post-widgets .widget のように範囲を絞って上書きします。
ブロックテーマでの代替策
ブロックテーマでは、ウィジェットエリアの代わりに次の方法で「後から中身を差し替えられる共通部分」を作ります。
- テンプレートパーツ:サイトエディターでヘッダーやフッターと同じように独立した部品を作り、投稿テンプレートの本文の下に配置します。中身を変えたいときはそのテンプレートパーツだけを編集します。
- 同期パターン:複数のページで同じブロックの組み合わせを使い回し、1か所の編集で全体に反映させたい場合に向いています。
ブロックテーマで register_sidebar() を書くと管理画面にウィジェット画面が現れることがありますが、テーマのテンプレート側に表示箇所が用意されていなければサイトには出力されません。ブロックテーマを使い続けるなら、サイトエディターの機能で組み立てるほうが自然です。ブロックテーマの画面名や機能はWordPressの更新ごとに変わることがあるため、作業時点の表記を確認してください。ここでの説明は一般的な構成に基づいています(2026年10月現在)。
よくあるつまずき
- エリアは出るがサイトに表示されない:
dynamic_sidebar()に渡したIDとregister_sidebar()のIDが一致しているか確認します。 - テーマを切り替えたらウィジェットが消えた:ウィジェットの配置はエリアのIDに結び付いているため、別テーマに同じIDのエリアがないと「使用停止中のウィジェット」に移ります。元のテーマに戻すか、移動先エリアに配置し直します。
- 画面が真っ白になった:functions.php の構文エラーが疑われます。FTPなどで子テーマの functions.php を編集前のものに戻し、wp-config.php で
WP_DEBUGを有効にしてエラー内容を確認します。
まとめ
- ウィジェットエリアは
widgets_initフック内のregister_sidebar()で登録し、表示箇所でis_active_sidebar()とdynamic_sidebar()を組み合わせて呼び出します。 idは半角小文字で付け、運用開始後は変更しません。変更するとウィジェットの配置が外れます。- 記事下だけなら
the_contentフィルターで差し込むと、テンプレートをコピーせずに済みます。 - コードは子テーマに書き、編集前にバックアップを取っておきます。
- ブロックテーマではテンプレートパーツや同期パターンで同じ目的を果たします。