nodejh / nodejh.github.io

Blog
http://nodejh.com
267 stars 35 forks source link

从 Hexo 迁移到 Hugo #11

Open nodejh opened 7 years ago

nodejh commented 7 years ago

把博客从 Hexo 迁移到了 Hugo。主要原因有二:

遂弃用 Hexo。

1. 将 Hexo 的 YAML 转换为 Hugo 的 TOML

Hugo 的配置文件是 TOML 格式的,其生成的 Markdown 文件的 front matter(不知如何翻译)也是 TOML 结构:

+++
date = "2016-09-30T17:14:37+08:00"
description = ""
title = "Migrate to Hugo from Hexo"
tags = ["hugo", "hexo", "blog"]

+++

而 Hexo 的配置文件是 YAML 格式,其 Markdown 文件的 front matter 如下:

title: 'Start React with Webpack'
date: 2016-09-09 04:11:13
tags:
  - webpack
  - react

---

所以直接将 Hexo 的 Markdown 文件复制到 Hugo 中是不行的,必须得转换一下格式。虽然 Hugo 也可以直接在 config.toml 中配置 metaDataFormat:"yaml",这样 Hugo 就会生成 YAML 结构的 front matter ,但原 Hexo 的 Markdown 文件依旧不能正常的转换,因为 date 的格式不一样。

在 Hexo 中,文件里面的 date: 2016-09-09 04:11:13 并没有存储时区信息,而是把时区放在了 _config.yml 配置文件中。

By the way,TOML 是 GitHub 觉得 YAML 不够简洁优雅,所以捣鼓出来的一个东西。既然现在在用 Hugo,就没有理由不用 TOML 代替原来的 YAML。

其实两者之间的转换也很简单,我用 JS 写了一个脚本来将 YAML 转换为 TOML:

// yaml_to_toml.js
const readline = require('readline');
const fs = require('fs');
const os = require('os');
const moment = require('moment-timezone');  // 需要通过 npm install moment-timezone 来安装

const timezone = 'Asia/Shanghai';  // 时区
const src = 'hexo';  // hexo .md 文件源目录
const target = 'post';  // 目标文件目录

// 开始转换
readDir();

// 遍历目录
function readDir() {
    // read all files in src
    fs.readdir(src, function(err, files) {
        files.map((filename) => {
            // get the file extension
            const extension = filename.substr(filename.lastIndexOf('.', filename.length));
            if (extension === '.md') {
              readFile(`${filename}`);
            }
        });
    });

}

function readFile(filename) {
  fs.readFile(`${src}/${filename}`, { encoding: 'utf8' }, function(err, data) {
      if (err) {
          return console.log('err: ', err);
      }

      const content = data.split('---');
      const head = content[0].split('\n');
      // console.log('head: ', head);

      let newHead = head.map((item, index) => {
        // console.log('slpitHead: ', slpitHead(item, index, head));
        return slpitHead(item, index, head);
      });
      newHead = newHead.filter((item) => {return item;});
      // console.log('newHead: ', newHead);
      const newContent = `+++${os.EOL}${newHead.join(os.EOL)}${os.EOL}${os.EOL}+++${os.EOL}${content[1]}`;
      fs.writeFile(`${target}/${filename}`, newContent, {
          encoding: 'utf8'
      }, function(err) {
          if (err) {
            throw err;
          }
          console.log(`${filename}  生成成功!`);
      });
  });
}

function slpitHead(item, index, head) {
  // title
  if (item.indexOf('title:') !== -1) {
    return `title = "${item.split('title:')[1].trim()}"`;
  }

  // date
  if (item.indexOf('date:') !== -1) {
    return `date = "${(moment.tz(item.split('date:')[1], timezone)).format()}"`;
  }

  // tags
  if (item.indexOf('tags:') !== -1) {
    // console.log('tags...');
    const tags = [];
    for (let i=index+1; i<head.length; i++) {
      if (head[i].indexOf('-') !== -1) {
        // console.log('head[i].split('-')[1]: ', head[i].split('-')[1]);
        tags.push(head[i].split('-')[1].trim());
      } else {
        break;
      }
    }
    // console.log('tags: ', tags);
    return `tags = ${JSON.stringify(tags)}`;
  }

  // categories
  if (item.indexOf('categories:') !== -1) {
    const categories = [];
    for (let i=index+1; i<head.length; i++) {
      if (head[i].indexOf('-') !== -1) {
        categories.push(head[i].split('-')[1].trim());
      } else {
        break;
      }
    }
    // console.log('categories: ', categories);
    return `categories = ${JSON.stringify(categories)}`;
  }

  return false;
}

