「テーマのテンプレートを直接書き換えずに、特定の要素へdata-*属性やARIA属性を足したい」「記事タイトルや本文に独自のclassやマイクロデータを付けたいけれど、親テーマを編集するとアップデートで消えてしまう」——テーマをカスタマイズしていると、こうした“あと一歩”の壁にぶつかることがあります。
Apuraテーマには、こうした要望にスマートに応えるための属性フィルターAPI(apura_attr_{context})が標準で組み込まれています。この記事では、属性出力の仕組みであるapura_attr() / apura_get_attr()の動作から、子テーマやプラグインから安全に属性を追加・変更する方法、そして実用的な拡張例までを順番に解説します。
属性フィルターAPIとは何か
多くのテーマでは、HTMLタグの属性(classやitemprop、data-*など)がテンプレートファイルの中に直接書き込まれています。そのため属性を1つ足したいだけでも、テンプレートをまるごと子テーマにコピーして上書きする必要がありました。これはアップデート追従の手間が増え、メンテナンス性を下げる原因になります。
Apuraは、主要な要素の属性出力を「コンテキスト名」付きの一つの関数に集約しています。各コンテキストには専用のフィルターフックが用意されているため、テンプレートを触らずに、フィルター経由で属性を追加・上書き・削除できます。これにより、親テーマのアップデートで失われない、堅牢なカスタマイズが実現できます。
2つの関数:apura_attr() と apura_get_attr()
属性の出力を担うのは、テーマが提供する次の2つのテンプレートタグです。役割はWordPressの慣習どおり、echoするものと、文字列をreturnするものに分かれています。
| 関数 | 動作 | 使う場面 |
|---|---|---|
| apura_attr( $context, $attributes ) | 生成した属性文字列をその場で出力(echo)する | テンプレート内のタグに直接書き出すとき |
| apura_get_attr( $context, $attributes ) | 属性文字列を返す(return) | sprintf等で組み立てる・変数に入れるとき |
第1引数の$contextは「どの要素か」を表す識別子で、これがそのままフィルター名(apura_attr_{context})の一部になります。第2引数の$attributesは、属性名をキー、属性値を値とした連想配列です。テンプレート側では、たとえば本文ラッパーが次のように書かれています。
<div <?php apura_attr( 'entry-content' ); ?>>
<?php the_content(); ?>
</div>
この'entry-content'というコンテキストに対しては、テーマ標準でitemprop="articleBody"が付与されます。私たちはapura_attr_entry-contentフィルターを使うことで、この出力に独自の属性を足し込めるわけです。
属性値の3つのルール(true・空・文字列)
フィルターで値を返すときは、属性配列の「値の型」によって出力が変わります。これを理解しておくと、真偽属性や条件付き属性をきれいに扱えます。apura_get_attr()の内部ロジックは次のとおりです。
| 値 | 出力結果 | 例 |
|---|---|---|
| true | キーのみ出力(真偽属性) | 'itemscope' => true → itemscope |
| false / null / '' (空文字) | 出力されない(スキップ) | 条件で属性を消したいとき |
| 上記以外の文字列・数値 | key="value" 形式で出力(値はesc_attr) | 'data-id' => 12 → data-id="12" |
主なコンテキスト一覧
属性フィルターはサイトの広範囲で使われています。よく利用するコンテキストを抜粋して紹介します。フィルター名は、いずれもapura_attr_にコンテキスト名を続けた形になります(例:apura_attr_article)。
| コンテキスト | 対象要素 | 標準で付く属性の例 |
|---|---|---|
| body | body タグ | itemtype="https://schema.org/WebPage" |
| header | サイトヘッダー | itemtype="https://schema.org/WPHeader" |
| article | 記事の article 要素 | itemtype="https://schema.org/Article" |
| entry-title | 記事タイトル | itemprop="headline" |
| entry-content | 本文ラッパー | itemprop="articleBody" |
| sidebar | サイドバー | itemtype="https://schema.org/WPSideBar" |
| footer | サイトフッター | itemtype="https://schema.org/WPFooter" |
このほかにも、パンくず(breadcrumb)、ナビゲーション(header_nav / mobile_nav / footer_nav)、著者情報(post-author / author-card)、コメント(comment__contentなど)といったコンテキストが用意されています。どのコンテキストが使えるか確実に知りたいときは、テーマ内をapura_get_attr( で検索すると、テンプレートで実際に使われているコンテキスト名を一覧できます。
実践:子テーマから属性を追加・変更する
ここからは具体的な使い方を見ていきます。いずれも子テーマのfunctions.phpに記述する想定です。フィルターのコールバックは、第1引数で属性配列を受け取り、加工してreturnするだけ、という非常にシンプルな構造です。
例1:本文ラッパーにdata属性とclassを追加する
記事本文の要素に、計測用のdata-content="post-body"と、独自のクラスを追加してみます。既存のitempropはそのまま残しつつ、新しいキーを足すだけです。
<?php
add_filter(
'apura_attr_entry-content',
function ( $attributes ) {
// 既存の属性(itemprop など)は維持したまま追記する。
$attributes['data-content'] = 'post-body';
$attributes['class'] = 'my-entry-content';
return $attributes;
}
);
出力されるタグは <div itemprop="articleBody" data-content="post-body" class="my-entry-content"> のようになります。テンプレートを一切コピーせず、属性だけをきれいに足せました。
例2:条件分岐で属性を出し分ける
フィルター内では条件分岐タグも使えます。たとえば「特定カテゴリーの記事のbodyにだけ目印クラスを付ける」といった処理が可能です。
<?php
add_filter(
'apura_attr_body',
function ( $attributes ) {
if ( is_singular( 'post' ) && has_category( 'campaign' ) ) {
$attributes['data-campaign'] = 'active';
}
return $attributes;
}
);
例3:既存の属性を上書き・削除する
SEOプラグインで構造化データを別途出力していて、テーマ側のitempropと重複させたくない、というケースもあります。値をfalse(または空文字)にすれば、その属性は出力対象から外れます。
<?php
add_filter(
'apura_attr_article',
function ( $attributes ) {
// itemscope / itemtype を出力しない(空にするとスキップされる)。
$attributes['itemscope'] = false;
$attributes['itemtype'] = '';
return $attributes;
}
);
第2引数とコールバックの優先度
フィルターには第2引数として$context(コンテキスト名そのもの)が渡されます。複数のコンテキストに同じ処理を適用したいときに、1つのコールバックで使い回せて便利です。受け取るにはadd_filter()の第3・第4引数で優先度と引数の数を指定します。
<?php
$common = function ( $attributes, $context ) {
$attributes['data-context'] = sanitize_html_class( $context );
return $attributes;
};
// 優先度10、引数2つを受け取る設定。
add_filter( 'apura_attr_header', $common, 10, 2 );
add_filter( 'apura_attr_footer', $common, 10, 2 );
テーマ標準の属性(Schema.orgなど)は優先度10で追加されています。それより後に自分の値を反映させたい場合は、優先度を大きく(例:20)すると安全です。逆に標準値より先に下地を作りたいときは小さな値を指定します。
安全に使うためのチェックポイント
属性フィルターは強力ですが、WordPress開発の基本原則は守りましょう。最後に、安全で壊れないカスタマイズのためのポイントをまとめます。
- コールバックは必ず
$attributesをreturnする。条件に合わないときも、加工せずそのまま返す。 - 既存キーを意図せず潰さない。新しい属性は別キーで追加し、上書きが必要なときだけ既存キーへ代入する。
- 属性値の出力エスケープ(
esc_attr)はテーマ側で行われるが、外部入力を値に使うときはsanitize_text_field()やsanitize_html_class()などで入力のサニタイズを自分でも行う。 - クラスを足すときはスペース区切りで連結し、既存クラスを消さないよう
$attributes['class'] = trim( ( $attributes['class'] ?? '' ) . ' my-class' );のように追記する。