読んだ本をこのサイト(Notion Blog)で公開するようにした(少し実装の話)

📆November 22, 2020🔖 NotionNotion Blog

🐈 「(少しマニアックな)Notion の使い方まとめ」という note マガジンでも、毎週1本 Notion の使い方に関する記事を発信をしています。 もしよければそちらも覗いてみてください。

表題の通りですが、僕が読んだ本をこのサイトで公開するようにしました。こちらのページで見れます。

2021/01/08 時点での見た目はこんな感じ
2021/01/08 時点での見た目はこんな感じ

半年ほど前から読んだ本は Notion のデータベース機能でストックするようにしています。Notion のページと、ブログのページを同期するようにしてあって、Notion 側に本を追加すると、このサイトにも本が追加されるというような仕組みを実装しました。

2021/01/08 時点での Notion の本棚ページ
2021/01/08 時点での Notion の本棚ページ

以下、実装の話です。

型安全に実装する

Notion 側に付与してあるプロパティを Notion Blog 内で型安全に使用できるように、以下のような Book 型を作成しています。Notion 側でプロパティを追加した場合は、Notion Blog 内でもプロパティを追加します。

export interface Book {
  id: string // '2d40eeef-88d5-47f3-911d-3f31fa6ad11f'
  comment: string // コメント
  created: string //
  amazonUrl: string | null // https://amzn.to/2JEYunN
  blogUrl: string | null
  title: string // タイトル
  Slug: string // '-1'
  preview: Array<any>
  published: 'Yes' | 'No'
  Name: string // 波よ聞いてくれ
  status: string | null // '2020/09', '購入済み'
  evaluation: string | null
}

データベースの情報の取得

情報の取得は、getStaticProps 内で行い、ISR が効くようにしてあります。Notion 側からの情報の取得は getBookIndex 関数で行っており、これは Notion Blog にデフォルトで用意してある関数です(命名のみ変更済)

取得した情報を少し加工(ソートやフィルタリング)して、props に詰めて返しています。これで画面に描画することができるようになります。

export async function getStaticProps() {
  const bookTable: { number: Book } = await getBookIndex(normalizeId(ID))

  const books: Book[] = Object.keys(bookTable)
    .map(_ => bookTable[_])
    .filter((_: Book) => _.published === 'Yes')

  books.sort((a, b) => {
    if (b.created < a.created) {
      return -1
    }
    if (b.created > a.created) {
      return 1
    }

    return 0
  })

  const props: Props = { books }

  return {
    props,
    revalidate: 60,
  }
}

画面では受け取った props から books オブジェクトを取り出し、愚直にループを回して描画しています。(特に解説することはナシ)

気になった方はぜひ実装してみてください。分からんという方は Twitter でご連絡くださいませ。(DM 開放しています)


読んだ本に限らず、Notion で自分のライフログを残しておくと、後から見返すことができてオススメです。みなさんもぜひ真似してみてください。