VuePressで作ったblogに配布されているテーマを設定する

## はじめに
最近もVuePressを少しづつカスタマイズしています。

デフォルトのテーマをカスタマイズしているんですが、Vuepress本体のアップデートの際にエラーが出てしまうこともあり時間が取られていました。
そこでこの際カスタマイズするのではなくいくつか出ているテーマの中からテーマを選んで設定しました。

## 環境
VuePress v1.0.3
> ちなみにVuePressそのものの環境自体は構築されている前提です。
環境構築についてはこちらのページで書きました。→[VuePressとnetlifyで手軽にblogをはじめる](https://qiita.com/tomopict/items/400bc4ce76ba1d8abfa2)


## 何はともあれテーマを選ぶ

今回検討したのは以下です。

* yubisaki
    * [Github](https://github.com/Yubisaki/vuepress-theme-yubisaki)
    * [DEMO](https://wuwaki.me/yubisaki/intro.html)
* ktquez
    * [GitHub](https://github.com/ktquez/vuepress-theme-ktquez)
    * [DEMO](https://ktquez-play.web.app/en/)
* meteorlxy
    * [GitHub](https://github.com/meteorlxy/vuepress-theme-meteorlxy)
    * [DEMO](https://vuepress-theme-meteorlxy.meteorlxy.cn/)

判断基準としては

* UIが使いやすいか
* starの数がどのくらいあるのか
* どのくらい更新がなされているか(直近に更新があるかどうか)

結論としてmeteorlxyを選びました。
決め手は更新頻度です。

* yubisakiは直近が4ヶ月前
* ktquezは5ヶ月前
* meteorlxyは昨日

**上記は2019年8月3日現在**

VuePress自体もどんどんバージョンアップしてますし、それに伴って機能も追加されているので、こまめにアップデートされているものを選択しました。

ちなみに他にもいくつかテーマがありますので自分の好きなテーマを探して見てください。
[awesome-vuepress](https://github.com/ulivz/awesome-vuepress)

## テーマを入れる

meteorlxyの公式に導入ガイドがあるので、それを参考にテーマを設定して行きます。
[Theme Guide](https://vuepress-theme-meteorlxy.meteorlxy.cn/posts/2019/02/27/theme-guide-en.html)

### インストール

まずはインストール行います

```shell
yarn add vuepress-theme-meteorlxy
```

### Config.jsの設定
`src/config.js`を更新します。
config.jsの設定内容に関しては[Theme Guide](https://vuepress-theme-meteorlxy.meteorlxy.cn/posts/2019/02/27/theme-guide-en.html)の中盤に`Click to expand the sample config`という記載があり、そちらをクリックすると設定内容が表示されます。

それ自体はデフォルトの設定のままなので、適宜変更しておきます。
以下デフォルトの設定。

```js
// .vuepress/config.js

module.exports = {
  // Title of your website
  title: 'My Blog',

  // Description of your website
  description: 'This is my blog',

  // Language of your website
  locales: {
    '/': {
      lang: 'en-US',
    },
  },

  // Theme to use
  theme: 'meteorlxy',

  // Theme config
  themeConfig: {
    // Language of this theme. See the [Theme Language] section below.
    lang: 'en-US',

    // Personal infomation (delete the fields if you don't have / don't want to display)
    personalInfo: {
      // Nickname
      nickname: 'meteorlxy',

      // Introduction of yourself
      description: 'Happy Coding<br/>Happy Life',

      // Email
      email: 'meteor.lxy@foxmail.com',

      // Your location
      location: 'Xi\'an City, China',

      // Your organization
      organization: 'Xi\'an Jiao Tong University',

      // Your avatar image
      // Set to external link
      avatar: 'https://www.meteorlxy.cn/assets/img/avatar.jpg',
      // Or put into `.vuepress/public` directory. E.g. `.vuepress/public/img/avatar.jpg`
      // avatar: '/img/avatar.jpg',

      // Accounts of SNS
      sns: {
        // Github account and link
        github: {
          account: 'meteorlxy',
          link: 'https://github.com/meteorlxy',
        },

        // Facebook account and link
        facebook: {
          account: 'meteorlxy.cn',
          link: 'https://www.facebook.com/meteorlxy.cn',
        },

        // LinkedIn account and link
        linkedin: {
          account: 'meteorlxy',
          link: 'http://www.linkedin.com/in/meteorlxy',
        },

        // Twitter account and link
        twitter: {
          account: 'meteorlxy_cn',
          link: 'https://twitter.com/meteorlxy_cn',
        },

        // Sina Weibo account and link
        weibo: {
          account: '@焦炭君_Meteor',
          link: 'https://weibo.com/u/2039655434',
        },

        // Zhihu account and link
        zhihu: {
          account: 'meteorlxy.cn',
          link: 'https://www.zhihu.com/people/meteorlxy.cn',
        },

        // Douban account and link
        douban: {
          account: '159342708',
          link: 'https://www.douban.com/people/159342708',
        },

        // Reddit account and link
        reddit: {
          account: 'meteorlxy',
          link: 'https://www.reddit.com/user/meteorlxy',
        },

        // Medium account and link
        medium: {
          account: 'meteorlxy.cn',
          link: 'https://medium.com/@meteorlxy.cn',
        },

        // Instagram account and link
        instagram: {
          account: 'meteorlxy.cn',
          link: 'https://www.instagram.com/meteorlxy.cn',
        },

        // GitLab account and link
        gitlab: {
          account: 'meteorlxy',
          link: 'https://gitlab.com/meteorlxy',
        },

        // Bitbucket account and link
        bitbucket: {
          account: 'meteorlxy',
          link: 'https://bitbucket.org/meteorlxy',
        },

        // Docker Hub account and link
        docker: {
          account: 'meteorlxy',
          link: 'https://hub.docker.com/u/meteorlxy',
        },
      },
    },

    // Header Config
    header: {
      // The background of the header. You can choose to use an image, or to use random pattern (geopattern)
      background: {
        // URL of the background image. If you set the URL, the random pattern will not be generated, and the `useGeo` will be ignored.
        url: '/assets/img/bg.jpg',

        // Use random pattern. If you set it to `false`, and you don't set the image URL, the background will be blank.
        useGeo: true,
      },

      // show title in the header or not
      showTitle: true,
    },

    // Show the last updated time of your posts
    lastUpdated: true,

    // The content of your navbar links
    nav: [
      { text: 'Home', link: '/', exact: true },
      { text: 'Posts', link: '/posts/', exact: false },
    ],

    // Comments config. See the [Posts Comments] section below.
    comments: {
      owner: 'meteorlxy',
      repo: 'vuepress-theme-meteorlxy',
      clientId: 'MY_CLIENT_ID',
      clientSecret: 'MY_CLIENT_SECRET',
    },

    // Pagination config
    pagination: {
      perPage: 5,
    },

    // Default Pages (Optional, the default value of all pages is `true`)
    defaultPages: {
      // Allow theme to add Home page (url: /)
      home: true,
      // Allow theme to add Posts page (url: /posts/)
      posts: true,
    },
  },
}
```

### 記事を一つ追加してみる。
blogの記事自体は`src/_posts/`以下にmarkdwon形式書いて行きます。
一つめの記事を作成してみます。

```shell

mkdir ./src/_posts
touch  ./src/_posts/20190803.md
```

```markdown:20190803.md
---
title: ''
date: 2019-08-03
category: diary
tags:
  - 日常
---
# Hello meteorlxy!
```
ここまできたらローカルで確認してみます。

```shell
# develop
yarn dev
# build
yarn build
```

以下のアドレスでアクセスできるはずです。
`http://localhost:8080/posts/2019/08/03/_20190803.html`

![localhost_8080_posts_2019_08_03__20190803.html.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191638/2fe0c9ec-669d-a285-a447-e3eea9f8f644.png)

## 細かい調整

### 文字化け対応
そのままだと一部の漢字が文字化け(中国語？)します。
![localhost_8080_0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191638/a3288f5b-e462-0b15-e22a-18a89a5c89ef.png)

実はこの部分で結構はまりました。
原因はbodyに設定されていたfont-familyの設定でした。

```css:normalize.styl
body 
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", Heiti SC, Hiragino Sans GB, Microsoft YaHei, Dengxian, Simsun, sans-serif

```
上記のスタイル自体は`./node_modules/vuepress-theme-meteorlxy/lib/styles/normalize.styl`にありますが、ライブラリを上書きすることは避けて、`config.js`上で他のファイルから読み込んで上書きすることにします。
以下のコマンドでディレクトリとファイルを作成しておきます。

```shell
mkdir ./src/.vuepress/public/css
touch ./src/.vuepress/public/css/style.css
```
作成した`style.css`内に以下のcssを追加します。
あまりやりたくありませんが`!important`の記載もしています。

```css:style.css
body {
  font-family: "Helvetica", "Arial", "ヒラギノ角ゴ Pro W3", "Hiragino Kaku Gothic Pro", "Osaka", "メイリオ", "Meiryo", "ＭＳ Ｐゴシック", "MS PGothic"!important; 
}
```

これを`config.js`内で呼び出し元のスタイルを上書きします。
`config.js`に以下を追加します。

```js:config.js
// 前略
head: [
  ['link', { href: '/css/style.css', rel: 'stylesheet'}]
]
// 後略
```
これで文字化けが解消します。

![localhost_8080_.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191638/0a3a2b47-75d9-04fb-c0df-fe8caf1e1b2f.png)


### avatarの設定
ページ内に右側にあるavatar画像の設定をします。

```shell
mkdir ./src/.vuepress/public/img
```

上記ディレクトリに画像を追加して`config.js`内の以下の箇所を書き換えます。

```js:config.js
// 変更前
avatar: 'https://www.meteorlxy.cn/assets/img/avatar.jpg'
// 変更後
avatar: '/img/avatar.png'
```

### 言語の設定と日本語化ファイルの微調整
デフォルトが英語設定になっているので、変更します。

```js:config.js
// 変更前
  locales: {
    '/': {
      lang: 'en-US',
    },
  }

// 変更後
 locales: {
    '/': {
      lang: 'ja-JP'
    }
  }
```

また「次の投稿」「検索」などの箇所も日本語化されていないので、`config.js`の以下の箇所を変更します。
すでに有志のかたが日本語化をしてくださっていたので以下のように指定すれば日本語化されます。
[参考](https://blog.ouvill.net/blog/2019-03-29--change_blog_system/change_blog_system/)

```js:config.js
// 変更前
themeConfig: {
 lang: 'en-US',
}
// 変更後
themeConfig: {
  lang: 'en-JP',
  // OR
  lang: require('vuepress-theme-meteorlxy/lib/langs/en-JP'),
}
```

なお自分はそれらもカスタマイズしたかったので同じように`public`ファイル内にjsを作成して読み込んで上書きしています。

```shell
mkdir ./src/.vuepress/public/lang
touch ./src/.vuepress/public/lang/js-JP.js
```

```js:js-JP.js
module.exports = {
  // default pages title
  home: 'ホーム',
  posts: 'ポスト',
  category: 'カテゴリー',
  categories: 'カテゴリー',
  tag: 'タグ',
  tags: 'タグ',

  // post filter
  allCategories: '全て',
  search: '検索',
  searchHint: 'タイトルとタグから検索',
  noRelatedPosts: '関連する投稿はありません',

  // post meta
  top: 'トップ',
  createdAt: '作成日',
  updatedAt: '更新日',
  prevPost: '前の投稿',
  nextPost: '次の投稿',

  // post nav
  toc: '目次',
  comments: 'コメント',

  // hints
  notFound: '該当ページはありません',
}

```

```js:config.js
themeConfig: {
  lang: require('./public/lang/ja-JP')
}
```

## カテゴリとタグの設定
カテゴリとタグは以下のような形で定義します。

```markdown
---
date: 2019-08-03
category: diary
tags:
  - 日常
---
```

デプロイして確認ができれば完成です。

[実際公開しているblog](https://tomopict.netlify.com/)

## 終わりに
カスタマイズする手間もなく色々な機能がすでに用意されているのは嬉しいのですが、やはり自由度が少し下がるのは否めません。
今後はカスタムテーマの自作なんぞもやって見たいと思います。

## 参考サイト
[meteorlxy公式サイト](https://vuepress-theme-meteorlxy.meteorlxy.cn/)