WordPressのパーマリンクの変更を行いました。

WS2014-12-19_15_44_16

昨年の末、約1年前にサーバーを引っ越してCMSをMovable TypeからWordPressに変更したわけです。

サーバーを引っ越しました。ついでにCMSをMovable TypeからWordPressに変えました。

そして、パーマリンクが変わってしまうのは困るので、下記の記事の様にWordPressを魔改造して使ってきました。

Movable Type version 4.38(MTOS)からWordPress 3.8への移行記録

しかし、ワードプレスは頻繁にアップデートが来るし、自動アップデートされることもあるので、いつの間にか魔改造が更新されたソースで上書きされてしまいブログ記事が404になってしまうことが1年間に何度もありました。

その度に修正するのも面倒ですし、まあそれでも1年間は頑張ってみたのですが、もう面倒なのでパーマリンクを変更することにしました。

 

パーマリンクの変更

/%year%/%monthnum%/%postname%.html

今までのパーマリンクの設定はこのようになっていて、Movable Typeのパーマリンクを継承する形になっていました。それだけでは足りずpostnameの部分がWordPressはMovable Typeより短いので、DBの定義や、WordPressのソースを弄ってMovable Typeと同じ長さのパーマリンクが生成できるようにしていました。

【悲報】建築中のツバメの巣が崩壊!

結果上の様なURLになります。長いですね。

http://blog.kumacchi.com2013/03/猫と共に故郷へ還る.html

デコードされるとこんな感じになります。

これはまだ短い方なのでいいですが、長いものはとんでもないことになっていてそれはそれでちょっと問題になっていました。

/%year%/%monthnum%/%day%/%post_id%

そして今回のパーマリンクがこれです。

日本語が混じったURLと言うのは記事の内容がURLでわかるのでSEO的に良いとか聞きますが、まあ、そうなんですけど、もう、なんていうか面倒なんですね。URLもめちゃくちゃ長くなって色々困ったことも起きますし、無駄に容量喰いますし。リンクも貼りにくいですし、リンク貼ってもらわれにくくなるような気がしますし。短縮URL使えばいいですけど、それも面倒ですし。

もう面倒なのでSEOとかいいので日本語混じらない日付と記事番号だけのシンプルなのでいいやということになりました。

そうすると

こんなに長いURLも

blog.kumacchi.com/2013/05/%e3%83%8d%e3%82%b9%e3%82%ab%e3%83%95%e3%82%a7_%e3%83%90%e3%83%aa%e3%82%b9%e3%82%bf%e3%81%ae%e8%aa%bf%e5%ad%90%e3%81%8c%e6%82%aa%e3%81%84%e3%81%ae%e3%81%a7%e5%88%86%e8%a7%a3%e6%b8%85%e6%8e%83%e3%81%97%e3%81%a6%e3%81%bf%e3%81%9f.html
(デコードしたもの:blog.kumacchi.com/2013/05/100円ショップダイソーで買った物だけで猫草を栽培して愛猫に.html)

こんなに短いURLで済みます。

blog.kumacchi.com/2013/05/05/2363

大体下の様に日本語から数字のみで.htmlも外しました。

blog.kumacchi.com/2013/03/猫と共に故郷へ還る.html
blog.kumacchi.com/2013/03/27/2295

リダイレクトしてみる

最初はもうリダイレクトはいいかなーと思ったのですが、せっかくこのブログにリンクを張って頂いている方に申し訳ないですし、やっぱりアクセスが減るのはもったいないということで、リダイレクトすることにしました。

.htaccessには、下の様にデコード済みの文字とデコード前の文字でRewriteRuleを書きました。最初はデコード前のモノだけでやっていたのですが、上手くリダイレクトされないので、デコード後の行も作成しました。これでうまくいきました。このことで数時間悩みました。まさかデコード後の文字でマッチングしているとは思いませんでした。これだとどちらでアクセスされても行けるはずです。その分行数が多くなりますが。

RewriteRule ^2013/03/%e7%8c%ab%e3%81%a8%e5%85%b1%e3%81%ab%e6%95%85%e9%83%b7%e3%81%b8%e9%82%84%e3%82%8b.html$ /2013/03/27/2295 [R=301,NC,L]
RewriteRule ^2013/03/猫と共に故郷へ還る.html$ /2013/03/27/2295 [R=301,NC,L]

