Nuxt Content × SSG で作る静的ブログ。4:カテゴリーとタグ機能
技術スタック JavascriptNuxt.js

Nuxt Content × SSG で作る静的ブログ。4:カテゴリーとタグ機能

2021.05.09 2021.05.09

こんにちはjunです。前回の記事は詳細ページの実装と静的書き出しを行いました。今回の記事では カテゴリーとタグ機能 について解説します。

カテゴリーとタグについて

まず最初にカテゴリーとタグ機能について念のため定義しておきます。基本的にはwordpressのものと概念は似ています。カテゴリーは基本的に記事に一つだけ設定して大まかな分類を行います。タグは記事に対して複数個設定できます。

機能としては上記の通りですが、記事がどんなコンテンツであるか整理されてリスト化されることでサイト訪問者がコンテンツを探しやすくなります。実際私のサイトもわかりやすくありませんか笑?

そのためブログを作るのならば、このカテゴリーとタグの機能はかなり重要です。それでは早速解説します。

各記事にカテゴリー・タグを設定する

Nuxt Contentはマークダウンで原稿を作成します。マークダウン上部には以下のような記事のメタデータを記述します。

---
title: Nuxt Content × SSG で作る静的ブログ。4:カテゴリーとタグ機能
description: Nuxt Content × SSG で作る静的ブログ。カテゴリーとタグ機能
category: [devstack]
tag: [js,nuxt]
series: nuxt-content-blog
seriesTitle: Nuxt Content × SSG で作る静的ブログ。
index: 4
publish: true
thumbnail: logo-dark.jpg
---

ここで設定する値は基本的に自由につけることができます。そしてこの例のcategorytagsに注目してみてください。各記事のカテゴリーとタグはここで定義されています。そして配列形式で設定します。このようにメタデータに配列で設定することで記事のカテゴリー・タグを配列で取得できます。配列なので複数個設定することができます。

この時気をつけたいのが、例えば[開発スタック,メモ]と日本語(ラベル)を入力するのでなく、プログラム的なキー・スラグで入力した方が良いです。理由は後述します。

カテゴリー、タグ設定ファイルを作成する

プロジェクトルートにtaxonomy.jsというようなカテゴリー、タグを管理するファイルを作成します。中身は以下のようになっています。

taxonomy.js
module.exports = {
    category:[
        {text:'技術スタック',slug:'devstack'},
        {text:'プログラミング学習',slug:'learning'},
        {text:'メモ',slug:'ministack'},
    ],
    tags:[
        {text:'HTML',slug:'html'},
        {text:'CSS',slug:'css'},
        {text:'Javascript',slug:'js'},
        {text:'jquery',slug:'jquery'},
        {text:'Vue.js',slug:'vue'},
        {text:'Nuxt.js',slug:'nuxt'},
        {text:'webpack',slug:'webpack'},
        {text:'PHP',slug:'php'},
        {text:'Laravel',slug:'laravel'},
        {text:'Python',slug:'python'},
        {text:'Django',slug:'django'},
        {text:'HeadlessCMS',slug:'headlesscms'},
        {text:'wordpress',slug:'wordpress'},
        {text:'concrete5',slug:'concrete5'},
        {text:'ZOOM',slug:'zoom'},
        {text:'インフラ',slug:'infrastructure'},
        {text:'ネットワーク',slug:'network'},
        {text:'Docker',slug:'docker'},
    ]
}

module export としているのは静的書き出しの際にこのファイルを使用するからです。そしてNuxtで制御しやすいようにStoreに入れておきます。このように管理する時、キー(スラグ)とラベル(カテゴリ名)を分けてオブジェクトにしておいた方が良いです。キーを使用することで重複を避けたり、そのままURLの一部として使用することも可能です。

store/index.js
import taxonomy from '../taxonomy';
export const state = () => ({
    category:[
        ...taxonomy.category
    ],
    tags:[
        ...taxonomy.tags
    ]
  })

