diff --git a/content/blog/don't-publish.md b/content/blog/don't-publish.md new file mode 100644 index 0000000..0c12f97 --- /dev/null +++ b/content/blog/don't-publish.md @@ -0,0 +1,7 @@ +--- +title: Don’t publish +date: 2025-12-30T11:54:00.000Z +draft: true + +--- +undefined \ No newline at end of file diff --git a/content/blog/example-page.md b/content/blog/example-page.md new file mode 100644 index 0000000..014b3c4 --- /dev/null +++ b/content/blog/example-page.md @@ -0,0 +1,22 @@ +--- +title: Example page +description: Description test +date: 2025-12-30T11:50:00.000Z +draft: false + +--- + +## Test + + +This is an example of a post that I wrote using Notion. This way it’ll be easier to update my blog. + + +More complicated things + +- list +- of +- items + +Here’s a [link](https://patworld.world/) + diff --git a/eleventy.config.js b/eleventy.config.js index aa9685f..8c3623b 100644 --- a/eleventy.config.js +++ b/eleventy.config.js @@ -6,8 +6,73 @@ import { eleventyImageTransformPlugin } from "@11ty/eleventy-img"; import pluginFilters from "./_config/filters.js"; +import * as fs from 'fs'; +import { Client } from '@notionhq/client'; +import { NotionToMarkdown } from 'notion-to-md'; +import slugify from 'slugify'; +import * as YAML from 'yaml'; + /** @param {import("@11ty/eleventy").UserConfig} eleventyConfig */ export default async function(eleventyConfig) { + + eleventyConfig.on("eleventy.beforeConfig", async ({ directories, runMode, outputMode }) => { + const database_id = process.env.NOTION_DATABASE_ID + + if (!database_id || !process.env.NOTION_API_KEY) return + + const notion = new Client({ + auth: env.NOTION_API_KEY + }); + + const { data_sources } = await notion.databases.retrieve({ + database_id, + }); + + const data_source_id = data_sources[0].id + + const { results } = await notion.dataSources.query({ + data_source_id, + }) + + const pageProperties = results.reduce((res, { id, properties }) => ({ + ...res, + [id]: { + title: properties["Name"].title[0]?.plain_text, + description: properties["Description"].rich_text[0]?.plain_text, + date: properties["Last edited time"]?.last_edited_time, + draft: !properties["Live"].checkbox, + } + }), {}) + + const block_ids = results.map(({ id }) => id) + + // passing notion client to the option + const n2m = new NotionToMarkdown({ + notionClient: notion, + }); + + await Promise.all( + block_ids.map(async (block_id) => { + const mdblocks = await n2m.pageToMarkdown(block_id); + const mdString = n2m.toMarkdownString(mdblocks); + + const { title } = pageProperties[block_id]; + + const filename = `${slugify(title.toLowerCase())}.md`; + + const frontmatter = "---\n"+ YAML.stringify(pageProperties[block_id]) + "\n---\n" + + try { + fs.writeFileSync(`content/blog/${filename}`, frontmatter + mdString.parent) + } catch (e) { + console.log(`Writing ${filename} failed: ${e}`) + } + + console.log(`Wrote ${filename} successfully.`) + }) + ) + }) + // Drafts, see also _data/eleventyDataSchema.js eleventyConfig.addPreprocessor("drafts", "*", (data, content) => { if (data.draft) { diff --git a/package-lock.json b/package-lock.json index d274a55..53b26d6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,12 @@ "version": "9.0.0", "license": "MIT", "dependencies": { - "@zachleat/heading-anchors": "^1.0.5" + "@notionhq/client": "^5.6.0", + "@zachleat/heading-anchors": "^1.0.5", + "markdown-it-footnote": "^4.0.0", + "notion-to-md": "^3.1.9", + "slugify": "^1.6.6", + "yaml": "^2.8.2" }, "devDependencies": { "@11ty/eleventy": "^3.1.2", @@ -697,6 +702,14 @@ "url": "https://opencollective.com/libvips" } }, + "node_modules/@notionhq/client": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@notionhq/client/-/client-5.6.0.tgz", + "integrity": "sha512-eA3dO87vQJhFmR59utXH8r0nnulW7C7oTcxfp3bpiiTiv59luCkOkbbALCIa8TzBDdELoRD/zJEIfKcynyFR6Q==", + "engines": { + "node": ">=18" + } + }, "node_modules/@rgrove/parse-xml": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/@rgrove/parse-xml/-/parse-xml-4.2.0.tgz", @@ -1811,6 +1824,11 @@ "markdown-it": "bin/markdown-it.mjs" } }, + "node_modules/markdown-it-footnote": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/markdown-it-footnote/-/markdown-it-footnote-4.0.0.tgz", + "integrity": "sha512-WYJ7urf+khJYl3DqofQpYfEYkZKbmXmwxQV8c8mO/hGIhgZ1wOe7R4HLFNwqx7TjILbnC98fuyeSsin19JdFcQ==" + }, "node_modules/markdown-it/node_modules/entities": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", @@ -1824,6 +1842,18 @@ "url": "https://github.com/fb55/entities?sponsor=1" } }, + "node_modules/markdown-table": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-2.0.0.tgz", + "integrity": "sha512-Ezda85ToJUBhM6WGaG6veasyym+Tbs3cMAw/ZhOPqXiYsr0jgocBV3j3nx+4lk47plLlIqjwuTm/ywVI+zjJ/A==", + "dependencies": { + "repeat-string": "^1.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/maximatch": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/maximatch/-/maximatch-0.1.0.tgz", @@ -1937,6 +1967,25 @@ "dev": true, "license": "MIT" }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, "node_modules/node-retrieve-globals": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/node-retrieve-globals/-/node-retrieve-globals-6.0.1.tgz", @@ -1959,6 +2008,18 @@ "node": ">=0.10.0" } }, + "node_modules/notion-to-md": { + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/notion-to-md/-/notion-to-md-3.1.9.tgz", + "integrity": "sha512-SsYhhigh+jOv06QOiFynOQATPMl96CspWDIL3Q5klzp4eaZ1dYaPI3ELoly80G1K0jf730u3ItvfwskzPKK41g==", + "dependencies": { + "markdown-table": "^2.0.0", + "node-fetch": "2" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/nunjucks": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/nunjucks/-/nunjucks-3.2.4.tgz", @@ -2224,6 +2285,14 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", + "engines": { + "node": ">=0.10" + } + }, "node_modules/section-matter": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/section-matter/-/section-matter-1.0.0.tgz", @@ -2375,7 +2444,6 @@ "version": "1.6.6", "resolved": "https://registry.npmjs.org/slugify/-/slugify-1.6.6.tgz", "integrity": "sha512-h+z7HKHYXj6wJU+AnS/+IH8Uh9fdcX1Lrhg1/VMdf9PwoBQXFcXiAdsy2tSK0P6gKwJLXp02r90ahUCqHk9rrw==", - "dev": true, "license": "MIT", "engines": { "node": ">=8.0.0" @@ -2461,6 +2529,11 @@ "node": ">=0.6" } }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, "node_modules/tslib": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", @@ -2493,6 +2566,20 @@ "dev": true, "license": "MIT" }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -2531,6 +2618,20 @@ } } }, + "node_modules/yaml": { + "version": "2.8.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.2.tgz", + "integrity": "sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14.6" + }, + "funding": { + "url": "https://github.com/sponsors/eemeli" + } + }, "node_modules/zod": { "version": "3.25.67", "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.67.tgz", diff --git a/package.json b/package.json index c3c11b5..52afd19 100644 --- a/package.json +++ b/package.json @@ -47,6 +47,11 @@ "zod-validation-error": "^3.5.2" }, "dependencies": { - "@zachleat/heading-anchors": "^1.0.5" + "@zachleat/heading-anchors": "^1.0.5", + "@notionhq/client": "^5.6.0", + "markdown-it-footnote": "^4.0.0", + "notion-to-md": "^3.1.9", + "slugify": "^1.6.6", + "yaml": "^2.8.2" } }