Hatena::ブログ(Diary)

130単位

2010-07-24

WordPress 投稿記事のスラッグを変更しても旧URLでアクセスできる仕組み

Q. 投稿記事のスラッグを変更したら旧URLでアクセスできる?

(ex.http://example.com/過去のスラッグ/ → http://example.com/new-slug/)

A. できます

ってのを調べてみました。(※ WordPress 3.0)

過去のスラッグを記録する仕組み

  • 投稿記事の編集完了時に動作
  • 編集後と編集前のスラッグを比較
  • 変更されていればメタ情報(隠しカスタムフィールド)として_wp_old_slugキーに編集前のスラッグを登録
アクションフック

wp-includes/default-filters.php

<?php
add_action( 'post_updated',      'wp_check_for_changed_slugs', 12, 3 );
アクション関数

wp-includes/post.php

<?php
function wp_check_for_changed_slugs($post_id, $post, $post_before) {
	// dont bother if it hasnt changed
	if ( $post->post_name == $post_before->post_name )
		return;

	// we're only concerned with published posts
	if ( $post->post_status != 'publish' || $post->post_type != 'post' )
		return;

	$old_slugs = (array) get_post_meta($post_id, '_wp_old_slug');

	// if we haven't added this old slug before, add it now
	if ( !in_array($post_before->post_name, $old_slugs) )
		add_post_meta($post_id, '_wp_old_slug', $post_before->post_name);

	// if the new slug was used previously, delete it from the list
	if ( in_array($post->post_name, $old_slugs) )
		delete_post_meta($post_id, '_wp_old_slug', $post->post_name);
}

過去のスラッグからリダイレクトする仕組み

  • 表示の際のテンプレート決定時に動作
  • 404かつリクエストされたURLにスラッグが認識された場合
  • メタ情報_wp_old_slug(過去のスラッグ)とリクエストされたスラッグが一致する記事を照会
  • 存在すればその記事のURLリダイレクト
アクションフック

wp-includes/default-filters.php

<?php
// Redirect Old Slugs
add_action( 'template_redirect', 'wp_old_slug_redirect'              );
アクション関数

wp-includes/query.php

<?php
function wp_old_slug_redirect() {
	global $wp_query;
	if ( is_404() && '' != $wp_query->query_vars['name'] ) :
		global $wpdb;

		$query = "SELECT post_id FROM $wpdb->postmeta, $wpdb->posts WHERE ID = post_id AND meta_key = '_wp_old_slug' AND meta_value='" . $wp_query->query_vars['name'] . "'";

		// if year, monthnum, or day have been specified, make our query more precise
		// just in case there are multiple identical _wp_old_slug values
		if ( '' != $wp_query->query_vars['year'] )
			$query .= " AND YEAR(post_date) = '{$wp_query->query_vars['year']}'";
		if ( '' != $wp_query->query_vars['monthnum'] )
			$query .= " AND MONTH(post_date) = '{$wp_query->query_vars['monthnum']}'";
		if ( '' != $wp_query->query_vars['day'] )
			$query .= " AND DAYOFMONTH(post_date) = '{$wp_query->query_vars['day']}'";

		$id = (int) $wpdb->get_var($query);

		if ( !$id )
			return;

		$link = get_permalink($id);

		if ( !$link )
			return;

		wp_redirect($link, '301'); // Permanent redirect
		exit;
	endif;
}

留意点

レアケースですが、別の投稿記事で過去のスラッグが同じものが存在した場合は、先に過去のスラッグが登録された記事のほうに優先してリダイレクトされます。

何にせよ余計な処理が入り込んでしまうので、基本的には一度公開されたURL(スラッグ)は変更しないほうがいいと思います。

関連リンク

パーマリンクの変更後、旧アドレスでもアクセスできるWordPressプラグイン | コリス 
http://coliss.com/articles/blog/wordpress/plugin/wordpress-plugin-permalink-edirect.html

カスタムフィールドに表示されないメタ情報の作り方  |  wpxtreme 
http://wpxtreme.jp/meta-key-and-value-hidden-on-custom-fields

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証