Skip to content
これは pieceofcake2/seo のドキュメントです。pieceofcake2/cakephp 用の CakePHP 2.x プラグインです。 このフォークについて

リダイレクトとステータスコード ​

リダイレクトツールは、本来 404 Not Found になるリクエストに対して 301 リダイレクトを送ります。 主に SEO のために使いますが、ユーザーを誤った URL から正しい URL へ案内するためにも使えます。 リクエスト URI に対するルールを定義します。ルールはシンプルな URI、ワイルドカード、正規表現の いずれかで、それぞれに優先度と有効フラグがあります。ステータスコードも同じ仕組みで、URI に対して 410 Gone など任意のステータスコードを返します。

ルールが読み込まれるのは、本来 404 になる場合 (または自分で catch404() を呼んだ場合。 セットアップ をご覧ください) だけです。アプリケーションがエラーなく応答する URI のルールは 使われません。ページが表示されるなら、プラグインは読み込まれもしません。このツールは、検索エンジンと ユーザーにとって適切で役に立つ方法でエラーを扱うように設計されています。

リクエストが 404 になると、プラグインは次の順に確認します。

  1. 有効な ステータスコード (優先度順)
  2. 有効な リダイレクト (優先度順)
  3. URL 推測 が有効な場合、サイトマップの中で最も近い URL

何も一致しなければ、通常の 404 ページが表示されます。

セットアップ ​

config/core.php (レガシーレイアウトでは app/Config/core.php) でプラグインの例外ハンドラーを使います。

php
Configure::write('Exception', [
    'handler' => 'SeoExceptionHandler::handle',
    'renderer' => 'ExceptionRenderer',
    'log' => true,
]);

config/bootstrap.php (レガシーレイアウトでは app/Config/bootstrap.php) で、プラグインを読み込んだ後に ハンドラーのクラスを読み込みます。

php
require_once CakePlugin::path('Seo') . 'Lib' . DS . 'Error' . DS . 'SeoAppError.php';

自分のコードから、たとえば未知の URL を自分で処理するコントローラーから、ステータスコードとリダイレクトを 実行するには catch404() を呼びます。

php
$seoAppError = new SeoAppError();
$seoAppError->catch404();

URI はリクエストの REQUEST_URI と比較されるので、クエリ文字列も含みます。

リダイレクトの追加 ​

リダイレクトの一覧と管理は https://example.com/admin/seo/seo_redirects で、追加は https://example.com/admin/seo/seo_redirects/add で行います。リダイレクトには次のフィールドがあります (seo_redirects テーブル、URI は seo_uris)。

URI 301 でリダイレクトさせたいリクエスト URI です。ドメインからの相対パス (/old-page)、 ワイルドカード付きのパス (/old-section*)、または # で始まり # で終わる正規表現 (高度なリダイレクト をご覧ください) を指定します。

Redirect 一致した URI を 301 でリダイレクトする先の URL で、できればドメインからの相対パスにします。 絶対 URL、パス、または正規表現の URI の置換パターン (/guides/$1) を指定できます。 コールバック を使う場合は、リダイレクト先のどこかに {callback} を入れます。 これはコールバックの戻り値に置き換えられます。

Priority ルールの優先度で、デフォルトは 100 です。複数のルールが一致した場合は、優先度の数値が 小さい ルールが優先されます。たとえば、

  • /test.asp から /first-link へ、優先度 1
  • /test.asp から /other-link へ、優先度 2

の場合、/test.asp へのリクエストは /other-link ではなく /first-link にリダイレクトされます。

Is Active ルールを有効または無効にします。有効なルールだけが使われます。

Is Nocache (編集画面のみ) ブラウザーがリダイレクトをキャッシュしないように、301 と一緒に Cache-Control と Expires ヘッダーを 送ります。後で変更するかもしれないリダイレクトに使います。

Callback 呼び出すメソッドを Model::method (または Plugin.Model::method) の形で指定します。 リクエストされた URI が渡され、その戻り値でリダイレクト先の {callback} が置き換えられます。 メソッドが false を返すと、リダイレクトは取り消されます。Model:: のないメソッド名は SeoRedirect モデルで呼び出されます。