export const getters ={
    getTagTextBySlug(state){
        return (slug)=>{
            const idx = state.tags.findIndex(tag=>{
                return tag.slug === slug;
            })
            return (idx > -1)?state.tags[idx].text:undefined;
        }
    },
    getCategoryTextBySlug(state){
        return (slug)=>{
            const idx = state.category.findIndex(tag=>{
                return tag.slug === slug;
            })
            return (idx > -1)?state.category[idx].text:undefined;
        }
    }
}

カテゴリー、タグはサイドメニューにあるようにバッチで表示しています。その時は以下のようなv-forのコンポーネントで表示しています。

<div class="p-badge-container">
    <nuxt-link class="c-tag-badge" v-for="(t,index) in $store.state.category" :key="'tag-'+index" :to="'/tag/'+t">
        <span>{{t.text}}</span>
    </nuxt-link>
</div>

カテゴリー、タグを管理、使用、設定ができるようになりましたので、次はカテゴリー・タグ一覧を作成していきましょう。

カテゴリー、タグ一覧ページのためのpages構成

カテゴリーとタグ一覧ページの構成は互いに同じなので、タグ一覧だけ解説します。

タグ一覧はそのタグのバッチをクリックすると閲覧できるページです。そのタグがついた記事を全て見ることが可能です。そして/tag/{tag_key}というURLでルーティングされています。

そのようなルーティングを行うために以下のようにpages/を設定します。

pages
└── tag
    └── _slug
        ├── index.vue
        └── page
            └── _id.vue

こうすうることで{tag_key}という動的ルートに対応できます。またページングのためのページコンポーネントも作成しておきます。

特定のタグを持つ投稿のみを取得する。

それでは/tag/_slug/index.vueの中身を見ていきましょう。

pages/tag/_slug/index.vue
export default {
    async asyncData({ store,$content, params }) {
        const count = await $content({ deep: true }).only('title').where({ tag:{ $contains:params.slug}}).fetch();

        const content = await $content({ deep: true })
        .only(['title','description','thumbnail','path','category','tag','updatedAt','series','index'])
        .sortBy('createdAt', 'desc')
        .where({tag:{ $contains:params.slug}}) // ここ
        .skip(0).limit(store.state.indexPerPage)
        .fetch();

        return {
`        content,
        count:count.length`
        }
    },
}

まずしっかりと記事のデータとして'tag'を指定して、.where({tag:{ $contains:params.slug}})を使用します。params.slugからURLのスラグを取得して、それが配列内に含まれているかを確かめています。その条件に合致した投稿、すなわち目的のタグを持っている記事のみを取得することができます。

後は一覧ページの実装で説明した通りにテンプレートを記述するなり、ページングを実装すれば完了です。

静的書き出しの時はどうなるのか

このカテゴリーのルートはNuxtが知らないので、nuxt.config.jsで追加ルートとして記述しておく必要があります。ただし、私のサイトのようにサイドメニューにずっとリンクがある場合はとくに対策はしなくてもいいです。Nuxtの静的書き出しはnuxt-linkを辿ってルートを解決しているそうで、自動的にタグ・カテゴリーのルートを書き出してくれました。なのでnuxt-linkでタグのリンクを貼って、pages/ の構成が正しければ特に心配ありません。

以上でカテゴリー。タグ機能を実装

前回までの記事詳細→一覧の作成と似ていましたが、

  • 記事に新しいメタデータを設定
  • where()で特定のタグ・カテゴリーを取得する
  • store・外部ファイルで管理する

という点で少し違っていました。今回はカテゴリー・タグといったものですが使い方によってはいろんな分類方法があると思います。ぜひチャレンジしてみてください。次回は最後で、ブログとしてデプロイする前に設定すべきこと、アナリティクスやアドセンスの貼り方について解説します。

Copyright © 2021 jun. All rights reserved.