HOME / BLOG
BLOG

WordPressオリジナルテーマ開発で最初に作るべき便利関数10選

デフォルト画像

WordPressオリジナルテーマを作り始めると、画像URLの取得、SVGの読み込み、パンくず、OGP、投稿カードなど、毎回似た処理を書くことになります。最初に便利関数を用意しておくと、テンプレートが読みやすくなり、あとから修正もしやすくなります。

この記事では、functions.phpへ入れて使える便利関数を10個紹介します。PHP8系を前提に、WordPress標準関数を活用しながら、再利用しやすい形にしています。

SEOタイトル

WordPressオリジナルテーマ開発で最初に作るべき便利関数10選

meta description

WordPressオリジナルテーマ開発で最初に用意したい便利関数を10個紹介。SVG読み込み、asset関数、OGP、パンくず、投稿カードなどをPHP8対応コード付きで解説します。

便利関数のサンプルコード

まずはまとめてコードを掲載します。実際のテーマではfunctions.phpに直接書いても動きますが、量が増える場合はinc/helpers.phpのようなファイルに分けるのがおすすめです。

<?php
declare(strict_types=1);

/**
 * テーマ内の画像・CSS・JSなどのURLを返す。
 */
function nines_asset(string $path): string
{
    return esc_url(get_template_directory_uri() . '/' . ltrim($path, '/'));
}

/**
 * テーマ内ファイルの更新日時をバージョンとして返す。
 */
function nines_asset_version(string $path): string
{
    $file = get_template_directory() . '/' . ltrim($path, '/');

    return file_exists($file) ? (string) filemtime($file) : wp_get_theme()->get('Version');
}

/**
 * SVGを安全な場所から読み込む。
 */
function nines_inline_svg(string $path, string $class = ''): string
{
    $file = get_template_directory() . '/' . ltrim($path, '/');

    if (!is_readable($file) || pathinfo($file, PATHINFO_EXTENSION) !== 'svg') {
        return '';
    }

    $svg = file_get_contents($file);
    if ($svg === false) {
        return '';
    }

    if ($class !== '') {
        $svg = preg_replace('/<svg\b(?![^>]*class=)/', '<svg class="' . esc_attr($class) . '"', $svg, 1);
    }

    return $svg;
}

/**
 * アイキャッチがなければデフォルト画像を返す。
 */
function nines_featured_image_url(?int $post_id = null, string $size = 'large'): string
{
    $post_id = $post_id ?: get_the_ID();
    $url = get_the_post_thumbnail_url($post_id, $size);

    return esc_url($url ?: get_template_directory_uri() . '/images/any_eyecatch.png');
}

/**
 * ページ種別に応じたbody classを追加する。
 */
add_filter('body_class', function (array $classes): array {
    if (is_singular('post')) {
        $classes[] = 'is-blog-detail';
    }

    if (is_page()) {
        $classes[] = 'is-page-' . sanitize_html_class((string) get_post_field('post_name'));
    }

    return array_values(array_unique($classes));
});

/**
 * OGPに使う説明文を返す。
 */
function nines_meta_description(?int $post_id = null, int $length = 120): string
{
    $post_id = $post_id ?: get_the_ID();
    $description = has_excerpt($post_id)
        ? get_the_excerpt($post_id)
        : wp_strip_all_tags(get_post_field('post_content', $post_id));

    return esc_attr(wp_html_excerpt(trim($description), $length, '...'));
}

/**
 * パンくず用の配列を返す。
 */
function nines_breadcrumb_items(): array
{
    $items = [
        ['label' => 'HOME', 'url' => home_url('/')],
    ];

    if (is_singular('post')) {
        $items[] = ['label' => 'BLOG', 'url' => home_url('/blog/')];
        $items[] = ['label' => get_the_title(), 'url' => get_permalink()];
    } elseif (is_page()) {
        $items[] = ['label' => get_the_title(), 'url' => get_permalink()];
    }

    return $items;
}

/**
 * titleタグや見出しで使うページタイトルを返す。
 */
function nines_page_title(): string
{
    if (is_home() || is_front_page()) {
        return get_bloginfo('name');
    }

    if (is_archive()) {
        return get_the_archive_title();
    }

    if (is_search()) {
        return '検索結果: ' . get_search_query();
    }

    return get_the_title() ?: get_bloginfo('name');
}

/**
 * メニューを配列で取得する。
 */
function nines_menu_items(string $location): array
{
    $locations = get_nav_menu_locations();
    if (!isset($locations[$location])) {
        return [];
    }

    $items = wp_get_nav_menu_items($locations[$location]);

    return is_array($items) ? $items : [];
}

/**
 * 投稿カード表示に必要な情報をまとめて返す。
 */
