成果物をまとめて確認する
[成果物]テンプレートとfunctions.phpの整理によるコード保守性の向上
【テンプレートとfunctions.phpの整理によるコード保守性の向上】の成果物です。投稿の学びを終えた時点の構成を一覧でご確認いただけます。
前回の記事でカフェメニューシステムが完成しましたが、開発を進めるうちに各テンプレートファイルに同じようなコードが重複して記述され、functions.phpも肥大化してきました。
今回は、コードの整理整頓により保守性を向上させる技術について学習します。これにより、機能追加や修正が格段に行いやすくなる開発環境を整えましょう。
今回の目標
目次
WordPressテーマ開発が進むと、以下のような2つの問題が発生します。
複数のテンプレートで同じメニュー表示コードを記述することになり、以下の問題が生じます。
様々な機能を追加していくと、functions.phpに以下のコードが混在します。
これにより、どこに何が書かれているかが分からなくなり、メンテナンスが困難になります。
WordPressには、これらの問題を解決するコードを整理整頓する仕組みが用意されています。
今回学習する2つの解決アプローチ。
これらにより、コードの保守性が大幅に向上します。
前回までの作業で、以下のメニュー表示コードが複数箇所に重複して記述されています。
page-cafe-menu.php(カフェメニュー一覧)とtaxonomy-tax-menu.php(カテゴリー別一覧)の両方に、ほぼ同じコードが存在しています。
<?php
// Smart Custom Fieldsの繰り返しフィールドから価格を取得
$prices = SCF::get('price_group');
$first_price = '';
if (!empty($prices) && !empty($prices[0]['price'])) {
$first_price = $prices[0]['price'] . '円〜';
}
?>
<li class="menu-item">
<h3><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h3>
<?php if (has_post_thumbnail()) : ?>
<div class="menu-thumbnail">
<a href="<?php the_permalink(); ?>">
<?php the_post_thumbnail('medium'); ?>
</a>
</div>
<?php endif; ?>
<?php if (has_excerpt()) : ?>
<p class="menu-excerpt"><?php the_excerpt(); ?></p>
<?php endif; ?>
<?php if ($first_price) : ?>
<p class="menu-price"><?php echo $first_price; ?></p>
<?php endif; ?>
</li>
PHPこの重複により、デザインを変更したい場合は2箇所を修正する必要があり、修正漏れのリスクがあります。
WordPressにはget_template_partという関数があり、共通のコードを外部ファイル化して読み込むことができます。
テーマフォルダ内にpartsフォルダを作成し、共通のメニュー項目表示用ファイルmenu-item.phpを作成します。
<?php
// Smart Custom Fieldsの繰り返しフィールドから価格を取得
$prices = SCF::get('price_group');
$first_price = '';
if (!empty($prices) && !empty($prices[0]['price'])) {
$first_price = $prices[0]['price'] . '円〜';
}
?>
<li class="menu-item">
<h3><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h3>
<?php if (has_post_thumbnail()) : ?>
<div class="menu-thumbnail">
<a href="<?php the_permalink(); ?>">
<?php the_post_thumbnail('medium'); ?>
</a>
</div>
<?php endif; ?>
<?php if (has_excerpt()) : ?>
<p class="menu-excerpt"><?php the_excerpt(); ?></p>
<?php endif; ?>
<?php if ($first_price) : ?>
<p class="menu-price"><?php echo $first_price; ?></p>
<?php endif; ?>
</li>
PHPpage-cafe-menu.phpでmenu-item.php読み込むため、以下のように修正します。
<?php get_header(); ?>
<?php the_content(); ?>
<?php
// メニューカテゴリーを term_order 順で取得
$menu_categories = get_terms(
array(
'taxonomy' => 'tax-menu',
'hide_empty' => true,
'orderby' => 'term_order',
'order' => 'ASC'
)
);
foreach ($menu_categories as $category) :
?>
<h2>
<a href="<?php echo get_term_link($category); ?>">
<?php echo $category->name; ?>
</a>
</h2>
<?php
$args = [
'post_type' => 'menu_post',
'post_status' => 'publish',
'orderby' => 'menu_order',
'order' => 'ASC',
'posts_per_page' => -1,
'tax_query' => array(
array(
'taxonomy' => 'tax-menu',
'field' => 'term_id',
'terms' => $category->term_id,
),
),
];
// 現在のカテゴリーに属するメニューを取得
$menu_query = new WP_Query($args);
?>
<ul class="menu-list">
<?php
while ($menu_query->have_posts()) :
$menu_query->the_post();
get_template_part('parts/menu-item');
endwhile;
?>
</ul>
<?php
wp_reset_postdata();
endforeach;
?>
<p>※このページは page-cafe-menu.php テンプレートで表示されています</p>
<?php get_footer();?>
PHP同じようにtaxonomy-tax-menu.phpも修正します。
<?php get_header();?>
<?php the_content(); ?>
<?php
$target = get_queried_object();
// そのカテゴリーに属する投稿を取得
$args = [
'post_type' => 'menu_post',
'post_status' => 'publish',
'orderby' => 'menu_order',
'order' => 'asc',
'tax_query' => [
[
'taxonomy' => $target->taxonomy,
'field' => 'term_id',
'terms' => $target->term_id,
]
]
];
// 現在のカテゴリーに属するメニューを取得
$menu_query = new WP_Query($args);
?>
<ul class="menu-list">
<?php
while ($menu_query->have_posts()) :
$menu_query->the_post();
get_template_part('parts/menu-item');
endwhile;
?>
</ul>
<p>※このページは taxonomy-tax-menu.php テンプレートで表示されています</p>
<?php get_footer();?>
PHPphpget_template_part('parts/menu-item');
PHP.php
は不要)これにより、メニュー項目の表示デザインを変更したい場合はparts/menu-item.phpのみを修正すれば、すべての一覧ページに反映されます。
現在のfunctions.phpには、以下のような様々な機能が混在しています。
これらすべてが1つのファイルに記述されているため、特定の機能を修正したい場合でも、長大なfunctions.phpの中から該当箇所を探す必要があります。
テーマフォルダ内にfuncフォルダを作成し、機能別のファイルを配置します。今回はフォルダ名をfuncとしましたが任意のフォルダ名で大丈夫です。
テーマフォルダ
├── functions.php
├── func
│ ├── theme-func-support.php # テーマサポート関連
│ ├── theme-func-enqueue.php # CSS・JSファイル読み込み
│ ├── theme-func-post-types.php # カスタム投稿タイプ関連
│ └── theme-func-custom.php # その他のカスタマイズ
└── parts
└── menu-item.php
ファイル名のプレフィックスについて:ファイル名の重複を避けるため「theme-func-
」というプレフィックスを付けています。
<?php
// テーマサポート機能の設定
// 外観→メニューの有効化
add_theme_support('menus');
// titleタグの有効化
add_theme_support('title-tag');
// アイキャッチ画像サポートを有効化
add_theme_support('post-thumbnails');
PHP<?php
// スタイルシートとスクリプトの読み込み
add_action('wp_enqueue_scripts', 'load_theme_style');
function load_theme_style() {
wp_enqueue_style(
'theme-main-style',
get_stylesheet_directory_uri() . '/main.css',
array(),
filemtime(get_stylesheet_directory() . '/main.css'),
);
wp_enqueue_style(
'theme-sub-style',
get_stylesheet_directory_uri() . '/sub.css',
array('theme-main-style'),
filemtime(get_stylesheet_directory() . '/sub.css'),
);
}
PHP<?php
// カスタム投稿タイプとタクソノミーの登録
// 店舗タクソノミー(通常投稿用)
add_action('init', function() {
register_taxonomy(
'tax-store',
'post',
array(
'labels' => array(
'name' => '店舗',
'singular_name' => '店舗',
'search_items' => '店舗を検索',
'all_items' => 'すべての店舗',
'parent_item' => '親店舗',
'parent_item_colon' => '親店舗:',
'edit_item' => '店舗の編集',
'update_item' => '店舗を更新',
'add_new_item' => '新しい店舗を追加',
'new_item_name' => '新しい店舗名',
'menu_name' => '店舗',
),
'hierarchical' => true,
'public' => true,
'show_in_rest' => true,
'show_admin_column' => true,
'show_in_quick_edit' => true,
'show_in_nav_menus' => true,
'query_var' => 'store',
'rewrite' => array(
'slug' => 'store',
'with_front' => true,
),
)
);
});
// カフェメニューのカスタム投稿タイプ
add_action('init', function() {
register_post_type(
'menu_post',
array(
'labels' => array(
'name' => __('カフェメニュー'),
'all_items' => __('カフェメニュー一覧'),
'add_new' => __('カフェメニューを追加する'),
'add_new_item' => __('カフェメニューの追加'),
'edit_item' => __('カフェメニューの編集'),
'singular_name' => __('カフェメニュータイプ'),
'new_item' => __('新しいカフェメニュー'),
'view_item' => __('カフェメニューを見る'),
'search_items' => __('カフェメニューを探す'),
'not_found' => __('カフェメニューはありません'),
'not_found_in_trash' => __('ゴミ箱にカフェメニューはありません'),
),
'public' => true,
'hierarchical' => false,
'supports' => array(
'title',
'editor',
'page-attributes',
'thumbnail',
'excerpt',
'custom-fields'
),
'rewrite' => array(
'slug' => 'menu',
'with_front' => false,
),
'menu_icon' => 'dashicons-food',
'show_in_rest' => true,
)
);
});
// メニューカテゴリーのカスタムタクソノミー
add_action('init', function() {
register_taxonomy(
'tax-menu',
'menu_post',
array(
'labels' => array(
'name' => 'メニューカテゴリー',
'singular_name' => 'メニューカテゴリー',
'search_items' => 'メニューカテゴリーを検索',
'all_items' => 'すべてのメニューカテゴリー',
'parent_item' => '親メニューカテゴリー',
'parent_item_colon' => '親メニューカテゴリー:',
'edit_item' => 'メニューカテゴリーの編集',
'update_item' => 'メニューカテゴリーを更新',
'add_new_item' => '新しいメニューカテゴリーを追加',
'new_item_name' => '新しいメニューカテゴリー名',
'menu_name' => 'メニューカテゴリー',
),
'hierarchical' => true,
'public' => true,
'show_in_rest' => true,
'show_admin_column' => true,
'show_in_quick_edit' => true,
'show_in_nav_menus' => true,
'query_var' => 'menu-category',
'rewrite' => array(
'slug' => 'menu-category',
'with_front' => false,
),
)
);
});
PHP<?php
// その他のカスタマイズ機能
// カスタムタイトルタグの設定
function custom_document_title($title) {
$custom_title = '';
if (is_front_page()) {
// サイトタイトルを取得
$custom_title = get_bloginfo('name');
} else {
// 現在表示中のページタイトルを取得
$custom_title = get_the_title();
// 現在ページの親ページIDを取得
$parent_id = wp_get_post_parent_id(get_the_ID());
// 親ページが存在する場合(IDが0以外)、親ページのタイトルを追加
if ($parent_id) {
// 親ページのタイトルを取得
$custom_title = $custom_title . '|';
$custom_title = $custom_title . get_the_title($parent_id);
}
// サイトタイトルを取得
$custom_title = $custom_title . '|';
$custom_title = $custom_title . get_bloginfo('name');
}
return $custom_title;
}
add_filter('pre_get_document_title', 'custom_document_title');
PHPfunctions.phpを以下のように整理します。
<?php
// テーマの基本設定とファイル読み込み
// 機能別ファイルの読み込み
require_once get_stylesheet_directory() . '/func/theme-func-support.php';
require_once get_stylesheet_directory() . '/func/theme-func-enqueue.php';
require_once get_stylesheet_directory() . '/func/theme-func-post-types.php';
require_once get_stylesheet_directory() . '/func/theme-func-custom.php';
// その他のfunctions.php独自の処理があればここに記述
PHPrequire_once get_stylesheet_directory() . '/func/theme-func-support.php';
PHPこれにより、functions.phpがスッキリと整理され、各機能の編集時は対応するファイルのみを修正すれば済みます。
今回の整理により、以下の効果が得られます。
require_once
で読み込むだけrequire_once
行をコメントアウトするだけで機能を停止今回の学習で、WordPressテーマ開発におけるコード保守性の向上技術を身につけました。
get_template_part
による共通テンプレートの外部化require_once
による適切なファイル読み込み管理これらの技術により、開発効率が向上し、メンテナンスしやすいWordPressテーマの基盤が整いました。
学習が進むにつれて、さらに多くの機能が追加されることになりますが、今回学んだ整理手法を活用することで、常に保守性の高いコードを維持できます。
この記事で作成した成果物は、以下のページでまとめて確認することができます。
カスタム投稿の基本機能に加えて、抜粋・アイキャッチ・カスタムフィールドを追加する方法を学習します。これらの機能を有効化する手順、管理画面での入力方法、テンプレートでの表示方法を理解することで、より実用的なコンテンツ管理が可能になります。
WordPressを効率よく確実に学ぶためには、学習の順序が大切です。知識が自然に積み上がるよう、学習ステップに沿って記事を順番に並べています。
学習ストーリー第39話まで掲載中