由于之前用的WordPress里存了不少文章,而且用了wordpress的一些插件和特殊格式,所以要先去WordPress的后台里导出文章的xml格式文件到本地,然后使用Hexo的迁移插件进行一些特殊处理并生成MarkDown格式的文件。

目录

  1. 文章导出
  2. 文章转换
    1. 安装迁移扩展
    2. 防止扩展生成的markdown文件名乱码
    3. WordPress特殊格式转换
      1. html实体转换(附加防止转换删除线)
      2. 高亮代码标签转换,以及短代码提示框转换
      3. 生成和tag相同的Keywords
  3. 迁移文章导入

文章导出

按照Hexo官方文档的说明,在 WordPress 仪表盘中导出数据(“Tools” → “Export” → “WordPress”),检查生成并下载到本地的xml文件,去除其中的无用分类(因为当前版本的Hexo的同级分类只能有一个,多个分类会变成父分类-子分类的格式。或许此问题以后会有妥善的解决方案)。


文章转换

安装迁移扩展

在Hexo的项目目录下安装迁移扩展hexo-migrator-wordpress:

1
npm install hexo-migrator-wordpress --save

防止扩展生成的markdown文件名乱码

  1. 编辑Hexo项目中的node_modules/hexo-migrator-wordpress/index.js 文件
  2. 修改56行的slug,改为 slug = item[‘wp:post_id’][0] ,这里是将slug修改为文章id

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    var title = item.title[0],
    id = item['wp:post_id'][0],
    date = item['wp:post_date'][0],
    slug = item['wp:post_id'][0],//修改这里
    content = item['content:encoded'][0],
    comment = item['wp:comment_status'][0],
    status = item['wp:status'][0],
    type = item['wp:post_type'][0],
    categories = [],
    tags = [];

    if (!title && !slug) return next();
    if (type !== 'post' && type !== 'page') return next();
    if (typeof content !== 'string') content = '';
  3. 解释下上一步的原因:我之前的WordPress文章是按照数据库里的文章id作为唯一别名的(http://域名/blog/数字),而Hexo的文章链接是按照MarkDown文件名来决定的(http://域名/可选前缀/MarkDown文件名/)。为了新的站的链接也和之前相同,使用post_id作为slug即可迁移生成按文章id的文章文件。如果你的文章slug有特殊含义,请勿用这种方式处理。

WordPress特殊格式转换

同样编辑Hexo项目中的node_modules/hexo-migrator-wordpress/index.js 文件,然后根据自己需要修改的部分,在文件中分别进行以下处理.

html实体转换(附加防止转换删除线)

  1. 添加函数replaceHTMLEntity:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    function replaceHTMLEntity(str){
    str = str.replace(/amp;/g, '');
    str = str.replace(/&lt;/g, '<');
    str = str.replace(/&gt;/g, '>');
    str = str.replace(/&quot;/g, '"');
    str = str.replace(/&#92;/g, '\\');
    str = str.replace(/&#48;/g, '0');
    str = str.replace(/~~/g, '~ ~ ');//防止被转为删除线
    return str;
    };
  2. 添加一行代码到content = tomd(content).replace(/\r\n/g, ‘\n’);前面 :

    1
    2
    content = replaceHTMLEntity(content);//添加这行
    content = tomd(content).replace(/\r\n/g, '\n');

高亮代码标签转换,以及短代码提示框转换

在WordPress使用了Syntax Highlighter代码高亮插件,还有一个短代码提示框S-shortcodes插件,请根据实际插件使用情况自行修改函数中的替换内容。

  1. 添加函数replaceCodeTag :

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    function replaceCodeTag(str){
    //Syntax Highlighter代码高亮插件
    str = str.replace(/\[code\]/gi, '```\n');
    str = str.replace(/\[\/code\]/gi, '\n```');
    str = str.replace(/\[code\ lang\=\"bash\"\ collapse=\"true\"\]/gi, '```bash\n');
    str = str.replace(/\[code\ lang\=\"bash\"\]/gi, '```bash\n');
    str = str.replace(/\[code\ lang\=\"php\"\]/gi, '```php\n');
    str = str.replace(/\[code\ lang\=\"shell\"\]/gi, '```bash\n');
    str = str.replace(/\[code\ lang\=\"csharp\"\]/gi, '```cs\n');
    str = str.replace(/\[code\ lang\=\"html\"\]/gi, '```html\n');
    str = str.replace(/\[code\ lang\=\"js\"\]/gi, '```javascript\n');
    str = str.replace(/\[code\ lang\=\"javascript\"\]/gi, '```javascript\n');
    str = str.replace(/\[code\ lang\=\"sql\"\]/gi, '```sql\n');
    str = str.replace(/\[php\]/gi, '```php\n');
    str = str.replace(/\[\/php\]/gi, '\n```');

    //短代码提示框插件S-shortcodes
    str = str.replace(/\[box\ style\=\"alert\"\]/gi, '{% alert danger %}\n');
    str = str.replace(/\[box\ style\=\"warning\"\]/gi, '{% alert warning %}\n');
    str = str.replace(/\[box\ style\=\"download\"\]/gi, '{% alert info %}\n');
    str = str.replace(/\[box\ style\=\"info\"\]/gi, '{% alert success %}\n');
    str = str.replace(/\[box\ style\=\"tip\"\]/gi, '{% alert success %}\n');
    str = str.replace(/\[box\ style\=\"blue\"\]/gi, '{% alert info %}\n');
    str = str.replace(/\[\/box\]/gi, '\n{% endalert %}');


    return str;
    };
  2. 添加一行代码到content = tomd(content).replace(/\r\n/g, ‘\n’);前面 :

    1
    2
    3
    content = content = replaceCodeTag(content);//添加这行
    content = replaceHTMLEntity(content);
    content = tomd(content).replace(/\r\n/g, '\n');

生成和tag相同的Keywords

后续我们还要做SEO优化,这里可以先对其做一些前期准备。
Front-matter 是Hexo文章的MarkDown文件最上方以 --- 分隔的区域,可以用来指定个别文件的变量。
由于迁移插件会自动在Hexo文章最前面的Front-matter区域生成tags,我们可以也同时在Front-matter中生成与tags相同的关键词Keywords字符串。只需要在tag赋值处后面加一行:

1
2
3
if (categories.length && type === 'post') data.categories = categories;
if (tags.length && type === 'post') data.tags = tags;
if (tags.length && type === 'post') data.keywords = tags.join();//添加这行

这样在迁移文件生成的时候,每篇文章的tag还会以逗号分隔生成keywords项.


迁移文章导入

在hexo目录下,执行迁移指令:

1
hexo migrate wordpress ***.xml

  • 其中,*.xml为导出的WordPress文章数据文件。
  • 执行完成后,就可以看到hexo项目的source/_posts文件夹下生成了对应的MarkDown文件。
  • 如果有需要调整迁移脚本的地方,可以把生成的文件都删除(如果posts文件夹下已有文章记得转移或备份),修改迁移扩展的脚本文件后,重新执行迁移指令。
  • WordPress的加密文章也是会迁移过来的,需要注意处理。

剩下的就是修改和微调啦,毕竟有些地方转换为markdown的版式和缩进细节难以完美,可能需要手动校对修改一遍。