2026年6月29日

2026年6月29日

WordPressの抜粋(excerpt)が正しく表示されない問題を解決する方法

はじめに

WordPressの記事一覧ページで抜粋が表示されず本文全体が表示されてしまう・投稿編集画面で手動入力した抜粋が無視されて自動生成の抜粋が使われる・excerpt_lengthフィルターで文字数を変更したのに反映されない・抜粋にHTMLタグ(

等)がそのまま含まれてしまう・日本語テキストで抜粋が単語の途中で切れてしまうといった問題は、the_excerpt()get_the_excerpt()の使い分け・フィルターの適用順序・テーマのテンプレートの実装が原因です。

症状・原因

  • テーマのテンプレートでthe_content()を使っているため抜粋でなく全文が表示されている
  • excerpt_lengthフィルターで単語数を変更しても日本語には効かない(英語の単語数基準のため)
  • 手動入力の抜粋があるのにwp_trim_excerpt()が自動抜粋を生成して上書きしている
  • get_the_excerpt()the_loop外で呼んでいるためグローバルな$postが設定されていない

解決手順

ステップ1:抜粋の状態を診断する

# 投稿の抜粋データを確認
wp post get 1 --field=post_excerpt
wp eval "
\$post = get_post(1);
echo 'Manual excerpt: '    . (\$post->post_excerpt ? substr(\$post->post_excerpt, 0, 50) : '(empty)') . PHP_EOL;
echo 'Auto excerpt: '      . substr(get_the_excerpt(1), 0, 80) . PHP_EOL;
echo 'excerpt_length: '    . apply_filters('excerpt_length', 55) . PHP_EOL;
echo 'excerpt_more: '      . apply_filters('excerpt_more', '[...]') . PHP_EOL;
"

# 抜粋をサポートしている投稿タイプを確認
wp eval "
foreach (get_post_types(['public' => true], 'objects') as \$pt) {
    echo \$pt->name . ': supports excerpt=' . (post_type_supports(\$pt->name, 'excerpt') ? 'yes' : 'no') . PHP_EOL;
}
"

ステップ2:抜粋の文字数と省略記号を設定する

// 日本語対応の抜粋文字数設定(単語数ではなく文字数で制御)
add_filter('excerpt_length', fn(): int => 55);  // 英語の単語数

// 日本語での抜粋は wp_trim_excerpt をフィルターして文字数制御
add_filter('wp_trim_excerpt', function(string $text, string $raw_excerpt): string {
    if ($raw_excerpt) return $text;  // 手動抜粋があればそのまま返す

    // 本文からHTMLタグを除去して日本語文字数でトリム
    $content = get_the_content();
    $content = strip_shortcodes($content);
    $content = wp_strip_all_tags($content);
    $content = str_replace(["\r\n", "\r", "\n", "\t"], ' ', $content);
    $length  = 120;  // 日本語120文字

    if (mb_strlen($content) > $length) {
        $content = mb_substr($content, 0, $length) . apply_filters('excerpt_more', '…');
    }
    return $content;
}, 10, 2);

// 省略記号をカスタマイズ
add_filter('excerpt_more', fn(): string => '…<a href="' . esc_url(get_permalink()) . '">続きを読む</a>');

ステップ3:テンプレートで抜粋を正しく表示する

// ループ内での正しい抜粋表示
// ✅ 抜粋を表示(手動入力 → 自動生成の順で使用)
the_excerpt();

// ✅ 抜粋を変数として取得
$excerpt = get_the_excerpt();

// ✅ ループ外で特定の投稿の抜粋を取得
$post_id = 42;
$excerpt = get_the_excerpt($post_id);  // WordPress 4.5+

// ✅ 手動抜粋のみ使用(自動生成を使わない)
$post    = get_post($post_id);
$excerpt = $post->post_excerpt ?: '';

// ✗ 避けるべき:ループ外で引数なしは $post グローバルに依存
// $excerpt = get_the_excerpt();  // ループ外では正しい投稿を指さない

ステップ4:カスタム投稿タイプに抜粋サポートを追加する

// register_post_type() で excerpt サポートを追加
register_post_type('news', [
    'label'    => 'ニュース',
    'public'   => true,
    'supports' => ['title', 'editor', 'excerpt', 'thumbnail'],  // excerpt を追加
]);

// 既存の投稿タイプに後から抜粋サポートを追加
add_action('init', function(): void {
    add_post_type_support('page', 'excerpt');  // 固定ページにも抜粋欄を追加
});

ステップ5:抜粋のHTMLとショートコードを処理する

// 抜粋にHTMLを許可する(特定タグのみ)
add_filter('the_excerpt', function(string $excerpt): string {
    // p タグと strong タグのみ許可
    return wp_kses($excerpt, [
        'p'      => [],
        'strong' => [],
        'em'     => [],
        'a'      => ['href' => [], 'title' => []],
    ]);
});

// 抜粋内のショートコードを処理する
add_filter('the_excerpt', 'do_shortcode');

// 抜粋の自動段落変換を有効化
add_filter('the_excerpt', 'wpautop');
# 全投稿の抜粋を一括で自動生成して保存
wp eval "
\$posts = get_posts(['numberposts' => -1, 'post_status' => 'publish']);
foreach (\$posts as \$post) {
    if (! \$post->post_excerpt) {
        \$excerpt = wp_trim_words(\$post->post_content, 55, '...');
        wp_update_post(['ID' => \$post->ID, 'post_excerpt' => \$excerpt]);
    }
}
echo 'Done.' . PHP_EOL;
"

注意事項

  • excerpt_lengthフィルターは英語の単語数を制御するもので、日本語には直接効きません。日本語サイトではwp_trim_excerptフィルターをカスタマイズしてmb_substr()で文字数制御してください
  • the_excerpt()は自動的にwpautop()を適用してHTMLに変換します。get_the_excerpt()はプレーンテキストを返します
  • Moreタグ()を記事に挿入すると、the_excerpt()Moreタグまでの内容を抜粋として使用します

まとめ

WordPress抜粋不動作の解決は①wp post get --field=post_excerptで手動抜粋データを確認・apply_filters('excerpt_length', 55)で現在の設定を確認・post_type_supports()で抜粋サポートを確認、②wp_trim_excerptフィルターでmb_substr()による日本語120文字制御・手動抜粋がある場合はそのまま返す・excerpt_moreフィルターで「続きを読む」リンクを追加、③the_excerpt()でループ内表示・ループ外ではget_the_excerpt($post_id)で投稿IDを指定・$post->post_excerptで手動抜粋のみ取得、④register_post_type()supports配列にexcerptを追加・add_post_type_support('page', 'excerpt')で固定ページにも追加、⑤the_excerptフィルターでwp_kses()でHTML制御・do_shortcodeでショートコードを処理・wp_update_post()で全投稿に一括で抜粋を保存の手順で解決します。

お気軽にご相談ください