mintsu's blog

Nuxt.jsでMarkdownで作成可能なブログを作った

2019-02-24 01:18:00
フロントエンド

Markdownで作成可能なブログを作った

目次

動機

技術ブログであればQiitaや、git管理するにしても静的サイトジェネレータ等ありますが、
下記理由から自前でブログを立てることにしました。

  • ブログ記事をMarkdown(マークダウン)で管理したい、書きたい
  • 技術以外のブログ記事も書きたい
  • 記事をgitで管理したい
  • デザインや機能を自由に追加・変更したい
  • フロントエンド技術の習得

利用技術

  • Nuxt.js(Vue.js)
  • processmd
  • markdown-it
    • markdown-it-meta
    • markdown-it-hilight

ブログの作成

方向性

  • Markdownを直接パースは難しいため、プログラムから扱いやすいようにjsonに変換
    • 変換にはprocessmdを利用
  • Nuxtで画面表示時に変換したjsonを読み出してMarkdownからhtmlに変換して表示
    • markdownからHTMLへの返還へはmarkdown-itを利用

記事(マークダウン)を置く場所

下記のようにcontentsというディレクトリ以下に記事を置くようにしました。

contents/
├── json
│   └── 2019-02-16-sample001.json   # processmdによって自動生成
├── markdown
│   └── 2019-02-16-sample001.md
└── summary.json      # processmdによって自動生成

Markdownファイルのjson変換

Meta情報の埋め込み

ブログを作成するためにはカテゴリや、タグの分類機能が欲しくなります。
それらの情報はmeta情報として下記の様にMarkdownに記載します。

---
title: テスト記事1
description: テスト記事1です
tags: 
  - タグ1
category: その他
created_at: "2019-02-16 00:08:00"
updated_at: "2019-02-16 00:00:00"
---

Markdownからjsonへの変換

変換にはprocessmdを利用します。

processmdのインストール

$ yarn add -D processmd

変換コマンド

$ processmd \"contents/markdown/**/*.md\" --preview 160 --stdout --outputDir contents/json > contents/summary.json

実際に下記のMarkdownを使い変換を試してみます。

元となるMarkdown

---
title: テスト記事1
description: テスト記事1です
tags: 
  - タグ1
category: その他
created_at: "2019-02-16 00:08:00"
updated_at: "2019-02-16 00:00:00"
---

# Hello World
- Hello World

Markdownから生成された記事を表すjsonファイル

{
  "title": "テスト記事1",
  "description": "テスト記事1です",
  "tags": [
    "タグ1"
  ],
  "category": "その他",
  "created_at": "2019-02-16 00:08:00",
  "updated_at": "2019-02-16 00:00:00",
  "bodyContent": "# Hello World\n- Hello World",
  "bodyHtml": "<h1>Hello World</h1>\n<ul>\n<li>Hello World</li>\n</ul>\n",
  "preview": "Hello World\nHello World",
  "dir": "contents/json",
  "base": "2019-02-16-sample001.json",
  "ext": ".json",
  "sourceBase": "2019-02-16-sample001.md",
  "sourceExt": ".md"
}

生成された summary.json は下記の様になります。

{
  "fileMap": {
    "contents/json/2019-02-16-sample001.json": {
      "title": "テスト記事1",
      "description": "テスト記事1です",
      "tags": [
        "タグ1"
      ],
      "category": "その他",
      "created_at": "2019-02-16 00:08:00",
      "updated_at": "2019-02-16 00:00:00",
      "preview": "Hello World\nHello World",
      "dir": "contents/json",
      "base": "2019-02-16-sample001.json",
      "ext": ".json",
      "sourceBase": "2019-02-16-sample001.md",
      "sourceExt": ".md"
    }
  },
  "sourceFileArray": [
    "contents/markdown/2019-02-16-sample001.md"
  ]
}

MarkdownからHTMLへの変換

markdownitとmarkdown-itのプラグインのインストール

$  yarn add  @nuxtjs/markdownit markdown-it-anchor markdown-it-table-of-contents markdown-it-meta markdown-it-highlight

nuxtでもmarkdownitが使いやすいように @nuxt.js/markdownit も入れています

@nuxt.js/markdownitが有効になるようにnuxt.config.jsを修正します

nuxt.config.js

  modules: [
    '@nuxtjs/markdownit'
  ],
  markdownit: {
    preset: 'default',
    linkify: false,
    breaks: true,
    html: true,
    typegraphy: true,
    injected: true,
    use: [
      'markdown-it-meta',
      'markdown-it-highlightjs',
      'markdown-it-table-of-contents',
      'markdown-it-anchor'
    ]
  }

記事を表示するためのVueファイルはは下記の様に書きます。

<template>
  <v-container>
    <v-layout column justify-center align-center>
      <v-flex xs12 sma12 md12 style="width: 100%">
        <div class="ma-4 markdown-body" v-html="$md.render(article.bodyContent)" />
      </v-flex>
    </v-layout>
  </v-container>
</template>

<script>
export default {
  async asyncData() {
    const article = await import(`~/contents/json/2019-02-16-sample001.json`)
    return {
      article: article
    }
  }
}
</script>

@nuxt.js/markdownitによって$md.renderを呼べるようになっています

表示

作ったページを確認すると下記のようにHTMLで表示がされます
画面表示

最後に

ここまでで記事の表示は終わりです。

基本的な変換方法、表示方法について今回は記載しました。

他にもブログを作る際に、カテゴリ分類や一覧ページを作ったりと言うのはありますが、processmdによって吐き出された、summary.jsonをうまく使うことでそのあたりも実現可能かと思います。

そちらに関しては、次回以降書こうと思います。