WordPressの投稿一覧やアーカイブページで、タイトルや本文の表示文字数を制限したい場面があります。この記事では、個別記事ページ自体を壊さずに、一覧・アーカイブでだけ文字数を制限する正しい方法を解説します。
この記事でわかること
is_singular()による除外がなぜ必須か- 一覧・アーカイブでのみタイトル・本文を文字数制限する正しい実装
- 抜粋(excerpt)の文字数制限と日本語ロケールでの注意点
なぜthe_title/the_contentへの無条件フィルターは危険か
個別記事ページ自体まで切り詰められてしまう
add_filter('the_content', 'limit_content_length') のように、条件を付けずに the_content フィルターへ文字数制限を登録すると、これは一覧・アーカイブだけでなく、記事自身の単一ページにも適用されます。その結果、サイト上のすべての記事本文が問答無用で指定文字数に切り詰められ、読者は記事の続きを二度と読めなくなります。the_title フィルターも同様で、個別記事ページの見出しやタイトルタグまで切り詰められてしまいます。一覧・アーカイブでだけ文字数を制限したい場合は、必ず is_singular() で個別ページを除外してください。一覧・アーカイブでのみタイトルを文字数制限する
functions.php:is_singular()で個別ページを除外
function limit_title_length( $title ) {
if ( is_singular() ) {
return $title; // 記事自身のページでは切り詰めない
}
$max_length = 50;
if ( mb_strlen( $title ) > $max_length ) {
$title = mb_substr( $title, 0, $max_length ) . '…';
}
return $title;
}
add_filter( 'the_title', 'limit_title_length' );
一覧・アーカイブでのみ本文を文字数制限する
一覧・アーカイブで本文の冒頭だけを見せたい場合、本来はthe_excerpt()(抜粋)を使う方が適切です。それでも the_content を使う必要がある場合は、同様に is_singular() で個別ページを除外します。
functions.php:is_singular()で個別ページを除外(本文)
function limit_content_length( $content ) {
if ( is_singular() ) {
return $content; // 記事自身のページでは切り詰めない
}
$max_length = 100;
$plain = wp_strip_all_tags( $content );
if ( mb_strlen( $plain ) > $max_length ) {
return mb_substr( $plain, 0, $max_length ) . '…';
}
return $content;
}
add_filter( 'the_content', 'limit_content_length' );
本文にはHTMLタグが含まれる
the_content はHTMLタグを含んだ状態で渡されるため、そのままmb_substr()で切るとタグの途中で切れて表示が崩れることがあります。wp_strip_all_tags()でタグを除去してから文字数を数えるようにしています。テンプレート側で個別に呼び出す方法(最も安全)
グローバルフィルターは意図しない箇所にまで影響する可能性があるため、アーカイブテンプレート(archive.phpなど)のループ内で直接呼び出す方が安全です。この場合、is_singular()のガードを忘れる心配自体がありません。
archive.php:ループ内で直接文字数制限する
<?php
$archive_title = get_the_title();
$short_title = mb_strlen( $archive_title ) > 30
? mb_substr( $archive_title, 0, 30 ) . '…'
: $archive_title;
?>
<h2><?php echo esc_html( $short_title ); ?></h2>
抜粋(excerpt)の文字数制限
抜粋の文字数は、検索結果やアーカイブページでの表示に影響します。excerpt_lengthフィルターで文字数を、excerpt_moreフィルターで末尾の文字列を変更できます。こちらは元々自動生成の抜粋にのみ作用する仕組みのため、個別ページの本文を破壊する心配はありません。
functions.php:抜粋の文字数と末尾の文字列
function custom_excerpt_length( $length ) {
return 20;
}
add_filter( 'excerpt_length', 'custom_excerpt_length' );
function custom_excerpt_more( $more ) {
return '…';
}
add_filter( 'excerpt_more', 'custom_excerpt_more' );
日本語ロケールでは「20」は単語数でなく文字数
excerpt_lengthが返す数値は、内部でwp_trim_words()に渡されます。この関数はロケールによって数え方が変わり、日本語ロケールでは単語区切りが無いため文字数として扱われます(英語ロケールでは単語数)。そのため、このサイトのような日本語サイトでは20を設定すると「20文字」で切り詰められます。テーマやプラグインでの設定
一部のテーマやプラグインでは、設定画面からタイトル・本文・抜粋の文字数制限を行うことができます。テーマのカスタマイザーやプラグインの設定ページも確認してみましょう。
よくある質問(FAQ)
QWordPressのループで記事タイトルを指定文字数で切り詰めるには?
A
mb_substr(get_the_title(), 0, 30) . '…'のように、テンプレートのループ内で直接使うのが最も安全です。グローバルフィルターでthe_titleを書き換える場合は、is_singular()で個別ページを必ず除外してください。Q記事の抜粋(excerpt)を任意の文字数に制限するには?
Aexcerpt_lengthフィルターで文字数、excerpt_moreフィルターで末尾の文字列を変更できます。日本語ロケールでは文字数として扱われるため、英語圏向けの解説(単語数)とは挙動が異なる点に注意してください。
Q記事内の画像を最初の1枚だけ表示するには?
Aget_the_content()で本文取得後、preg_match(‘/
]+>/’, $content, $matches)で最初のimgタグを抽出します。has_post_thumbnail()でアイキャッチを優先し、なければ本文から抽出するという処理が一般的です。
まとめ
- 必須:
the_title/the_contentフィルターはis_singular()で個別ページを除外する - より安全:グローバルフィルターでなくテンプレートのループ内で直接切り詰める
- 抜粋:excerpt_length/excerpt_moreは日本語ロケールで文字数として扱われる
「一覧だけ短く見せたい」つもりが「記事自体が読めなくなる」事故につながらないよう、適用範囲を必ず確認してから実装してください。

