WordPress

✅【効率化テクニック】WordPressの get_template_part で爆速コーディング!パーツ分割でメンテナンス性アップ

こんにちは、コーダーのためのWeb制作ブログの中の人です!👋 今日は WordPressでのコーディングを劇的に効率化する便利な関数 get_template_part() について詳しく解説します。この関数を使いこなせば、コードの重複を減らし、メンテナンス性の高いテーマ開発ができるようになりますよ!✨

テンプレートパーツとは?🤔

WordPress開発をしていると、同じコードを複数の場所で使いまわす場面が多々あります。例えば:

  • ヘッダーやフッターの共通部分
  • 記事一覧のカード表示
  • サイドバーのウィジェット
  • お問い合わせフォーム
  • SNSシェアボタン

こういった繰り返し使用する部品を「テンプレートパーツ」として分離することで、コードの重複を避け、修正が必要な時に1箇所だけ修正すればOKという素晴らしい開発体験が得られます!

get_template_part() の基本的な使い方 💻

まずは基本的な使い方から見ていきましょう。

<?php get_template_part('parts/content'); ?>

この一行だけで、parts/content.php ファイルの内容を読み込んで表示してくれます。簡単ですね!

パラメータの詳細

この関数は主に2つのパラメータを受け取ります:

get_template_part( $slug, $name );
  • $slug: 必須パラメータ。テンプレートの基本名(ファイルパス)
  • $name: オプションパラメータ。テンプレートのバリエーション名

例えば:

<?php get_template_part('parts/content', 'post'); ?>

この場合、WordPressは以下のファイルを順番に探します:

  1. parts/content-post.php
  2. 見つからなければ、parts/content.php

これによって、共通部分と個別のバリエーションを効率よく管理できるのです!

実際のディレクトリ構成例 📁

効率的なテーマ開発では、以下のようなディレクトリ構成がおすすめです:

theme-directory/
├── style.css
├── functions.php
├── index.php
├── single.php
├── page.php
├── archive.php
├── header.php
├── footer.php
├── sidebar.php
└── parts/
    ├── content.php        // 投稿の基本表示
    ├── content-single.php // 投稿詳細用
    ├── content-page.php   // 固定ページ用
    ├── content-card.php   // カード表示用
    ├── hero-banner.php    // トップページのヒーローバナー
    ├── related-posts.php  // 関連記事
    ├── share-buttons.php  // シェアボタン
    └── newsletter.php     // ニュースレター登録フォーム

この構造により、再利用可能なコンポーネントが整理され、メインテンプレートファイルはクリーンで読みやすくなります!

実践例:投稿カードの共通化 🃏

実際に使用例を見てみましょう。まず、投稿カードのテンプレートパーツを作成します。

parts/content-card.php

<?php
/**
 * 投稿カード用のテンプレートパーツ
 */
?>
<article id="post-<?php the_ID(); ?>" <?php post_class('post-card'); ?>>
    <div class="post-thumbnail">
        <a href="<?php the_permalink(); ?>">
            <?php 
            if (has_post_thumbnail()) {
                the_post_thumbnail('medium', array('alt' => get_the_title()));
            } else {
                echo '<img src="' . get_template_directory_uri() . '/images/no-image.jpg" alt="記事のサムネイル画像">';
            }
            ?>
        </a>
        <?php 
        // カテゴリーラベルを表示
        $categories = get_the_category();
        if (!empty($categories)) {
            $category_class = 'category-' . $categories[0]->slug;
            echo '<span class="category-label ' . esc_attr($category_class) . '">' . esc_html($categories[0]->name) . '</span>';
        }
        ?>
    </div>
    <div class="post-content">
        <h3 class="post-title"><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h3>
        <div class="post-meta">
            <time datetime="<?php echo get_the_date('Y-m-d'); ?>" class="post-date">
                <i class="far fa-calendar-alt"></i> <?php the_time('Y.m.d'); ?>
            </time>
        </div>
        <div class="post-excerpt">
            <p><?php echo get_the_excerpt(); ?></p>
        </div>
        <a href="<?php the_permalink(); ?>" class="read-more">続きを読む <i class="fas fa-arrow-right"></i></a>
    </div>