先配置好 timezone src target 三个参数。然后 npm install moment-timezone 安装需要的第三方包,最后 node yaml_to_toml.js 即可。

2. 图片目录的迁移

本地图片迁移也非常简单。

我之前使用 Hexo 的时候,是将所有图片都放在 source/images/ 目录里面的,在 Markdown 文件中引入图片是这样的: ![image title](/iamges/image_name.png)

Hugo 的图片可以直接放在其 static/ 目录里面,其路径就是 /iamges/image_name.png,所以我只需要将 Hexo 中的 images 目录复制到 Hugo 的 static/ 目录下即可。

3. 主题

看遍了 Hugo 给出的所有主题,都不满意。很多主题都超级简洁,这种风格还是很喜欢的。所以决定自己写一个。

最终 Fork 了 https://github.com/digitalcraftsman/hugo-cactus-theme 这个主题,然后改成了自己想要的样子。

主页

Migrate-to-Hugo-from-Hexo-1.png

文章页

Migrate-to-Hugo-from-Hexo-2.png

改后的主题源码:https://github.com/nodejh/hugo-theme-cactus-plus

4. 部署

由于 Github Pages 国内访问速度慢,所以同时把静态页面部署到了 Github Page 和 Coding Pages。

// 添加两个仓库
git remote add all https://github.com/nodejh/nodejh.github.io
git remote set-url origin --push --add https://git.coding.net/nodejh/nodejh.git
git remote set-url origin --push --add https://github.com/nodejh/nodejh.github.io

然后只需要执行 git push all branch 就可以同时向两个仓库 push 代码了。但暂时不这样做。而是在 public 目录外创建一个 deploy.sh 目录,用来自动部署:

#!/bin/bash

echo -e "\033[0;32mDeploying updates to GitHub...\033[0m"

# Build the project.
hugo # if using a theme, replace by `hugo -t <yourtheme>`

# Go To Public folder
cd public
# Add changes to git.
git add -A

# Commit changes.
msg="rebuilding site `date`"
if [ $# -eq 1 ]
  then msg="$1"
fi
git commit -m "$msg"

# Push source and build repos.
git push origin master

# Come Back
cd ..

接下来再给 deploy.sh 添加可执行权限 chmod +x deploy.sh。然后每次写完东西只需要 ./deploy.sh 'commit message' 即可。

gnostr commented 7 years ago

你好。请问用nginx + hugo + 这个主题,为什么生成的页面没有css? 谢谢

nodejh commented 7 years ago

写完 markdown 之后,使用 hugo 命令,就会根据 config.toml 中配置的主题生成对应的静态资源文件(包括 html/css/js)。静态资源文件在 public 目录。使用该主题生成的资源文件列表如下:

70e51c47-43b2-4509-b514-c2f68aff7220

所以我猜测可能原因有两个

gnostr commented 7 years ago

谢谢回复!

有css文件,

screen shot 2017-02-28 at 10 57 43

config.toml中也有指定theme

网页加载还是这样

screen shot 2017-02-28 at 10 58 06
nodejh commented 7 years ago

那应该是 config.tomlbaseurl 设置的问题了。

hugo 生成的 html 文件中,所有的链接都是根据 baseurl 生成的绝对路径(带域名的)。比如 baseurl = "http://nodejh.com",则在 index.html 中生成的路径就是 http://nodejh.com/js/main.js

所以根据你的服务器环境,修改一下 config.tomlbaseurl ,应该就能解决问题。

gnostr commented 7 years ago

还是不行。。我试了另外一个theme,没有问题。我也很是困惑... anyway,谢谢你,很可惜用不了这个theme!

CentOS 7 + Vultr

xinx1n commented 6 years ago

能否添加对 gitalk 评论系统的支持?

94192448 commented 6 years ago

config.toml 中文乱码,有设置地方吗?

binhaifgs1 commented 5 years ago

config.toml 中文乱码,有设置地方吗?

找到办法了吗

iamwlb commented 4 years ago

node yaml_to_toml.js ─╯ /Users/iamwlb/Documents/Workspace/nodejs/yaml_to_toml.js:21 files.map((filename) => { ^

TypeError: Cannot read property 'map' of undefined

tianheg commented 4 years ago

node yaml_to_toml.js ─╯ /Users/iamwlb/Documents/Workspace/nodejs/yaml_to_toml.js:21 files.map((filename) => { ^

TypeError: Cannot read property 'map' of undefined

我也遇到了同样的问题,找了很久,找不到解决办法。有这类错误的,跟 React 相关的很多,可是我不了解它。不知道 JavaScript 和 React 之间的联系