リダイレクト先がリクエストと同じルールは、リダイレクトループを避けるためにスキップされます。 log 設定がオンの場合、リダイレクトと検出されたループは seo_redirects タイプでログに記録されます。

リダイレクトの種類 ​

リダイレクトには、基本的なリダイレクトと高度なリダイレクトの 2 種類があります。

基本的なリダイレクト ​

基本的なリダイレクトは、一対一または多対一のリダイレクトです。書くのも理解するのも簡単です。 URI とリダイレクト先は、ドメインからの相対パスにしてください。

一対一

  • URI: /library
  • Redirect: /guides/common-questions
  • 結果: https://example.com/library は https://example.com/guides/common-questions にリダイレクトされます

比較では大文字と小文字を区別せず、リクエスト全体が一致する必要があります。

多対一、ワイルドカードを使う場合

  • URI: /website*
  • Redirect: /
  • 結果: https://example.com/website、https://example.com/websites-are-fun、 https://example.com/website/param/really/long/url は https://example.com/ にリダイレクトされます

URI の末尾の * は、指定した部分に続く任意の文字列に一致します。このルールは /website で始まる すべてのリクエストに一致します。

高度なリダイレクト ​

高度なリダイレクトは、正規表現でリクエストを照合し、リダイレクト先は preg_replace() の置換パターンになります。 はるかに柔軟ですが、読み書きは難しくなります。多対多のリダイレクトができるのは、高度なリダイレクトだけです。

正規表現の URI は # で始まり # で終わる (その後に i などの修飾子を続けてもかまいません) 必要があります。そうでなければ基本的な URI として扱われます。

正規表現のルールは強力ですが、リダイレクトループなどの思わぬ事態を引き起こすこともあります。 注意して使ってください。

正規表現の URI は未承認として保存され (URI の管理画面で Is Approved にチェックを入れた場合を除く)、 承認されるまでそのルールは使われません。プラグインは approverEmail に通知メールを送ります (送信元は replyEmail、メール設定は emailConfig。設定 をご覧ください)。 メールには URI、リダイレクト先、優先度と、URI を承認する /admin/seo/seo_uris/approve/<URI の id> へのリンクが載ります。リンクの先頭は parentDomain で、parentDomain を設定していない場合は アプリケーションの完全なベース URL (App.fullBaseUrl) になります。 https://example.com/admin/seo/seo_uris で URI を編集し、Is Approved にチェックを入れて 承認することもできます。シェル で追加したリダイレクトはすぐに承認されます。

多対多

  • URI: #(.*)\?from\=sb\-tracked\:(.*)#i
  • Redirect: $1
  • 結果: ?from=sb-tracked:... で終わる URI は、そのクエリ文字列を除いた同じ URL にリダイレクトされます。

式の末尾の i によって、大文字と小文字が区別されなくなります。URI の中の括弧の組は、左から順に番号が 付けられ、リダイレクト先で $1、$2 などとして使えます。この例では $1 は ? より前の部分、 $2 は tracked: の後の値です。

  • URI: #^/article/([0-9a-zA-Z]*)#
  • Redirect: /guides/$1
  • 結果: URI の残りの部分を保ったまま、/article/ を /guides/ の別名にします。

コールバックによるリダイレクト ​

コールバックを使うと、.htaccess のリダイレクトではできないことができます。特に、404 を表示する代わりに データベースから正しい URL を探せます。

たとえば、記事の URL が https://example.com/article/123-slug のような形で、id が 123、 スラッグが slug だとします。id 123 の壊れたリンクを正しいスラッグの URL にリダイレクトするには、 記事ごとにルールを書く代わりに、コールバックを使ったルールを 1 つ書けば済みます。

  • URI: #^/article/([0-9]+)(.*)#i
  • Redirect: /article/$1-{callback}
  • Callback: Article::callbackFindSlugById

Article モデルにコールバックを書きます。

