58 - garden-astro - use hashtags
Livestream
Previously I add support for tags in this format
tags:
- Astro
- Digital Garden
- 100DaysOfCode
However it is hard to search existing tags in Obsidian, I’ll change the format to use hashtags instead like this. Upon typing #
in Obsidian will show tags autocomplete menu
tags:
- #Astro
- #Digital-Garden
- #100DaysOfCode
But in yaml #
is a comment keyword so that it will be [null, null, null]
in Astro. I have to strip all the #
so that the tags can appear on the website. I tried parsing this frontmatter with js-yaml
but also get null
so I have to use RegEx to match and replace them. This is the resulting code.
import fs from "node:fs"
import { remark } from "remark"
import { visit } from "unist-util-visit"
import remarkFrontmatter from "remark-frontmatter"
export const stripHashFromTags = (filePath: string) => {
const markdown = fs.readFileSync(filePath, "utf-8")
const processor = remark()
.use(remarkFrontmatter)
.use(() => (tree, file) => {
visit(tree, "root", (node) => {
visit(node, "yaml", (yamlNode) => {
const frontmatter = yamlNode.value.replace(
/tags:\n((\s*-\s+)?#.+\n)+/g,
(match) => {
return match.replace(/#.+/g, (tag) => tag.slice(1))
}
)
yamlNode.value = frontmatter
})
})
})
const result = processor.processSync(markdown)
fs.writeFileSync(filePath, String(result), {
encoding: "utf-8",
})
}
It will now display on Astro site since #
is removed.
Disallow whitespaces in tags
Since we’re using hashtags as tags in Obsidian, we should not have spaces in the tags like #Digital Garden
should not be allowed.
Add zod
schema with refine
to scan for whitespaces within tags array.
const secondBrain = defineCollection({
schema: z.object({
...,
tags: z
.array(
z
.string()
.refine(
(tag) => !/\s/.test(tag), // returns false when tag has spaces
(tag) => ({
message: `Tag "${tag}" cannot include whitespaces`,
})
)
.or(z.null())
)
})
})
Astro site will now raise errors if any tags are including spaces.