サイトジェネレーター Gridsome(グリッドサム)でブログ投稿機能を作る

サイトジェネレーターGridsome(グリッドサム)でブログ投稿機能を作る

Post スキーマの設計

まず、gridsome.config.js を編集し、 Post スキーマを作ります

この設定が Graph QL に反映されるような仕様です。

  • use: "@gridsome/source-filesystem"

    グリッドサムのソースファイルシステムと言うのを使います

  • typeName:"Post"

    呼び出す時に使います

  • route: '/post/:slug',

    ページを表示したときのスラッグの設定

  • path: "./src/contents/*/.md"

    どこの Markdown ファイルを読むか

※メモ:スラッグを数字に設定し、ルート階層で表示しようとした場合は 404 エラーが出ます

このケースの場合、refs でタグやカテゴリの設定も入れています。

gridsome.config.js

module.exports = {
    plugins: [
        {
            use: "@gridsome/source-filesystem",
            options: {
                typeName: "Post",
                route: '/post/:slug',
                path: "./src/contents/**/*.md",
                refs: {
                    tags:{
                        typeName: "Tag",
                        route: "/tag/:id",
                        create: true
                    },
                    category:{
                        typeName: "Category",
                        route: "/category/:id",
                        create: true
                    }
                }
            }
        }
    ]
}

/src/pages/Index.vue

続いて Index.vue ファイルの編集です。トップページでブログ記事の一覧を作ります

Page-Query の中で、Type : Post を allPost という記法で、Post の中のデータを全て呼び出しています。Graph QL 特有のクエリの書き方みたいですね

HTML 部分は Gridsome 標準のページャーを組み込んでいますが、 post の数だけループを回し、それぞれ、タイトルとディスクリプション、また URL パスを取りに行くような仕組みにしています

<template>
  <Layout>
    <h1>僕のデザインプロセス</h1>
    <div class="index">
      <article class="blog-article" v-for="post in $page.posts.edges" :key="post.node.id">
        <h2>{{post.node.title}}</h2>
        <p>{{post.node.description}}</p>
        <div>
          <g-link :to="post.node.path">本文を読む</g-link>
        </div>
      </article>
      <Pager :info="$page.posts.pageInfo"/>
    </div>
  </Layout>
</template>

<page-query>
query ($page: Int) {
  posts : allPost (perPage: 5, page: $page) @paginate {
    pageInfo {
      totalPages
      currentPage
    }
    edges {
      node {
        id
        title
        description
        date (format: "YYYY/MM/DD")
        path
      }
    }
  }
}
</page-query>

続いて、/src/templates/Post.vue

ブログのページ詳細の部分にあたりますが、 templates 改装の中には Post をどう表示するのかをテンプレートで表現できます

今回のサンプルは投稿内容と、投稿に設定されているタグを表示するような形で、投稿内容は

<div v-html="$page.post.content" />

でクリックで指定した*.md ファイルを呼び出すような形になります

Post.vue

<template>
  <Layout>
    <div class="post">
      <div v-html="$page.post.content" />
      <g-link :to="tag.path" v-for="tag in $page.post.tags" :key="tag.id" class="">
        {{ tag.title }}
      </g-link>
    </div>
  </Layout>
</template>

<page-query>
query Post($id: ID!) {
  post(id: $id) {
    title
    description
    summary
    path
    date (format: "YYYY/MM/DD")
    tags{
      id
      title
      path
    }
    content
  }
}
</page-query>

<script>
export default {
  metaInfo() {
    return {
      title: this.$page.post.title,
      meta: [
        { name: 'description', content: this.$page.post.description },
      ]
    }
  }
}
</script>

##続いて、ブログの中身である Markdown ファイル

/src/contents/posts/1.md
  • slug: 1

    ポストの際に表示したい URL の設定

  • title / description

    サイトのタイトルやディスクリプションの定義 script の中の Meta info で HTML のメタ情報上書きしています

  • summary

    ページの一覧ページなどで利用する用のテキスト

  • date

    ブログの投稿日の設定

  • tags

    つけたいタグ設定

---
slug: 1
title: Gridsome + Netlifyでかつてない爆速サイトをつくる
description: Jamstack型のサイト作成のために、Gridsomeを用いてサイトを作って運用し始めました。
summary: 静的サイトジェネレータは、ソースファイルから静的HTMLを生成し、サイトを構築するアプローチです。Static Site Generator = SSGとも呼ばれ、有名どころで行くとGatsbyなどのフレームワークがあります
date: 2022-01-25T21:00:00
tags:
 - Gridsome
 - サイトジェネレーター
---

# 以下contents

タグは、gridsome.config.js で route や Typaname を事前に定義しているので、クリックすると自動的にタグページを表示しようとします。※今回は Tag のテンプレートを作っていないため、表示はできません

ブログ投稿機能の完成

全体像としては、config で Post スキーマの定義を行い、トップページの index.vue 内で GraphQL のクエリをかき、記事一覧の表示を行う。コンテンツは Markdown のファイルを読み生成。テンプレートの中の Post.vue ファイルを用意して、各ブログ詳細ページを表示しているという感じです

ソースの構造がフロント思考でもわかりやすく、取り掛かりやすかったです

次は、タグアーカイブページを作ります