perlスプリクトでRewriteruleを自動生成してみる

何しろ記事が2000件強あるので、どうしようかな~リダイレクトやめようかなーと思ったのですが、なんとか自動で作れないかなと思って試行錯誤してみました。

WordPressのプラグインなどもありますが、うまく動かなかったので前に諦めたことがあったので今回はそれは考えませんでした。シンプルにmod_rewriteを使おうと思ったわけです。

方法としては、DBもアップデートで書き換わったようなので、毎日とっているバックアップから復元したSQLを使ってDBの複製を生成しました。データ抽出専用です。

そこからSQLで取り出したIDとpost_nameとpost_dateから旧URLと新URLを生成してRewriteRuleを生成するという寸法です。

さくっとつぎはぎで作ったものなので、ソースは推敲されていません。

wpttlcv.pl

#!/usr/bin/perl

use strict;
use warnings;
use utf8;
use Encode qw/from_to decode_utf8 encode_utf8 is_utf8/;
use DBI;
#use Translate;
#use File::Path qw(make_path);
#use LWP::Simple;
#use HTML::Entities;

use CGI::Simple;

my $q = new CGI::Simple();

my $dbh = DBI->connect(‘DBI:mysql:<データベース名>:localhost’, ‘<ユーザ名>’, ‘<パスワード>’,{PrintError=>0,AutoCommit=>0});
unless($dbh){die $DBI::errstr;}
my ($hst,$retval,$ref,$count);

=pod
mysql> DESCRIBE wp_posts;
+———————–+———————+——+—–+———————+—————-+
| Field                 | Type                | Null | Key | Default             | Extra          |
+———————–+———————+——+—–+———————+—————-+
| ID                    | bigint(20) unsigned | NO   | PRI | NULL                | auto_increment |
| post_author           | bigint(20) unsigned | NO   | MUL | 0                   |                |
| post_date             | datetime            | NO   |     | 0000-00-00 00:00:00 |                |
| post_date_gmt         | datetime            | NO   |     | 0000-00-00 00:00:00 |                |
| post_content          | longtext            | NO   | MUL | NULL                |                |
| post_title            | text                | NO   | MUL | NULL                |                |
| post_excerpt          | text                | NO   |     | NULL                |                |
| post_status           | varchar(20)         | NO   |     | publish             |                |
| comment_status        | varchar(20)         | NO   |     | open                |                |
| ping_status           | varchar(20)         | NO   |     | open                |                |
| post_password         | varchar(20)         | NO   |     |                     |                |
| post_name             | varchar(500)        | NO   | MUL |                     |                |
| to_ping               | text                | NO   |     | NULL                |                |
| pinged                | text                | NO   |     | NULL                |                |
| post_modified         | datetime            | NO   |     | 0000-00-00 00:00:00 |                |
| post_modified_gmt     | datetime            | NO   |     | 0000-00-00 00:00:00 |                |
| post_content_filtered | longtext            | NO   |     | NULL                |                |
| post_parent           | bigint(20) unsigned | NO   | MUL | 0                   |                |
| guid                  | varchar(255)        | NO   |     |                     |                |
| menu_order            | int(11)             | NO   |     | 0                   |                |
| post_type             | varchar(20)         | NO   | MUL | post                |                |
| post_mime_type        | varchar(100)        | NO   |     |                     |                |
| comment_count         | bigint(20)          | NO   |     | 0                   |                |
+———————–+———————+——+—–+———————+—————-+
23 rows in set (0.02 sec)
=cut

$hst = $dbh->prepare(‘SELECT ID,post_date,post_name,post_type FROM wp_posts’);
unless($hst){ &dberror("104:",$dbh,$hst);    }

$retval = $hst->execute();
unless($retval){ &dberror("66105:",$dbh,$hst); }