</article>

そして、これを各テンプレートファイルから呼び出します。

index.php(ブログ一覧ページ)

<?php get_header(); ?>

<div class="container">
    <main class="main-content">
        <div class="post-grid">
            <?php if (have_posts()) : ?>
                <?php while (have_posts()) : the_post(); ?>
                    <?php get_template_part('parts/content', 'card'); ?>
                <?php endwhile; ?>
                
                <?php the_posts_pagination(); ?>
                
            <?php else : ?>
                <p>記事が見つかりませんでした。</p>
            <?php endif; ?>
        </div>
    </main>
    
    <?php get_sidebar(); ?>
</div>

<?php get_footer(); ?>

archive.php(アーカイブページ)

<?php get_header(); ?>

<div class="container">
    <main class="main-content">
        <header class="archive-header">
            <h1 class="archive-title"><?php the_archive_title(); ?></h1>
            <?php the_archive_description('<div class="archive-description">', '</div>'); ?>
        </header>
        
        <div class="post-grid">
            <?php if (have_posts()) : ?>
                <?php while (have_posts()) : the_post(); ?>
                    <?php get_template_part('parts/content', 'card'); ?>
                <?php endwhile; ?>
                
                <?php the_posts_pagination(); ?>
                
            <?php else : ?>
                <p>記事が見つかりませんでした。</p>
            <?php endif; ?>
        </div>
    </main>
    
    <?php get_sidebar(); ?>
</div>

<?php get_footer(); ?>

このように get_template_part() を使うと、複数のページで同じカードデザインが使えて、修正が必要な場合も parts/content-card.php を1つ直すだけで済みます!😊

応用テクニック:パラメータの引き渡し 🔄

WordPress 5.5以降では、第3引数でテンプレートパーツに変数を渡せるようになりました!これによって柔軟性が大幅に向上します。

<?php
// パラメータを配列で渡す
$args = array(
    'title' => 'おすすめ記事',
    'post_count' => 3,
    'show_date' => true
);
get_template_part('parts/related-posts', null, $args);
?>

そして、テンプレートパーツ側では $args として受け取れます:

parts/related-posts.php

<?php
/**
 * 関連記事表示用テンプレート
 * 
 * @param array $args {
 *     表示設定の配列
 *     @type string  $title      セクションのタイトル
 *     @type integer $post_count 表示する記事数
 *     @type boolean $show_date  日付を表示するかどうか
 * }
 */

// デフォルト値とマージ
$args = wp_parse_args($args, array(
    'title' => '関連記事',
    'post_count' => 4,
    'show_date' => true
));
?>

<section class="related-posts">
    <h2 class="section-title"><?php echo esc_html($args['title']); ?></h2>
    
    <?php
    // 現在の投稿と同じカテゴリーの記事を取得
    $categories = get_the_category();
    if ($categories) {
        $category_ids = array();
        foreach ($categories as $category) {
            $category_ids[] = $category->term_id;
        }
        
        $related_query = new WP_Query(array(
            'category__in' => $category_ids,
            'post__not_in' => array(get_the_ID()),
            'posts_per_page' => $args['post_count'],
            'orderby' => 'rand'
        ));
        
        if ($related_query->have_posts()) : ?>
            <div class="related-posts-grid">
                <?php while ($related_query->have_posts()) : $related_query->the_post(); ?>
                    <article class="related-post-item">
                        <a href="<?php the_permalink(); ?>" class="related-post-link">
                            <?php if (has_post_thumbnail()) : ?>
                                <?php the_post_thumbnail('thumbnail', array('class' => 'related-post-thumbnail')); ?>
                            <?php else : ?>
                                <img src="<?php echo get_template_directory_uri(); ?>/images/no-image-small.jpg" alt="サムネイル" class="related-post-thumbnail">
                            <?php endif; ?>
                            <h3 class="related-post-title"><?php the_title(); ?></h3>
                        </a>
                        <?php if ($args['show_date']) : ?>
                            <div class="related-post-date"><?php the_time('Y.m.d'); ?></div>
                        <?php endif; ?>
                    </article>
                <?php endwhile; ?>
            </div>
        <?php else : ?>
            <p>関連記事はありません。</p>
        <?php endif;
        
        wp_reset_postdata();
    }
    ?>