php
/**
 * Returns the slug of the requested article, for the SEO redirect.
 *
 * @param string $request the requested URI
 * @return string|false the slug, or false to cancel the redirect
 */
public function callbackFindSlugById($request)
{
    if (!preg_match('#^/article/([0-9]+)#', $request, $matches)) {
        return false;
    }

    $slug = $this->field('slug', ['id' => $matches[1]]);

    return $slug ?: false;
}

このルールは、記事への壊れたリンクを正しい id-slug の URL にリダイレクトします。コールバックが false を返すと (たとえば存在しない id の場合)、リダイレクトは取り消され、404 ページが表示されます。

ステータスコードの追加 ​

ステータスコードの一覧と管理は https://example.com/admin/seo/seo_status_codes で、追加は https://example.com/admin/seo/seo_status_codes/add で行います。ステータスコードには、URI (リダイレクトの URI と同じように照合されます)、ステータスコード、優先度 (小さいものが先)、有効フラグがあります。一致したリクエストには、ステータスコードとその理由フレーズ (たとえば 410 Gone) だけが返されます。

注意: 特別なケースとして、ステータスコード 200 は、代替 URL を消すための (410 の代わりとなる) 帯域を最小限に抑えた noindex の robots ページを返します。

URL 推測 ​

levenshtein 設定 (設定 をご覧ください) を使うと、ステータスコードにも リダイレクトにも処理されない 404 は、 レーベンシュタイン距離 でサイトマップの中から 最も近い URL に 301 でリダイレクトされます。

  • active: URL 推測を有効にします。
  • source: サイトマップです。webroot の中のパス (/sitemap.xml) または URL を指定します。 その URL は、最初に必要になったとき、または seo_urls シェル で seo_urls テーブルに インポートされます。
  • cost_add、cost_change、cost_delete: 文字の追加、変更、削除のコストです。コストが高いほど、 一致を見つけるためにその変更が許される量が少なくなります。
  • threshold: URL はサイトマップでの優先度の順に確認され、しきい値より近い最初の URL で検索が 止まります。そうでなければ最も近い URL が使われます。-1 を指定すると常にすべての URL を確認し、 最も近いものを見つけます。

log 設定がオンの場合、これらのリダイレクトは seo_levenshtein タイプでログに記録されます。

シェル ​

Seo.seo_redirects シェルでリダイレクトを管理します。

bash
# Quickly search for an existing redirect
bin/cake Seo.seo_redirects search <url or redirect>

# Add a new redirect, priority 100 by default
bin/cake Seo.seo_redirects add <url> <redirect> [priority] [callback]

# Delete redirects or URIs by id
bin/cake Seo.seo_redirects delete <id> [<id> ...]
bin/cake Seo.seo_redirects delete_uri <id> [<id> ...]

例:

bash
bin/cake Seo.seo_redirects add '/mybad/path*' '/my-cleaned-up-path' 50
bin/cake Seo.seo_redirects add '/myother-bad/path*' '/my-cleaned-up-path' 60
bin/cake Seo.seo_redirects add '/my*' '/my-failover-path' 10
bin/cake Seo.seo_redirects add '#/some-old-route-(.*)#i' '/new-route-$1' 10
bin/cake Seo.seo_redirects add '#/(admin|moderator)/(.*)#i' '/$2?old-prefix=$1' 10

URI は / または # で始まり、リダイレクト先は / または http で始まる (または {callback} を含む) 必要があります。URI に既存のリダイレクトがある場合は変更されません。管理画面で編集してください。

URL 推測 で使う URL を levenshtein.source からインポートする (levenshtein.active がオンの場合のみ。インポートはすべての URL を置き換えます) か、1 件追加します。

bash
bin/cake Seo.seo_urls import
bin/cake Seo.seo_urls add <url> <priority>

レガシーレイアウトでは、bin/cake の代わりに app/Console/cake を使います。

参考資料 ​

正規表現について詳しくは、次の資料をご覧ください。

正規表現は regex101 でテストできます (PCRE を選んでください)。

著作権とライセンスについては LICENSE を参照してください。Cake Software Foundation とは関係ありません。