#すべて (2,157) |    公開済み (2,119) |    下書き (37) |    非公開 (1)
#旧URLでアクセスしてきても探すみたいで表示される 場合もある
#http://blog.kumacchi.com/2014/11/nexus-72012-wifi-32gb%e3%83%a2%e3%83%87%e3%83%ab%e3%81%abandroid-5-0-lrx21p%e3%83%ad%e3%83%aa%e3%83%9d%e3%83%83%e3%83%97%e3%82%92%e3%83%95%e3%82%a1%e3%82%af%e3%83%88%e3%83%aa%e3%83%bc%e3%82%a4%e3%83%a1%e3%83%bc%e3%82%b8%e3%81%a7%e3%82%a2%e3%83%83%e3%83%97%e3%83%87%e3%83%bc%e3%83%88%e3%81%97%e3%81%9f.html
#http://blog.kumacchi.com/2014/11/nexus-72012-%e3%82%92android-5-0-lrx21p%e3%83%ad%e3%83%aa%e3%83%9d%e3%83%83%e3%83%97%e3%81%ab%e3%81%97%e3%81%a6%e9%87%8d%e3%81%8b%e3%81%a3%e3%81%9f%e3%82%89wipe-cache-partition%e3%81%99%e3%82%8b%e3%81%a8%e3%81%84%e3%81%84%e3%82%89%e3%81%97%e3%81%84.html#more-6313
#http://blog.kumacchi.com/2014/11/18/6291
#旧:/%year%/%monthnum%/%postname%.html

#http://blog.kumacchi.com/2014/11/01/6256
#新:/%year%/%monthnum%/%day%/%post_id%
#RewriteRule ^old_url$ new_url [R=301,L]

#2157|6351|2014-12-15 13:56:12||post_type:post

my %tmp=();
my $cnt = 0;
while($ref = $hst->fetch()){
    my $ID         = $ref->[0] || ”;
    my $post_date  = $ref->[1] || ”;
    my $post_name  = $ref->[2] || ”;
    my $post_type  = $ref->[3] || ”;

    my $yyyy = substr($post_date,0,4);
    my $mm = substr($post_date,5,2);
    my $dd = substr($post_date,8,2);

    if($post_type ne ‘post’){
        $tmp{$post_type} = 1;
    }

#    next if($post_type ne ‘page’);
    next if($post_type eq ‘revision’ || $post_type eq ‘attachment’ || $post_type eq ‘nav_menu_item’ || $post_type eq ‘wpcf7_contact_form’ || $post_type eq ‘page’);

    $cnt++;
    #print "$cnt|$ID|$post_date|$post_name|post_type:$post_type\n";
#    print "$cnt|$ID|$post_date [$yyyy/$mm/$dd]|$post_name|post_type:$post_type\n";

    #RewriteRule ^old_url$ new_url [R=301,L]
    my $decoded_post_name = $q->url_decode($post_name);

    my $rr_a = "RewriteRule ^$yyyy/$mm/$post_name.html\$ /$yyyy/$mm/$dd/$ID [R=301,NC,L]\n";
    my $rr_b = "RewriteRule ^$yyyy/$mm/$decoded_post_name.html\$ /$yyyy/$mm/$dd/$ID [R=301,NC,L]\n";

    #同じなら一個だけ、違ったら別々に出力
    my $rr = ($rr_a eq $rr_b) ? $rr_a : $rr_a . $rr_b;
    print $rr;

}
$hst->finish;
$dbh->disconnect;

#foreach my $key(keys %tmp){
#    print "$key\n";
#}

#====================================================================
#    dberror
#====================================================================
sub dberror{
    my $msg = shift;
    my $dbh = shift;
    my $hst = shift;

    my $errstr = $dbh->errstr;
    $dbh->rollback;
    if($hst) { $hst->finish; undef $hst; }
    $dbh->disconnect;
    die "$msg$errstr\n";
#    debug_print("$msg$errstr\n");
#    error("data base error [$msg$errstr]");
}

これを実行すると下のようなリストが生成されます。

