Profile picture

新しい技術や古い技術も気になる優柔不断マン!トキメキ大事に!
旧サイトはこちら!

Gatsbyブログに月別アーカイブを追加

June 29, 2023

この記事は2分ぐらいで読めるっぽいよ。

前提条件

GraphQLのスキーマとして、gatsby-starter-blogをベースとする

コード

コンポーネント作成

src/components下にmonthlyarchives.jsを作成し、以下コピペ

monthlyarchives.js
Copy
import { graphql, useStaticQuery, Link } from "gatsby"
import React from 'react'
import styled from '@emotion/styled'

const MonthlyArchives = () => {

    const Wrapper = styled.div`
  `

    const groupBy = (array, getKey) =>
        Array.from(
            array.reduce((map, cur, idx, src) => {
                const key = getKey(cur, idx, src);
                const list = map.get(key);
                if (list) list.push(cur);
                else map.set(key, [cur]);
                return map;
            }, new Map())
        );


    const data = useStaticQuery(graphql`
  query MonthlyArchiveQuery {
    allMarkdownRemark {
      edges {
        node {
          fields {
            slug
          }
          frontmatter {
            title
            date
          }
        }
      }
    }
  }
  `)

    let groupingData = groupBy(data.allMarkdownRemark.edges.map(item => [item.node.frontmatter.date.substring(0, 7), item.node]), item => item);
    let yearGropuingDara = groupBy(groupingData.map(x => [x[0][0].substring(0, 4), x]), x => x[0]);
    return (
        <Wrapper >
            <center>
            <h4>月別アーカイブ</h4>
            </center>
            <ol style={{ listStyle: `none` , paddingLeft: '1em' }}>
                {yearGropuingDara.map(yearGr => {
                    return (
                        <li>
                            <details>
                                <summary>{yearGr[0]}({yearGr[1].map(x => x[0][1][1]).flat(Infinity).length})</summary>
                                <ol style={{ listStyle: `none` , paddingLeft: '1em'}}>
                                    {groupBy(yearGr[1].map(x => [x[1][0][0], x[1][0][1]]), x => x[0]).map(month => {
                                        return (
                                            <li>
                                                <details>
                                                    <summary>{month[0]}({month[1].map(x => x[1]).flat(Infinity).length})</summary>
                                                    <ol style={{ listStyle: `none` , paddingLeft: '1em'}}>
                                                        {month[1].sort((a,b) => a[1].frontmatter.date - b[1].frontmatter.date).map(days => {
                                                            return (
                                                                <li>
                                                                    <Link to={days[1].fields.slug} itemProp="url">
                                                                        <span>{days[1].frontmatter.title}</span>
                                                                    </Link>
                                                                </li>
                                                            )
                                                        })}
                                                    </ol>
                                                </details>
                                            </li>
                                        )
                                    })}
                                </ol>
                            </details>
                        </li>
                    )
                }
                )
                }
            </ol>
        </Wrapper>
    )
}

export default MonthlyArchives

使用例

あとは任意の場所にコンポーネントを宣言する

hoge.js
Copy
import { graphql, useStaticQuery } from "gatsby"
import React from 'react'
import MonthlyArchives from "./monthlyarchives"
const Hoge = () => {


  return (
    <div >
        <MonthlyArchives />    </div>
  )
}

こんな感じになる↓
2023 06 29 22 56 45

ぶっちゃけクソコードだと思ってます(おい
名前付きタプルとか使えばいいんだろうな〜
とか思いながらめんどくさがって配列地獄になってしまった...
というか!一番驚いたのが、groupBy関数が標準になってない事!
厳密には、最近ようやく標準化されたけど、現状まだSafariしか対応してなさそう!

2023 06 29 22 54 25 ↑きれいな > の字。アスキーアートを感じた
では(^^)ノシ


このポエムを轟かせたいと思ったらシェアやで

© 2024 yukimakura All rights reserved, Built with Gatsby