ホームへ

Gastby-Starter-Lumenにカテゴリーリストを追加する

Gatsby-Starter-Lumenはmatejlatin/Gutenbergにインスパイアされているということで、シンプルでテキストそのものが読みやすいようなデザインになっている。

シンプルを突き詰めているため、一般的なブログサービスにデフォルトで装備されている機能がないケースがある。 例えば、サイドバーのカテゴリーリストとか月別アーカイブなどである。

シンプルを目指しているものに何やかんや色々付け足すのはどうかとも思うが、最低限必要な機能だけは追加しておきたい。 そこで、今回はサイドバーにカテゴリーリストを追加していく。

まず、最初にgastby-starter-lumenのディレクトリ構成を確認しておく。

└── src
    ├── assets
    │   ├── fonts
    │   │   └── fontello-771c82e0
    │   │       ├── css
    │   │       └── font
    │   └── scss
    │       ├── base
    │       ├── mixins
    │       └── pages
    ├── components
    │   ├── CategoryTemplateDetails
    │   ├── Disqus
    │   ├── Links
    │   ├── Menu
    │   ├── PageTemplateDetails
    │   ├── Post
    │   ├── PostTemplateDetails
    │   ├── Sidebar
    │   └── TagTemplateDetails
    ├── layouts
    ├── pages
    │   ├── articles
    │   │   ├── 2016-01-09---Perfecting-the-Art-of-Perfection
    │   │   ├── 2016-01-12---The-Origins-of-Social-Stationery-Lettering
    │   │   ├── 2016-02-02---A-Brief-History-of-Typography
    │   │   ├── 2017-18-08---The-Birth-of-Movable-Type
    │   │   └── 2017-19-08---Humane-Typography-in-the-Digital-Age
    │   └── pages
    │       ├── 2015-05-01---about
    │       └── 2015-05-01---contact
    └── templates

コンポーネントはcomponentsディレクトリ配下に置かれているので、これから作るカテゴリーリストのコンポーネントもそちらに追加する。

mkdir src/components/CategoriesInSidebar/
cd src/components/CategoriesInSidebar/
emacs -nw index.jsx style.scss

次にCategoriesInSidebar/index.jsxを書いていく。このようなコンポーネントになった。

import React from 'react';
import { navigateTo } from 'gatsby-link';
import kebabCase from 'lodash/kebabCase'
import './style.scss';

class CategoriesInSidebar extends React.Component {
  render() {
    const categories = this.props.data;

    return (
      <div className="categories-in-sidebar">
        <p className="categories-in-sidebar__title">
          カテゴリー
        </p>
        <ul className="categories-in-sidebar__list">
          {Object.keys(categories).map(category => (
            <li className="categories-in-sidebar__list-item">
              <a
                onClick={ () => navigateTo(`/categories/${kebabCase(category)}/`)}
                className="categories-in-sidebar__list-item-link"
                >
                {`${category} (${categories[category]})`}
              </a>
            </li>
          ))
          }
        </ul>
      </div>
    );
  }
}

export default CategoriesInSidebar;

カテゴリ名がkeyで記事数がvalueである連想配列であるcategoriesは、あらかじめ親コンポーネントであるSidebarの処理の中で作っておき、それを子のCategoriesInSidebarにpropsとして受け渡している。

Sidebar内では次のようにしてcategoriesを作成する。

// lodash使う
import uniq from 'lodash/uniq'

// もっと良いやり方あるか
let categories = {};
const categories_list  = this.props.data.allCategoryNames.edges.map((edge) => {
  return (edge.node.frontmatter.category)
})
uniq(categories_list).forEach(category => {
  categories[category] = categories_list.filter(item => item === category).length;
});

// categories ==> {Javascript: 2, Docker: 1, Python: 1}

// 以下のように受け渡す
<CategoriesInSidebar data={categories}/>

こんな感じでカテゴリーリストを追加することができた。
次は月別アーカイブを実装したい。

2018/06/29 13:48:15に更新

カプセルで書く技術ログ
Capsule-Man on Github