RewriteRule ^2014/10/%e3%80%90%e3%83%9f%e3%83%a5%e3%83%bc%e3%82%b8%e3%83%83%e3%82%af%e3%83%93%e3%83%87%e3%82%aa%e3%80%91ok-go-i-wont-let-you-down-official-video%e3%81%8c%e3%81%8b%e3%81%aa%e3%82%8a%e3%81%99%e3%81%94%e3%81%8f%e3%81%a6%e7%b6%9a%e3%81%91%e3%81%a6%ef%bc%93%e5%9b%9e%e8%a6%8b%e3%81%9f.html$ /2014/10/29/6236 [R=301,NC,L]
RewriteRule ^2014/10/【ミュージックビデオ】ok-go-i-wont-let-you-down-official-videoがかなりすごくて続けて3回見た.html$ /2014/10/29/6236 [R=301,NC,L]
RewriteRule ^2014/11/%e6%90%ba%e5%b8%af%e9%9b%bb%e8%a9%b1%e3%81%abrakuten-co-jp%e3%83%89%e3%83%a1%e3%82%a4%e3%83%b3%e3%82%92%e6%a8%a1%e5%80%a3%e3%81%97%e3%81%9f%e3%83%a1%e3%83%bc%e3%83%ab%e3%82%a2%e3%83%89%e3%83%ac%e3%82%b9%e3%81%8b%e3%82%89%e5%bb%b6%e3%80%85%e3%81%a8%e3%82%b9%e3%83%91%e3%83%a0%e3%83%a1%e3%83%bc%e3%83%ab%e3%81%8c%e5%b1%8a%e3%81%8f%e4%bb%b6.html$ /2014/11/01/6251 [R=301,NC,L]
RewriteRule ^2014/11/携帯電話にrakuten-co-jpドメインを模倣したメールアドレスから延々とスパムメールが届く件.html$ /2014/11/01/6251 [R=301,NC,L]
RewriteRule ^2014/11/hbjyuyahoobb%e3%81%aeadsl%e3%81%ae%e6%9c%80%e8%bf%91%e3%81%ae%e7%8a%b6%e6%85%8b2014%e5%b9%b4%e3%81%be%e3%81%a8%e3%82%81.html$ /2014/11/01/6256 [R=301,NC,L]
RewriteRule ^2014/11/hbjyuyahoobbのadslの最近の状態2014年まとめ.html$ /2014/11/01/6256 [R=301,NC,L]
RewriteRule ^2014/11/ntt%e8%a5%bf%e6%97%a5%e6%9c%ac%e3%82%92%e5%81%bd%e3%81%a3%e3%81%9f%e3%83%95%e3%82%a3%e3%83%83%e3%82%b7%e3%83%b3%e3%82%b0%e3%82%b5%e3%82%a4%e3%83%88%e3%81%8b%e3%82%89%e3%81%ae%e3%83%a1%e3%83%bc%e3%83%ab.html$ /2014/11/16/6282 [R=301,NC,L]
RewriteRule ^2014/11/ntt西日本を偽ったフィッシングサイトからのメール.html$ /2014/11/16/6282 [R=301,NC,L]
RewriteRule ^2014/11/nexus-72012-wifi-32gb%e3%83%a2%e3%83%87%e3%83%ab%e3%81%abandroid-5-0-lrx21p%e3%83%ad%e3%83%aa%e3%83%9d%e3%83%83%e3%83%97%e3%82%92%e3%83%95%e3%82%a1%e3%82%af%e3%83%88%e3%83%aa%e3%83%bc%e3%82%a4%e3%83%a1%e3%83%bc%e3%82%b8%e3%81%a7%e3%82%a2%e3%83%83%e3%83%97%e3%83%87%e3%83%bc%e3%83%88%e3%81%97%e3%81%9f.html$ /2014/11/18/6291 [R=301,NC,L]
RewriteRule ^2014/11/nexus-72012-wifi-32gbモデルにandroid-5-0-lrx21pロリポップをファクトリーイメージでアップデートした.html$ /2014/11/18/6291 [R=301,NC,L]

そして.htaccessの適当な場所に以下のルールを書き込みます。

# BEGIN MY
# BEGIN MY
<IfModule mod_rewrite.c>

RewriteEngine On
RewriteBase /
RewriteRule ^2005/04/post_8.html$ /2005/04/11/2 [R=301,NC,L]
RewriteRule ^2005/04/post_9.html$ /2005/04/12/3 [R=301,NC,L]
RewriteRule ^2005/04/post_10.html$ /2005/04/13/4 [R=301,NC,L]
RewriteRule ^2005/04/post_11.html$ /2005/04/13/5 [R=301,NC,L]
RewriteRule ^2005/04/post_12.html$ /2005/04/15/6 [R=301,NC,L]
RewriteRule ^2005/04/part.html$ /2005/04/28/7 [R=301,NC,L]
RewriteRule ^2005/04/post_13.html$ /2005/04/28/8 [R=301,NC,L]
RewriteRule ^2005/05/post_14.html$ /2005/05/07/9 [R=301,NC,L]

</IfModule>

# END MY
# END MY

これで、リダイレクトされるようになりました。

これでもう、WordPressのアップデートも躊躇しなくてよくなりそうです。

参考になれば幸いです。

タグ : , ,