</section>

さらに実用的な例:条件によって表示を切り替える 🔀

テンプレートパーツの真価は、条件によって表示内容を切り替えられるところにあります。例えば投稿フォーマットに応じてデザインを変えるケースを見てみましょう。

single.php(投稿詳細ページ)

<?php get_header(); ?>

<div class="container">
    <main class="main-content">
        <?php if (have_posts()) : while (have_posts()) : the_post(); ?>
            
            <?php
            // 投稿フォーマットによってテンプレートを切り替え
            $format = get_post_format() ? get_post_format() : 'standard';
            get_template_part('parts/content-single', $format);
            ?>
            
            <?php
            // コメントテンプレート
            if (comments_open() || get_comments_number()) {
                comments_template();
            }
            ?>
            
            <?php
            // 関連記事を表示
            get_template_part('parts/related-posts', null, array(
                'title' => 'あわせて読みたい',
                'post_count' => 4
            ));
            ?>
            
        <?php endwhile; endif; ?>
    </main>
    
    <?php get_sidebar(); ?>
</div>

<?php get_footer(); ?>

このコードでは以下のようなテンプレートパーツを探します:

  • 標準投稿: parts/content-single-standard.php
  • ビデオ投稿: parts/content-single-video.php
  • ギャラリー投稿: parts/content-single-gallery.php

それぞれのフォーマットに最適化されたデザインを個別のファイルで管理できるので、メインテンプレートはスッキリしたままです!

パフォーマンス最適化テクニック ⚡

テンプレートパーツを使いこなす上で、パフォーマンス最適化も考慮しましょう。

1. テンプレートパーツのキャッシュ

繰り返し利用するテンプレートパーツは locate_template()require_once を組み合わせてキャッシュできます:

/**
 * テンプレートパーツをキャッシュする関数
 */
function cached_template_part($slug, $name = null) {
    static $cache = array();
    
    $key = $slug . '-' . $name;
    
    if (!isset($cache[$key])) {
        $cache[$key] = locate_template(array(
            "{$slug}-{$name}.php",
            "{$slug}.php"
        ));
    }
    
    if ($cache[$key]) {
        require $cache[$key];
    }
}

2. 必要なときだけロードする

条件に応じてテンプレートパーツをロードすれば、不要な処理を省けます:

<?php
// 条件に応じてテンプレートを読み込む
if (is_user_logged_in()) {
    get_template_part('parts/user-dashboard');
} else {
    get_template_part('parts/login-form');
}

// 投稿が6つ以上あるときだけページネーションを表示
if ($wp_query->max_num_pages > 1) {
    get_template_part('parts/pagination');
}
?>

クリエイティブな活用法 🎨

テンプレートパーツの活用はヘッダーやフッターだけにとどまりません。以下のような使い方も効果的です:

1. ブロックエディタのブロックパターンの実装

カスタムブロックパターンの見た目をテンプレートパーツとして実装できます:

// functions.php
function register_custom_block_patterns() {
    register_block_pattern(
        'mytheme/testimonial',
        array(
            'title'       => '推薦の声',
            'description' => '推薦文を表示するブロック',
            'content'     => get_template_part_content('parts/block-patterns/testimonial'),
        )
    );
}
add_action('init', 'register_custom_block_patterns');

// テンプレートパーツの内容を文字列として取得する関数
function get_template_part_content($template) {
    ob_start();
    get_template_part($template);
    return ob_get_clean();
}

2. カスタムショートコードの実装

ショートコードの出力をテンプレートパーツで管理すれば、デザイン変更が容易になります:

// functions.php
function cta_button_shortcode($atts) {
    $atts = shortcode_atts(array(
        'text' => '詳細はこちら',
        'url' => '#',
        'color' => 'primary'
    ), $atts);
    
    ob_start();
    set_query_var('button_atts', $atts);
    get_template_part('parts/shortcodes/button');
    return ob_get_clean();
}
add_shortcode('cta_button', 'cta_button_shortcode');

