特定のカテゴリーのブログを表示
特定のカテゴリーのブログを表示
VuePress のブログ一覧ページをいい感じに変更 - hene.dev では、ブログ一覧ページを作成しました。
今回のブログ一覧ページの変更では、特定のカテゴリーのブログを一覧表示できるようにしました。また、特定のカテゴリーのブログ一覧
と すべてのブログ一覧
ページは同じコンポーネントを使うようにしました。
変更したページ例
ブログ一覧ページ
カテゴリー
ページから、Tag
ページに変更しました。
ブログ一覧を表示するコンポーネント
まず、ブログ(すべてのブログ
or 特定のカテゴリーのブログ
)を表示するコンポーネントを変更しました。
BlogList.vue
ブログ(すべてのブログ
or 特定のカテゴリーのブログ
)を表示するコンポーネントです。
<!-- src/.vuepress/components/BlogList.vue -->
<template lang="pug">
main.blog-list
.content
h1
a.header-anchor(href="#blog" aria-hidden="true") #
| {{ title }}
.blog(v-for="post in posts")
p.blog-date {{ date(post.frontmatter.date) }}
h2.blog-title
a(v-bind:href="post.path") {{ post.title }}
.blog-categories
a.blog-category(v-for="category in post.frontmatter.categories" :href="'../category/' + category + '.html'") {{ category }}
</template>
<script>
export default {
computed: {
isAllPosts() {
return (
this.$page.path === "/blog/" || typeof this.$category === "undefined"
);
},
title() {
return this.isAllPosts
? "Blog"
: `Blog / ${this.$route.meta.categoryName}`;
},
categoryPosts() {
return this.$category.posts
.filter(post => post.regularPath.startsWith("/_posts/blog/"))
.sort(
(x, y) => new Date(y.frontmatter.date) - new Date(x.frontmatter.date)
);
},
allPosts() {
return this.$site.pages
.filter(post => post.regularPath.startsWith("/_posts/blog/"))
.sort(
(x, y) => new Date(y.frontmatter.date) - new Date(x.frontmatter.date)
);
},
posts() {
return this.isAllPosts ? this.allPosts : this.categoryPosts;
}
},
methods: {
date(postDate) {
const date = new Date(postDate);
const yyyy = date.getFullYear();
const MM = ("0" + (date.getMonth() + 1)).slice(-2);
const dd = ("0" + date.getDate()).slice(-2);
return [yyyy, MM, dd].join("/");
}
}
};
</script>
script
computed
、methods
の中で何をしているか詳しく説明します。
computed
isAllPosts()
以下 2 つを比較しています。
this.$page.path
が/blog/
かどうか比較しています。this.$category
がundefined
かどうか比較しています。
isAllPosts() {
return (
this.$page.path === "/blog/" || typeof this.$category === "undefined"
);
},
他の方法
最初、isAllposts()
を以下のように書いていました。
isAllPosts() {
return this.$page.path === "/blog/";
},
npm run build
すると、/category/
ページが残っていてエラーが出たので、
typeof this.$category === "undefined"
を追加することで対応しました。
error Error rendering /category/: false
undefined
TypeError: Cannot read property 'posts' of undefined
at a.categoryPosts (src/.vuepress/components/BlogList.vue:27:28)
at a.categoryPosts (/Users/username/privateworkspace/hene/node_modules/vue/dist/vue.runtime.common.prod.js:6:29311)
at a.posts (src/.vuepress/components/BlogList.vue:41:52)
at a.posts (/Users/username/privateworkspace/hene/node_modules/vue/dist/vue.runtime.common.prod.js:6:29311)
at a.render (src/.vuepress/components/BlogList.vue?f542:1:131)
at a.t._render (/Users/username/privateworkspace/hene/node_modules/vue/dist/vue.runtime.common.prod.js:6:34886)
at /Users/username/privateworkspace/hene/node_modules/vue-server-renderer/build.prod.js:1:70219
at Gi (/Users/username/privateworkspace/hene/node_modules/vue-server-renderer/build.prod.js:1:66783)
at ro (/Users/username/privateworkspace/hene/node_modules/vue-server-renderer/build.prod.js:1:70195)
at eo (/Users/username/privateworkspace/hene/node_modules/vue-server-renderer/build.prod.js:1:69826)
at bt.Qi [as renderNode] (/Users/username/privateworkspace/hene/node_modules/vue-server-renderer/build.prod.js:1:67073)
at bt.next (/Users/username/privateworkspace/hene/node_modules/vue-server-renderer/build.prod.js:1:20498)
at n (/Users/username/privateworkspace/hene/node_modules/vue-server-renderer/build.prod.js:1:18710)
at /Users/username/privateworkspace/hene/node_modules/vue-server-renderer/build.prod.js:1:68184
at Qi (/Users/username/privateworkspace/hene/node_modules/vue-server-renderer/build.prod.js:1:68192)
at /Users/username/privateworkspace/hene/node_modules/vue-server-renderer/build.prod.js:1:70293
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] build: `vuepress build src`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] build script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm ERR! A complete log of this run can be found in:
npm ERR! /Users/username/.npm/_logs/2019-05-25T06_26_27_609Z-debug.log
title()
isAllPosts
を用いて、ブログ一覧ページとカテゴリーページで表示するタイトルを判別しています。
- ブログ一覧ページ:
Blog
- カテゴリーページ:
Blog / カテゴリー名
title() {
return this.isAllPosts
? "Blog"
: `Blog / ${this.$route.meta.categoryName}`;
},
categoryPosts()
カテゴリーページで表示するブログを取得して、日付を降順(新しい日付のものを上)にしています。
categoryPosts() {
return this.$category.posts
.filter(post => post.regularPath.startsWith("/_posts/blog/"))
.sort(
(x, y) => new Date(y.frontmatter.date) - new Date(x.frontmatter.date)
);
},
allPosts()
すべてのブログを取得して、日付を降順(新しい日付のものを上)にしています。
allPosts() {
return this.$site.pages
.filter(post => post.regularPath.startsWith("/_posts/blog/"))
.sort(
(x, y) => new Date(y.frontmatter.date) - new Date(x.frontmatter.date)
);
},
posts()
isAllPosts
を用いて、すべてのブログを表示するかカテゴリーのページを表示するか判別しています。
posts() {
return this.isAllPosts ? this.allPosts : this.categoryPosts;
}
methods
date(postDate)
日付を 2019/05/25
のような形式に変換しています。
date(postDate) {
const date = new Date(postDate);
const yyyy = date.getFullYear();
const MM = ("0" + (date.getMonth() + 1)).slice(-2);
const dd = ("0" + date.getDate()).slice(-2);
return [yyyy, MM, dd].join("/");
}
Markdown ファイルの内容を表示
Content
には、Markdown
ファイルの内容が表示されます。
v-if
、 v-else-if
の条件すべてに当てはまらなかったときは、Blog
や BlogList
、Log
のコンポーネントを表示せずに Markdown
ファイルの内容が表示されます。
今回表示したい BlogList
(すべてのブログ
or 特定のカテゴリーのブログ
を表示するコンポーネント)は、以下のとき表示するようにしました。
- すべてのブログを表示:
$page.regularPath
が/_posts/blog/
で始まるとき - 特定のカテゴリーのブログを表示:
$page.path
が/blog/
のとき
CustomContent.vue
<!-- src/.vuepress/components/CustomContent.vue -->
<template lang="pug">
div
Blog(v-if="$page.regularPath.startsWith('/_posts/blog/')")
BlogList(v-else-if="$page.regularPath.startsWith('/category/') || $page.path === '/blog/'")
Log(v-else-if="$page.regularPath.startsWith('/_posts/log/')")
Content(v-else)
</template>
CustomContent を経由するように変更
通常のページは Markdown
ファイルの内容を Page
-> Content
のように経由して表示しています。
そこで、Page
-> CustomContent
-> Content
のように経由して表示するように変更しました。
Page.vue
<!-- src/.vuepress/theme/components/Page.vue -->
<template lang="pug">
main.page
slot(name="top")
- Content
+ CustomContent
略
ブログ一覧ページの設定
すべてのブログを表示するときの設定です。
src/.vuepress/components/CustomContent.vue
で指定した、 this.$page.path
が /blog/
のときにこのページが表示されます。
設定内容
- サイドバー:
非表示
- タイトル:
blog
- 説明:
ブログ一覧
- パーマリンク:
/blog
blog.md
<!-- src/pages/blog.md -->
---
sidebar: false
title: Blog
description: ブログ一覧
permalink: /blog
---
できなかったこと
カテゴリー一覧ページのサイドバーを非表示にしたかったのですが、わかりませんでした・・