0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

VuePress でテンプレートから記事生成

Posted at

最近 VuePress で個人ブログの運用をはじめました

ですが、VuePress 単体では記事の Markdown を自動で生成できないことに悩んでいたので、{{ mustache }} を使った簡易的な記事生成スクリプトを作りました。

イメージ的には hexonew コマンド のような感じです。

登場人物

new-post.jstemplates/*.mustache を新規に追加します。

$ tree vuepress
.
├── new-post.js <------------------------- スクリプト本体
├── package.json
├── docs <-------------------------------- VuePress のプロジェクトフォルダ
│   ├── .vuepress
│   │   └── config.yml 
│   └── _posts
│       └── 2019-12-31-newpost.md <------- 生成される markdown
└── templates <--------------------------- テンプレート フォルタ
    ├── base.mustache
    └── header.mustache

スクリプトの実装

まずは、スクリプトです。mustache を使うのでパッケージを入れておきます。

$ yarn add --dev mustache

スクリプト本体は git で管理 してますがここにも記載しておきます。そんな大したことはしてません。

機能:

  • 引数で次の 3 つを指定
    • ベースとなるテンプレート
    • 記事のタイトル
    • (optional) markdown のファイル名
  • ベースとなるテンプレートに「タイトル」と「日付」を埋め込んで出力
  • 出力するファイルは 2019-12-13-lower-case-title.md のような名前
new-post.js
'use strict';

const fs = require("fs");
const path = require('path');
const mustache = require('mustache');

function formatedateDate(date, includesDatetime) {
    const dateStr = [
        date.getFullYear(),
        ("0" + (date.getMonth() + 1)).slice(-2),
        ("0" + date.getDate()).slice(-2)
    ].join("-");
    const datetimeStr = [
        ("0" + date.getHours()).slice(-2),
        ("0" + date.getMinutes()).slice(-2),
        ("0" + date.getSeconds()).slice(-2),
    ].join(":");

    return includesDatetime ? dateStr + " " + datetimeStr : dateStr;
}

function sanitizeTitle(title) {
    return title.replace(/[ ?!@;'\\.]/g, '-').toLowerCase().replace(/^[ -]+|[ -]+$/g, "");
}

/** Parameters */
const postDir = path.join("docs", "_posts");
const templateEngine = {
    name: "Mustache",
    dir: "templates",
    extension: ".mustache",
};

/** Parse arguments */

const usage = "Usage: node new-post.js <template-name> <title> [<title-for-filename>]";
const args = process.argv.slice(2, process.argv.length);
if (args.length != 2 && args.length != 3) {
    console.error("Invalid arguments")
    console.error(usage);
    process.exit(1);
}

const templatePath = path.join(templateEngine.dir, args[0] + templateEngine.extension);
const title = args[1];
const filetitle = args[2] ? sanitizeTitle(args[2]) : sanitizeTitle(title);
const postFilename = formatedateDate(new Date(), false) + "-" + filetitle + ".md";
const postPath = path.join(postDir, postFilename);

/** Main */

fs.readFile(templatePath, 'utf8', function (err, templateData) {
    if (err) throw err;

    // render the template with mustache.
    const renderedData = mustache.render(templateData, {
        title: title,
        date: formatedateDate(new Date(), true),
        overview: title + "についての記事です。",
    });

    // write a markdown file out.
    fs.writeFile(postPath, renderedData, {
        flag: 'wx'
    }, function (err) {
        if (err) {
            throw err;
        }
        console.log("Created a new post at: " + postPath)
    });
});

テンプレートの実装

templates/<template-name>.mustache にテンプレートを置いていきます。

base.mustache
---
title: "{{ title }}"
date: {{ date }}
category: その他
tags:
  - タグ
---

{{ overview }}

<!-- more -->

# {{ title }}

[[toc]]

## はじめに

new-post.js 内の以下の部分が、テンプレートに値を代入して markdown をレンダリングする処理に相当します。

    // render the template with mustache.
    const renderedData = mustache.render(templateData, {
        title: title,
        date: formatedateDate(new Date(), true),
        overview: title + "についての記事です。",
    });

使い方

$ node new-post.js <template-name> <title> [<title-for-filename>]

# e.g.
$ node new-post.js base "はじめての Node.js" getting-started-with-nodejs
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?