#18 No-code 之旅 — 读取资料库来实作部落格 ft. Notion SDK

嗨大家~ 像昨天文章里提的,这专案会采用 Notion 来当 CMS (包含资料库),意思是部落格文章的新增编辑删除都会发生在 Notion 里。所以,这专案需要可以读取 Notion database 的资料。今天就是来串 Notion SDK 读取 DB 资料喔!开始之前有些步骤需要完成才能拿到 Notion 的读取权限喔,请大家看这篇

Notion DB

Setup

这专案会用到 Notion SDK,所以需要安装 SDK,不过如果你们想要用 Notion API 也可以喔!:

npm install @notionhq/client
# or
yarn add @notionhq/client

装完之後我们需要初始化 Client:

import { Client } from "@notionhq/client";

// 初始化 Client
const notion = new Client({
  auth: process.env.NOTION_TOKEN, // Notion 的 secret token
});

取得 Database 资料

因为我们要做的是部落格,所以这次不是用 Notion Page,而是用 Notion Database。Database 里有很多 Pages,所以 Database 就是我们的部落格资料库,然後 Page 是我们每篇部落格文章的内容。Notion API 有提供很多 endpoints,其中一个是取得该 database 里的 pages:

export const queryDatabase = async (params) => {
  const databaseId = process.env.NOTION_DATABASE_ID;

  if (!databaseId) {
    throw new Error("Required: Notion database ID.");
  }

  // 读取资料库里的 pages
  const response = await notion.databases.query({
    database_id: databaseId,
    filter: params?.filter,
    sorts: params?.sorts,
  });

  return response;
};

在这里用的是 notion.databases.query 而不是 notion.databases.retrieveretrieve 这 API 是来读取该 database 的 properties,而 query 是来读取 database 里的 pages,我们也可以加 filtersorts 做文章的过滤和排序。

{
  "object": "list",
  "results": [
    {
      "object": "page",
      "id": "2e01e904-febd-43a0-ad02-8eedb903a82c",
      "created_time": "2020-03-17T19:10:04.968Z",
      "last_edited_time": "2020-03-17T21:49:37.913Z",
      "parent": {
        "type": "database_id",
        "database_id": "897e5a76-ae52-4b48-9fdf-e71f5945d1af"
      },
      "archived": false,
      "url": "https://www.notion.so/2e01e904febd43a0ad028eedb903a82c",
      "properties": {
        "Recipes": {
          "id": "Ai`L",
          "type": "relation",
          "relation": [
            {
              "id": "796659b4-a5d9-4c64-a539-06ac5292779e"
            },
          ]
        },
        ...
      }
    }
  ],
  "has_more": false,
  "next_cursor": null
}

response 会包含 results 为 list of pages,还有 has_morenext_cursor 做 pagination 用的~

部落格路径

因为我们使用 Next.js,所以做部落格的话,应该要用 Next.js 的 dynamic routing!於是我们需要写 getStaticPaths

export const getStaticPaths = async () => {
  const blogs = await queryDatabase();
  const paths = blogs.results.map((b) => ({
    params: { id: b.id }, // Notion 的 Page ID 当路径的 dynamic path
  }));

  return { paths, fallback: "blocking" };
};

把上面这段 code 放在 pages/blogs/[id].js 里面,这样我们会匹配到 /blogs/[id] 的动态路径~

小结

今天才读取资料库的文章,还没把每篇文章的内容取出来,而抓完资料还要做多处理喔!现在还蛮流行把 Notion 当成 CMS 或是资料库,把文章都写在 Notion 里,然後再用 API 取这些资料去显示。今天的小功能还差很多很多,尤其是资料处理方面!XD 我发现第三方 library 大部分都不是用 Notion SDK 读取资料,所以资料格式又不一样Q 感觉要自己写 Notion renderer 了 :o

大家想要看看之前的网站可以看这里,或是直接到首页~ 有任何问题可以问我,或是也可以讨论未来要开发的 No-code 专案喔。

祝大家明天上班上课愉快!

晚安 <3

看更多


<<:  Day18 - 物理模拟篇 - 弹力、引力与磁力III - 成为Canvas Ninja ~ 理解2D渲染的精髓

>>:  【在厨房想30天的演算法】Day 18 演算法 : 搜寻 search II 指数搜寻、内插搜寻

【day21】创建对象列表(下)

昨天我们已经按照时间去新增我们的资料了,也得到列表啦,那麽我们今天就要来建立点击事件,因为如果只有...

[DAY 20]用bot打出色色柴犬counter牌(更新句子相似度判断)

原本以为色色柴犬counter功能不会再更新了 直到discord上来了这样一段 哇他们这样玩还没触...

Day 30 | 很像 Vue 的 AlpineJS(五): 与 Livewire 共享资料

前面三篇关於 AlpineJs 的文章都是在控制前端的页面而跟 Livewire 比较无关,那今天就...

学习资源

分享一些我很喜欢的学习资源 有看到新的好资源会陆续更新 Computer Science 计算机概论...

LeetCode 解题 Day 03

587. Erect the Fence https://leetcode.com/problems...