wordpress迁移至Ghost的url重定向

在开发部落的改版声明「开发部落改版了」一文中有说到开发部落已经从wordpress迁移到Ghost了,里面提到说原来搜索引擎收录的原来旧版本的文章,由于url规则不一样了,所以从搜索引擎跳过来会404,并且说到等搜索引擎更新本站索引之后才能正常访问,这里要纠正一下,如果我对此未做任何配置的话,搜索引擎是不会自动更新索引的。就算你等到花儿谢了又开了,它都不会有什么反应的。如果你域名没变,它老人家会以为你的站弄了好些个重复的文章,如果你域名变了,它甚至会认为你这个新站是不是在抄‘人家’的内容啊。

那如何才会让搜索引擎更新索引呢?用301重定向

情况一

如果你的新站跟旧站采用的是相同的规则,比如都是使用着相同的别名作为文章的链接,在你导入文章数据到新站后,那就比较方便了,只需要一条rewrite规则就可以了。我们假设你原来wordpress站的链接使用的是http://sitename.com/yyyy/MM/dd/the-post-title这种规则,而你的新站是使用的http://sitename.com/the-post-title这种规则,如果你跟我一样用的是nginx服务器,那么你就应该写一条像rewrite "\d{4}/\d{2}/\d{2}/(.*)$" /$1 permanent;这样的rewrite规则到你的站点配置文件里。当然,如果是apache的话,写法应该是差不多的,将写好的规则写到.htaccess文件里即可。

情况二

如果新旧站的url规则完全不一样,比如旧站用的是/articles/[id].html,老站却用的是别名/[post_slug],那岂不是一篇文章要写一条rewrite规则?恭喜你——是的,就是要写那么多条!而我这次迁移就是这种情况。。。╥﹏╥

不过我还是用相对轻松简单的手段完全了这个工作。这里详细记录一下,以便有需要的朋友前来查阅。

1. 查出所有文章映射关系

首先使用sql语句把新旧文章映射关系查询出来导出到文件里。比如类似/articles/409.html对应/ssh-port-forwarding这种。ok,how? 用一条SQL搞定它:

select p1.slug,p1.title,p2.ID into outfile '[/output/filepath]'  
from  [new_ghost_site_db].posts p1  
join [old_wordpress_site_db].wp_posts p2  
on p1.title = p2.post_title and p2.post_type='post';  

你需要将[/output/filepath]替换输出路径,[new_ghost_site_db]替换为新站db名字,[old_wordpress_site_db]就不解释了。

注意:[/output/filepath]最后是/tmp目录或者其子目录,否则可能出现写权限问题。

你可以在登录进mysql的命令界面直接执行该语句,也可以直接在未登录进mysql的terminal终端敲入mysql -u[username] -p -e "[the_magic_sql]"显然你需要把[username]替换为你的数据库用户名,把[the_magic_sql]替换为上面这条sql语句)后输入密码执行。

2. 将映射关系转成rewrite配置文件

然后再写一个脚本把导出的映射关系tg。我使用nodejs来做这个事情。代码中的/tmp/match_blog_url就是上面导出的文件

var fs = require('fs');  
var type = process.argv[2];  
var readFileName = '/tmp/match_blog_url';  
var writeFileName = '/tmp/url_migration_result.txt';  
var rewriteConfFileName = '/etc/nginx/sudodev_ghost.rewrite';  
var data = fs.readFileSync(readFileName,{encoding:'utf8'});  
var paires = data.split('\n');  
paires.forEach(function(line){  
    console.log(line);
    var row_data = line.split('\t');
    if(row_data.length==3){
        var slug = row_data[0];
        var oldId = row_data[2];
        if(type=='rewrite'){
            var rule = 'rewrite /articles/' + oldId + '.html ' + "/" + slug + ' permanent;';
            fs.appendFileSync(rewriteConfFileName,rule+'\n');
        }else{
            var newUrl = 'http://www.sudodev.cn/'+slug;
            var oldUrl = 'http://www.sudodev.cn/articles/'+ oldId +'.html';
            var outputLine = oldUrl + ' ' + newUrl;
            console.log('==='+outputLine);
            fs.appendFileSync(writeFileName,outputLine+'\n');
        }
    }
});

需要替换上面的几个文件路径,这里不再赘述。然后执行nodejs [the_script_filename.js] rewrite就会生成一个包含所有rewrite条目的文件。

命令里的rewrite参数是必须的,因为我这个脚本默认只生成包含‘旧老网址对’的文件。

3. 将生成的rewrite配置文件引入服务器容器

我的是ngix,所以在ngix配置文件中,加入include sudodev_ghost.rewrite这行至站点的配置文件里,重启nginx就可以了。注意rewrite文件的放置路径,否则重启会报错并且不生效。

4. 验证配置是否成功

Ok,试试访问你的旧链接,是否已经正确跳转到你的新链接上去了,如果你足够严谨的话, 你还应该确认一下,跳转码是否是301。

以上提到的SQL和nodejs脚本我已经放到了我的MagicScripts 项目里,供你我享用,:)