Wordpress 3.0 で記事分割のアドレスをクリックしても表示が切り替わらない問題について

公開日| 2010年10月27日   更新日| 2012年9月14日   コメントはありません。

こんにちわ。管理人です。

今回は、前回インストールしたWordpress3.0の問題についてです。

WordPressでは、記事分割という機能があります。これは、長い1つの記事をページ分割して見やすくする機能です。

投稿記事の中で、分割したい位置に以下のタグを埋め込めば、記事の分割をすることができます。

<!--nextpage-->

実際に分作した記事は、以下のように表示されます。
記事が分割された様子
サンプル記事は、こちらで実際に記事を確認できます。

上記の例では、1つの記事を3ページに分割しています。
1ページ目は、正しく表示されるのですが、分割された2ページ目以降が、表示できないのです。 下の2、3ページへのリンクをクリックしても1ページ目が表示されてしまいます。

そこで、この問題に対応すべく、少し調べてみましたので以降に記載しておきます。

まずは、現象の条件を明確にしましょう

ここの例(サンプル記事です。)で、この問題が、少なくともWordpress3.01までは、発生しています。

いろいろと調べてみると以下のWordpressのフォーラムでも同じ問題が提起されていました。
参照記事:3.0でサブカテゴリに登録した記事をページ分割するとリダイレクトされる

先のフォーラムによれば、

  • パーマリンク構造をカスタム構造(/%category%/%postname%/)で使用しています。
  • 2.9.2から3.0にバージョンアップをしたところ、サブカテゴリに登録した記事のページ分割ナビゲーションが上手くいかなくなりました。

    – サブカテゴリとここで言っているのは、カテゴリの子カテゴリを言っています。

    具体的には、
    http://example.com/category/category2/postname/2/
    という風にアクセスすると、
    http://example.com/category/category2/postname/
    にリダイレクトされてしまいます。

ということらしいです。実際に、自分でも確認してみました。
確かにこの現象は、上記の2つの条件があいまって発生しているようです。

さらに、

remove_action('template_redirect', 'redirect_canonical');

これをfunction.phpで実施すると、問題が回避できたそうです。

先の‘redirect_canonical’は、実際、どこで処理しているか調べてみれば、wp-includes/canonical.phpというファイルであることがわかります。 結局、このファイルのどこかしら原因があって、この問題が発生しているということになるわけですね。

問題の本質を確認しましょう

次に、問題の直接的原因がどこで何をしているためかを明確にします。
先にファイルの限定ができているわけですから、あとは、ソースを追うのか、Wordpress 2.x との差分をとれば、わかると思います。

そこで、単純にコンペアして、その差分から怪しいところを見つけました。
wp-includes/canonical.phpの192行目あたりです。

192
193
194
195
196
197
} elseif ( is_single() && strpos($wp_rewrite->permalink_structure, '%category%') !== false ) {
	$category = get_term_by('slug', get_query_var('category_name'), 'category');
	$post_terms = wp_get_object_terms($wp_query->get_queried_object_id(), 'category', array('fields' => 'tt_ids'));
	if ( (!$category || is_wp_error($category)) || ( !is_wp_error($post_terms) && !empty($post_terms) && !in_array($category->term_taxonomy_id, $post_terms) ) )
		$redirect_url = get_permalink($wp_query->get_queried_object_id());
}

この処理は、まさしくパーマリンクに/%category%を使用している場合の処理のようです。
カテゴリのslug名からterm情報を取り出そうとして、取り出せなかったら現在の記事のパーマネントリンクアドレスへ強制的にリダイレクトしています。

ピンポーン!!

ここに違いないようですね。

つまりは、カテゴリのslug名からterm情報を取り出そうとしていることに問題があって、カテゴリは、何階層かなんて意識していないので、ここで2階層のカテゴリでNGとなってしまうんですね。

これは、ほぼ、Wordpressの問題に違いないのですが、対処が問題です。
Wordpress本家によるこの問題の対処を待つのは、ちょっと、気が長すぎますね。

じゃあ、とりあえず、このバグ?っぽいのを自前で修正するかって話ですが、できれば、避けたいですね。
だって、このルートが、この問題を引き起こしているのは間違いないのですが、ここを変更することで、現在、うまくいっているところへの影響も考えないといけなくなって、ちょっと大変です。

そこで、今回は、自前のテーマ(テンプレート)を一部変更してあげることで対応してみましょう。

問題の対処をしましょう

今回の問題は、自前のテーマ(テンプレート)の中で対処したいと思います。
結局ですね、この問題っていうのは、

http://example.com/category/category2/postname/2/
が、↓こうなちゃうのが問題なんですよね。
http://example.com/category/category2/postname/

つまり、URLの最後の(ページ番号を意味する)数値(ここでは、2)が、パラメータじゃなく、URLの通常のアドレスとして処理されるので、リダイレクトされてしまうんですよね。
※この問題の意味は、もう少し説明が必要なんですが、wp-includes/canonical.phpの処理内容を説明しないといけなくなるので、ここでは割愛します。

もっと具体的に言えば、この(ページ番号を意味する)数値を、ちゃんとパラメータだよって渡してあげるとうまくいくんですよね。

例えば、
http://example.com/category/category2/postname/2/
を、↓こんな感じで変換しちゃえばOKなんですよね。
http://example.com/category/category2/postname/?page=2

もし、同じ問題をかかえている方がおられるなら、お試しください。
最後に?page=2のようにしてあげると、ちゃんと表示できると思います。

さて、対処です。
対処するのは、自前のテーマ(テンプレート)の中でwp_link_pages();を使っている箇所を以下のように変更すればOKのはずです。

$page_link=wp_link_pages('echo=0');
if(!empty($page_link)){
	$page_link = preg_replace('/"(http:\/\/[^"]*)\/([\d]+)\/"/i','"\1/?page=\2"',$page_link);
	if(!is_null($page_link)){
		echo $page_link;
	}
}

これは、さっきの?page=2のように、単純に2という数値を取り出して、URLを置換しているだけです。

最初に示した問題の投稿ページに対して、対策を施したページは、こちらです。

どうでした?

さすがに、これは、原因究明と対処に数時間かかってしまいました。

ま、自力でもなんとか対処できるところがオープンソースの良いところでもありますけどね。

プラグインの問題は、もっと限定できるので良いですが、Wordpress本体の問題は、結構、面倒です。バージョンアップは、十分な確認の上にやりましょう。


コメント

口コミ・評判を投稿 :

ブラウザの JavaScriptが無効となっている場合、コメントの投稿はできません。
コメントを投稿するには、JavaScriptを有効にしてください

お名前 *

メールアドレス *
(口コミ・評判欄には、表示されませんが入力が必要です。)

サイトアドレス



  • はてなブックマークへ追加する
  • Facebookでシェアする
  • twitter でつぶやく
  • Google Plusでシェアする
  • Pocketでシェアする
ページトップへ