WordPressでトップページだけ見せたいとき functions.phpでリダイレクトした記録

はじめに

WordPress サイトで「もうトップページのお知らせだけ見せたい」という場面はないでしょうか。

たとえば、あるサービスサイトを終了したあとに、トップページだけは残しておきたいけれど、昔の下層ページが検索結果などから開けてしまう状態は避けたい、というケースです。

今回は、そうした状況でトップページ以外に来た人をすべてトップページへ戻したいという要件を実現しようとして、.htaccessfunctions.php を試した記録をまとめます。

今回やりたかったこと

今回の要件をシンプルに言うと、次のような動きです。

  • https://example-driving-school.test/ はそのまま表示する
  • それ以外の下層ページはすべてトップページへ戻す

たとえば、次のような URL があったとします。

  • https://example-driving-school.test/
  • https://example-driving-school.test/about
  • https://example-driving-school.test/course
  • https://example-driving-school.test/news/test

この場合にやりたかったのは、トップページだけを見せて、それ以外はすべてトップへ戻すことでした。

イメージとしては、玄関だけ開けておいて、他の部屋に入ろうとしたら玄関へ戻すような状態です。

.htaccess を使う方法を先に試した

まずは .htaccess でリダイレクトできないか試しました。

.htaccess は、サーバーに対して「この URL で来たらこう処理してね」と伝える設定ファイルです。

かなり早い段階で動くので、WordPress がページを表示する前に処理を決められるのが特徴です。

イメージとしては、建物の入口にいる警備員のような存在です。

  • 入口で止める
  • 中に入る前に別の場所へ案内する

そのため、単純なリダイレクトには向いています。

たとえば、次のような処理は .htaccess が得意です。

  • /about に来たら / へ飛ばす
  • 古いドメインから新しいドメインへ飛ばす
  • 特定の 1 ページだけ別 URL へ移す

.htaccess で失敗した理由

ところが、今回は .htaccess ではうまくいきませんでした。

というのも、対象のサイトは WordPress で動いていて、さらに次のような仕組みが重なっていたからです。

  • WordPress のリライトルール
  • ログイン URL を変更する仕組み
  • 画像変換のルール
  • サーバー側の PHP 処理

つまり、入口に案内役が何人もいて、それぞれ別のルールで動いているような状態でした。

その中で「トップ以外は全部トップへ飛ばす」と強く書いてしまうと、本来は内部処理で必要なアクセスまで巻き込んでしまうことがあります。

その結果、同じところを何度も行き来するような状態になり、最終的には「リダイレクトが繰り返し行われました」と表示されてしまいました。

感覚としては、玄関に来た人だけ通したいのに、家の中でも何度も「玄関へ戻ってください」と言われ続けてしまうようなイメージです。

functions.php に切り替えたらうまくいった

そこで試したのが functions.php に書く方法です。

.htaccess が「建物の外の受付」だとしたら、functions.php は「建物の中の案内係」のようなものだと感じました。

WordPress が「これはトップページ」「これは投稿ページ」「これは管理画面」といった情報をある程度理解したあとで判断できるので、単純な URL 文字列だけで処理するよりも、今回のような条件分岐に向いていました。

今回うまくいったコード

<?php
// トップページ以外へのアクセスをトップページへリダイレクトする
function redirect_all_to_top_except_front() {
    // 管理画面は除外
    if ( is_admin() ) {
        return;
    }

    // ログイン画面や管理系処理は除外
    $request_uri = $_SERVER['REQUEST_URI'] ?? '';

    if (
        strpos($request_uri, '/wp-login.php') !== false ||
        strpos($request_uri, '/wp-admin') !== false ||
        strpos($request_uri, '/wp-cron.php') !== false ||
        strpos($request_uri, '/wp-json') !== false ||
        strpos($request_uri, '/xmlrpc.php') !== false ||
        strpos($request_uri, '/login_XXXXX') !== false
    ) {
        return;
    }

    // フロントページ・ホームはそのまま表示
    if ( is_front_page() || is_home() ) {
        return;
    }

    // それ以外はトップへ移動
    wp_redirect( home_url('/'), 301 );
    exit;
}
add_action('template_redirect', 'redirect_all_to_top_except_front');

このコードでは、次の流れで処理しています。

  1. 管理画面ならそのまま
  2. ログイン画面や内部処理ならそのまま
  3. トップページならそのまま
  4. それ以外ならトップへ移動

WordPress の中で「これは飛ばさない」「これは飛ばす」と判断できるので、.htaccess よりループしにくかったようです。

.htaccess と functions.php の違い

.htaccess の特徴

  • サーバーが最初に見る
  • 処理が速い
  • URL 単位の単純な振り分けが得意
  • WordPress の内部事情までは分かりにくい
  • 書き方を間違えるとサイト全体が見えなくなることがある
  • ループが起きると管理画面にも入れなくなることがある

functions.php の特徴

  • WordPress が動いたあとで使える
  • 「トップページかどうか」などを WordPress のルールで判断できる
  • 条件分岐を書きやすい
  • WordPress が壊れていなければ調整しやすい
  • テーマ変更時に消えることがある
  • WordPress 自体が動かない状態では効かない

言いかえると、.htaccess は強いけれど大ざっぱな判断向き、functions.php は少し後で動く代わりに、より賢く条件分岐しやすいという違いでしょうか。

今回は functions.php のほうが向いていた理由

今回は明らかに functions.php のほうが向いていました。

理由は大きく 2 つです。

1 つ目は、対象が WordPress サイトだったことです。単純な HTML サイトではなく、内部処理が多いので、URL だけを見て全部飛ばすのは危険でした。

2 つ目は、「トップだけ表示」「管理画面とログインは除外」という少し細かい条件があったことです。これは WordPress の中で判定したほうがわかりやすかったです。

今回の方法で注意したいこと

functions.php に書く方法にも注意点があります。

  • テーマを変えると消えることがある
  • 管理画面やログイン URL の除外を忘れると、自分も入れなくなる
  • キャッシュの影響で、直ったのに直っていないように見えることがある

そのため確認はゲストブラウザなどでも試したほうが安心だと感じました。

まとめ

今回は、トップページだけ見せて下層ページはすべてトップへ戻したい、という WordPress サイトでの対応を整理しました。

今回の学びをまとめると、次のようになります。

  • .htaccess は強力だが、WordPress の内部処理を巻き込んでループすることがある
  • functions.php は WordPress の状態を見ながら細かく判定できる
  • トップだけ表示して他を隠したいようなケースでは、functions.php のほうが安定しやすいことがある

今回のように「WordPress サイトで、トップだけ見せて他を隠したい」というケースでは、URL だけで止めるより、WordPress の中で条件を見て判断する方法のほうが向いている場面があることがわかりました。

WordPress

Posted by auto_post