WordPressで特定の投稿だけをトップページ・一覧ページから隠したいことがあります。投稿に「一覧に表示しない」チェックボックスを用意し、pre_get_posts + meta_query でクエリ段階から除外すれば、ページネーションを崩さずに非表示にできます。カスタムフィールドは Custom Field Suite・ACF・標準機能のいずれでも実装できます。
- 「一覧に表示しない」チェック用のカスタムフィールドを用意する
pre_get_posts+meta_queryでクエリ段階から除外する(推奨)- ループ内で隠すとページネーションが崩れる理由
- CFS・ACF・標準カスタムフィールドのいずれでも使える実装
「表示しない」チェック用のカスタムフィールドを用意する
投稿に真偽(チェックボックス)のカスタムフィールドを追加します。キー名は英数字(例:hide_from_home)にしておくと、コードで扱いやすく安全です。ここでは Custom Field Suite(CFS)での作成例を示します。
Custom Field Suite は手軽ですが更新が停滞しています。新規なら定番の ACF(Advanced Custom Fields) や、プラグイン無しの標準カスタムフィールドでも同じことができます。キー(
hide_from_home)を合わせれば、後述のコードはそのまま使えます。
管理画面の「Custom Field Suite」→「新規追加」で、フィールド名(ラベル)と名前(キー)を hide_from_home、タイプを「真/偽(簡易チェックボックス)」にして保存します。
投稿で「表示しない」をオンにする
作成したフィールドは投稿の編集画面に表示されます。一覧から隠したい投稿でチェックをオンにして更新します。

クエリ段階で除外する(pre_get_posts・推奨)
functions.php に次のコードを追加し、チェックがオンの投稿をクエリ自体から除外します。NOT EXISTS の条件で、フィールド未設定の投稿(=従来の投稿)も表示されるようにします。
function exclude_hidden_from_home($query) {
if (is_admin() || !$query->is_main_query()) {
return;
}
// トップページ・一覧で除外(必要に応じて条件を調整)
if ($query->is_home() || $query->is_archive()) {
$query->set('meta_query', array(
'relation' => 'OR',
array(
'key' => 'hide_from_home',
'value' => '1',
'compare' => '!=', // 1(チェックオン)以外
),
array(
'key' => 'hide_from_home',
'compare' => 'NOT EXISTS', // フィールド未設定の投稿も表示
),
));
}
}
add_action('pre_get_posts', 'exclude_hidden_from_home');
NOT EXISTS を入れないと従来の投稿が消えるmeta_query で key を条件にすると、そのフィールドを持たない投稿は除外されてしまいます。チェックを付けていない既存投稿を表示し続けるには、NOT EXISTS の条件を OR で必ず加えてください。カテゴリでの除外は記事一覧から特定のカテゴリーを除外する方法、カスタムフィールドが空の投稿を隠す例は特定のカスタムフィールドが空の投稿を一覧に非表示にする方法も参考になります。(非推奨)ループ内で隠すとページネーションが崩れる
下のようにループの中で表示/非表示を分岐する書き方も見かけますが、注意が必要です。
<?php while (have_posts()) : the_post(); ?>
<?php if (get_post_meta(get_the_ID(), 'hide_from_home', true) !== '1') : ?>
<h2><?php the_title(); ?></h2>
<div><?php the_content(); ?></div>
<?php endif; ?>
<?php endwhile; ?>
この方法は隠す投稿もクエリで取得済みで、
posts_per_page の件数にカウントされます。「10件表示」でも非表示が3件あれば実際の表示は7件になり、ページごとの件数がバラバラ・ページ番号がずれる不具合が起きます。一覧から確実に除外したいなら、前章の pre_get_posts 方式を使ってください。応用:逆に「特定の投稿だけ」表示する/期間で出し分ける
compare を '=' にすれば、逆にチェックした投稿だけを表示できます。日付で自動的に表示・非表示を切り替えたい場合は指定期間だけ記事を表示・非表示にする方法、AND/OR/NOTを組み合わせた複雑な条件はWP_Queryで複雑な条件検索を実装する方法を参照してください。
よくある質問(FAQ)
pre_get_posts + meta_query ならクエリ段階で除外するので、件数もページ送りも正しく保たれます。基本はこちらを使ってください。meta_query で key 条件だけだと、フィールドを持たない投稿が除外されます。NOT EXISTS の条件を OR で加えると、未設定の投稿も表示され続けます。まとめ
- 準備:真偽のカスタムフィールド(キー
hide_from_home)を用意(CFS/ACF/標準いずれでも可) - 除外:
pre_get_posts+meta_query(!= 1+NOT EXISTS) - ループ内で隠さない:件数・ページネーションが崩れるため
- 応用:
=で「特定投稿だけ表示」、日付条件で期間出し分け
クエリ段階で除外すれば、見た目もページ送りも自然なまま、投稿の表示・非表示をチェックひとつで管理できます。

