WordPressでサイトを制作していると、ページごとに異なるCSSを適用したいケースがよくあります。そんな時に便利なのが、<body>タグにIDやクラスを追加する方法です。

ネットで「WordPress body id スラッグ」と検索すると、多くのサイトで以下のようなコードが紹介されています:

<body id='<?php echo esc_attr($post->post_name); ?>'>

実はこのコード、404ページやアーカイブページではエラーが発生します
今回はなぜエラーが起きるのか、そしてどうすれば正しく実装できるのかを、初心者の方にもわかりやすく解説します。

    なぜエラーが発生するのか?

    よくある間違ったコード

    <body id='<?php echo esc_attr($post->post_name); ?>' <?php body_class(); ?>>
    

    このコードを使うと、以下のようなエラーログが記録されることがあります:

    PHP Warning: Attempt to read property "post_name" on null in /path/to/header.php on line XXX
    

    エラーの原因

    このエラーは、$postオブジェクトがnull(存在しない)場合に発生します。WordPressでは、すべてのページで$postが存在するわけではありません。

    $postが存在しないページの例:

    • 404エラーページ
    • カテゴリーアーカイブページ
    • タグアーカイブページ
    • 検索結果ページ
    • 投稿一覧ページ(ブログトップ)

    これらのページでは$postが定義されていないため、$post->post_nameにアクセスしようとするとエラーになるのです。

    body_class()関数について

    まず、WordPressに標準で用意されているbody_class()関数について理解しましょう。

    body_class()の基本

    body_class()は、現在表示しているページの種類に応じて、自動的に適切なクラスを<body>タグに追加してくれる便利な関数です。

    <body <?php body_class(); ?>>
    

    このコードは、例えば固定ページなら以下のようなHTMLを出力します:

    <body class="page page-id-2 page-template-default">
    

    body_class()に任意のクラスを追加する

    body_class()関数には、独自のクラスを追加することもできます:

    <?php
    $my_class = 'my-custom-class another-class';
    ?>
    <body <?php body_class($my_class); ?>>
    

    出力結果:

    <body class="page page-id-2 page-template-default my-custom-class another-class">
    

    正しい実装方法

    それでは、エラーを回避しながら、bodyタグにIDとクラスを適切に追加する方法を見ていきましょう。

    基本的な実装

    <?php
    //初期値の設定
    $body_id = '';
    $body_addclass = '';
    
    //ページタイプごとにIDを設定
    if (is_singular()) {
        //投稿・固定ページの場合
        global $post;
        if ($post && isset($post->post_name)) {
            $body_id = esc_attr($post->post_name);
        }
    } elseif (is_404()) {
        //404ページの場合
        $body_id = 'error-404';
    } elseif (is_search()) {
        //検索結果ページの場合
        $body_id = 'search-results';
    }
    
    //任意のクラスを追加(例:テーマ名)
    $body_addclass = 'my-theme-name';
    ?>
    <body id='<?php echo $body_id; ?>' <?php body_class($body_addclass); ?>>
    

    より詳細な実装例

    すべてのページタイプに対応した、より完全な実装例です:

    <?php
    /* ===================================
     * body要素の設定
     * =================================== */
    
    //初期値の設定
    $body_id = '';
    $body_addclass = '';
    
    //ページタイプごとにIDを設定
    if (is_singular()) {
        //投稿・固定ページ
        global $post;
        if ($post && isset($post->post_name)) {
            $body_id = esc_attr($post->post_name);
        }
    } elseif (is_category() || is_tag() || is_tax()) {
        //カテゴリー・タグ・カスタムタクソノミー
        $term = get_queried_object();
        if ($term && isset($term->slug)) {
            $body_id = 'archive-' . esc_attr($term->slug);
        }
    } elseif (is_post_type_archive()) {
        //カスタム投稿タイプアーカイブ
        $body_id = 'archive-' . esc_attr(get_post_type());
    } elseif (is_home()) {
        //ブログ投稿一覧ページ
        $body_id = 'home';
    } elseif (is_front_page()) {
        //フロントページ
        $body_id = 'front';
    } elseif (is_404()) {
        //404エラーページ
        $body_id = 'error-404';
    } elseif (is_search()) {
        //検索結果ページ
        $body_id = 'search-results';
    } else {
        //その他のページ
        $body_id = 'default';
    }
    
    //テーマ名などの固定クラスを追加
    $theme_name = 'my-theme';
    $body_addclass = $theme_name;
    
    //特定の条件で追加クラスを設定(例:モバイル判定など)
    if (wp_is_mobile()) {
        $body_addclass .= ' is-mobile';
    }
    
    //余分な空白を削除
    $body_addclass = trim($body_addclass);
    ?>
    <body id='<?php echo $body_id; ?>' <?php body_class($body_addclass); ?>>
    

    カスタムタクソノミーのタームをクラスに追加する

    カスタムタクソノミー(例:pgというタクソノミー)のタームをbodyクラスに追加したい場合:

    <?php
    //カスタムタクソノミー'pg'のタームをクラスに追加
    $term_slug_pg = '';
    
    if (is_singular()) {
        global $post;
        if (isset($post) && $post) {
            //'pg'タクソノミーのタームを取得
            $terms_pg = get_the_terms($post->ID, 'pg');
            
            //エラーチェックを含めて処理
            if ($terms_pg && !is_wp_error($terms_pg)) {
                foreach ($terms_pg as $term_pg) {
                    $term_slug_pg = $term_pg->slug;
                    break; //最初の1つだけ取得
                }
            }
        }
    }
    
    //bodyクラスに追加
    $body_addclass = trim($body_addclass . ' ' . $term_slug_pg);
    ?>
    

    functions.phpで関数化する方法

    コードを整理したい場合は、functions.phpに関数を作成することもできます:

    //functions.php に追加
    function get_custom_body_id() {
        if (is_singular()) {
            global $post;
            if ($post && isset($post->post_name)) {
                return esc_attr($post->post_name);
            }
        } elseif (is_category() || is_tag() || is_tax()) {
            $term = get_queried_object();
            if ($term && isset($term->slug)) {
                return 'archive-' . esc_attr($term->slug);
            }
        } elseif (is_404()) {
            return 'error-404';
        } elseif (is_search()) {
            return 'search-results';
        }
        
        return '';
    }
    
    //header.php での使用
    <body id='<?php echo get_custom_body_id(); ?>' <?php body_class('my-theme'); ?>>
    

    CSSでの活用例

    設定したIDやクラスを使って、ページごとに異なるスタイルを適用できます:

    /* 特定の固定ページのみのスタイル */
    #about .header {
        background-color: #f0f0f0;
    }
    
    /* カテゴリーアーカイブページのスタイル */
    #archive-news article {
        border-left: 3px solid #0073aa;
    }
    
    /* 404ページのスタイル */
    #error-404 .content {
        text-align: center;
        padding: 100px 20px;
    }
    
    /* body_classで自動付与されるクラスを使用 */
    .home .header {
        height: 500px; /* トップページのみヘッダーを大きく */
    }
    
    .single-post .sidebar {
        display: none; /* 投稿ページではサイドバーを非表示 */
    }
    

    まとめ

    WordPressで<body>タグにIDやクラスを追加する際は、以下のポイントを押さえましょう:

    1. $postオブジェクトの存在を必ず確認する

      • if ($post && isset($post->post_name))のようにチェック
    2. ページタイプごとに適切な処理を行う

      • is_singular()is_404()などの条件分岐関数を活用
    3. body_class()関数を活用する

      • WordPressが自動で付与するクラスも有効活用
    4. エスケープ処理を忘れない

      • esc_attr()で属性値をエスケープ
    5. エラーハンドリングを実装する

      • is_wp_error()でエラーチェック

    参考:WordPressの条件分岐タグ

    • is_singular() - 投稿、固定ページ、カスタム投稿タイプの個別ページ
    • is_single() - 投稿の個別ページ
    • is_page() - 固定ページ
    • is_category() - カテゴリーアーカイブ
    • is_tag() - タグアーカイブ
    • is_tax() - カスタムタクソノミーアーカイブ
    • is_archive() - アーカイブページ全般
    • is_home() - ブログ投稿一覧
    • is_front_page() - フロントページ
    • is_404() - 404エラーページ
    • is_search() - 検索結果ページ

    これらの実装により、エラーを回避しながら、柔軟なページごとのデザイン制御が可能になります。

    WordPress $post変数のnullエラーを完全解決!error_logを綺麗にする実践的修正ガイド error_logに頻出する「Attempt to read property on null」エラー。WordPress の$post変数が原因です。本記事では5つの典型パターンと修正方法、グローバル変数での一元管理まで実践的に解説。$post->IDや$p...  続きを読む