function nines_post_card_data(?WP_Post $post = null): array
{
    $post = $post ?: get_post();
    if (!$post instanceof WP_Post) {
        return [];
    }

    return [
        'id' => $post->ID,
        'title' => get_the_title($post),
        'url' => get_permalink($post),
        'date' => get_the_date('Y.m.d', $post),
        'image' => nines_featured_image_url($post->ID, 'medium_large'),
        'excerpt' => get_the_excerpt($post),
    ];
}

便利関数1: nines_asset

テーマ内の画像、CSS、JavaScriptのURLを返す関数です。テンプレート内でget_template_directory_uri()を何度も書かずに済みます。

<?php echo nines_asset('images/logo.svg'); ?>

便利関数2: nines_asset_version

CSSやJavaScriptの更新日時をバージョンに使う関数です。ファイルを更新したのに古いCSSが残るキャッシュ問題を減らせます。

wp_enqueue_style('theme-style', nines_asset('style.css'), [], nines_asset_version('style.css'));

便利関数3: nines_inline_svg

SVGをインラインで読み込む関数です。アイコンの色をCSSで変えたい場合や、ロゴをcurrentColorで扱いたい場合に便利です。外部入力のパスをそのまま渡さず、テーマ内の固定ファイルに使うのが安全です。

<?php echo nines_inline_svg('images/svg2/nines_logo.svg', 'site-logo'); ?>

便利関数4: nines_featured_image_url

アイキャッチがある場合はそのURLを返し、ない場合はデフォルト画像を返します。記事カードの画像抜けを防げます。

<img src="<?php echo nines_featured_image_url(); ?>" alt="<?php the_title_attribute(); ?>">

便利関数5: body_classの追加

ページ種別に応じたclassをbodyへ追加します。CSSでページごとの調整をするとき、テンプレート側に余計な分岐を書かずに済みます。

便利関数6: nines_meta_description

OGPやmeta descriptionで使う説明文を返します。抜粋があれば抜粋を使い、なければ本文から短く切り出します。

<meta name="description" content="<?php echo nines_meta_description(); ?>">

便利関数7: nines_breadcrumb_items

パンくずに必要なラベルとURLを配列で返します。HTMLの出し方はテンプレート側で自由に変えられるので、デザイン変更にも対応しやすいです。

便利関数8: nines_page_title

トップ、アーカイブ、検索、固定ページ、投稿ページで表示するタイトルをまとめます。見出しやtitleタグの出し分けに使えます。

<h1><?php echo esc_html(nines_page_title()); ?></h1>

便利関数9: nines_menu_items

登録済みメニューを配列で取得します。メニューのHTMLを細かく制御したい場合に使いやすい関数です。

便利関数10: nines_post_card_data

投稿カードで使うタイトル、URL、日付、画像、抜粋をまとめて返します。ループ内のテンプレートがかなり読みやすくなります。

<?php foreach ($query->posts as $post) : ?>
  <?php $card = nines_post_card_data($post); ?>
  <a href="<?php echo esc_url($card['url']); ?>">
    <img src="<?php echo esc_url($card['image']); ?>" alt="">
    <span><?php echo esc_html($card['date']); ?></span>
    <strong><?php echo esc_html($card['title']); ?></strong>
  </a>
<?php endforeach; ?>

おすすめディレクトリ構成

theme-root/
├── functions.php
├── inc/
│   ├── helpers.php
│   ├── setup.php
│   └── enqueue.php
├── template-parts/
│   ├── card-post.php
│   └── breadcrumb.php
├── css/
├── js/
└── images/

命名規則

  • テーマ固有の関数には接頭辞を付ける。例: nines_asset()
  • HTMLを返す関数とデータを返す関数を混ぜすぎない
  • esc_url、esc_html、esc_attrなど、出力場所に合わせてエスケープする
  • 関数が増えたらfunctions.phpからinc/helpers.phpへ分ける
  • WordPress標準関数でできることは、独自実装しすぎない

FAQ

functions.phpに全部書いてもいいですか?

小さなテーマなら問題ありません。ただ、関数が増えてきたらinc/helpers.php、inc/enqueue.phpのように分ける方が管理しやすいです。

SVG読み込み関数は安全ですか?

テーマ内に置いた信頼できるSVGだけを読み込む前提なら扱いやすいです。管理画面からアップロードされたSVGや外部URLをそのまま読み込む使い方は避けてください。

便利関数を作りすぎるデメリットはありますか?

あります。WordPress標準関数を薄く包むだけの関数が増えすぎると、逆に読みづらくなります。テンプレートの重複を減らせるもの、変更に強くなるものだけを残すのがおすすめです。

内部リンク案

まとめ

WordPressオリジナルテーマでは、最初に便利関数を整えておくと、テンプレートの見通しがかなり良くなります。特にasset、SVG、アイキャッチ、OGP、パンくず、投稿カードは使う頻度が高いので、早めに用意しておく価値があります。