parts/shortcodes/button.php

<?php
$atts = get_query_var('button_atts');
?>
<a href="<?php echo esc_url($atts['url']); ?>" class="btn btn-<?php echo esc_attr($atts['color']); ?>">
    <?php echo esc_html($atts['text']); ?>
</a>

上級テクニック:ファイル名からの自動ロード 🚀

フォルダ内のすべてのテンプレートパーツを自動でロードする仕組みも作れます:

/**
 * 指定ディレクトリ内のすべてのパーツを自動ロードする関数
 */
function load_all_template_parts($directory, $args = array()) {
    $dir = get_template_directory() . '/' . $directory;
    if (!is_dir($dir)) {
        return;
    }
    
    $files = scandir($dir);
    foreach ($files as $file) {
        if ($file === '.' || $file === '..') continue;
        
        if (pathinfo($file, PATHINFO_EXTENSION) === 'php') {
            $slug = $directory . '/' . pathinfo($file, PATHINFO_FILENAME);
            get_template_part($slug, null, $args);
        }
    }
}

// 使用例
load_all_template_parts('parts/social-icons');

これを使えば、parts/social-icons ディレクトリ内のすべてのPHPファイルを一度に読み込めます。SNSアイコンなど複数の小さなパーツを自動表示するのに便利です!

プラグイン開発での活用法 🔌

テンプレートパーツの考え方はプラグイン開発にも適用できます。プラグインでは plugin_dir_path() と組み合わせて使いましょう:

/**
 * プラグイン用のテンプレートパーツを読み込む関数
 */
function my_plugin_get_template_part($slug, $name = null, $args = array()) {
    $template = '';
    $name = (string) $name;
    
    // テーマまたは子テーマ内にテンプレートがあるか確認
    if ($name) {
        $template = locate_template(array(
            "my-plugin/{$slug}-{$name}.php",
            "my-plugin/{$slug}.php"
        ));
    } else {
        $template = locate_template(array(
            "my-plugin/{$slug}.php"
        ));
    }
    
    // テーマにテンプレートがなければプラグインのデフォルトを使用
    if (!$template) {
        if ($name && file_exists(plugin_dir_path(__FILE__) . "templates/{$slug}-{$name}.php")) {
            $template = plugin_dir_path(__FILE__) . "templates/{$slug}-{$name}.php";
        } elseif (file_exists(plugin_dir_path(__FILE__) . "templates/{$slug}.php")) {
            $template = plugin_dir_path(__FILE__) . "templates/{$slug}.php";
        }
    }
    
    // テンプレートが見つかった場合は読み込む
    if ($template) {
        if (!empty($args) && is_array($args)) {
            extract($args);
        }
        include $template;
    }
}

まとめ:テンプレートパーツを最大限活用しよう!📝

get_template_part() の活用で得られるメリットをまとめます:

  • コードの再利用性向上: 同じコードを複数の場所で使い回せる
  • メンテナンス性の向上: 変更が必要な場合、1箇所だけ修正すればOK
  • コードの整理: メインテンプレートファイルをスッキリと保つことができる
  • 柔軟な条件分岐: 状況に応じて最適なテンプレートを選択できる
  • チーム開発の効率化: 担当範囲を明確に分けて並行開発が可能

WordPressの開発効率を上げたいなら、テンプレートパーツの活用は必須スキルです。この記事で紹介したテクニックを実践して、メンテナンスしやすい美しいコードを書いていきましょう!

質問やさらなるテクニックの共有は、ぜひコメント欄でお願いします!ハッピーコーディング!😊

追加リソース 📚

✉️ あなたのリクエスト教えてください!

「この記事わかりやすかった!」
「他にもこんな記事書いてほしい!」
そんな声を、ぜひXのDMで教えてください!😊📩

できるだけリクエストにお応えして、今後の記事作成に活かしていきます

▶️ X@TumaLOVE0127もフォローしてもらえるとめちゃくちゃ嬉しいです!

hisa

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA