Skip to content

Commit

Permalink
fix(tags): Fix tag links using slugs and other minor inconsistencies
Browse files Browse the repository at this point in the history
Change the tag link generation to use the tag text instead of it's slug
for the link display - another issue that would be pretty visible with
lowercase slugs.
  • Loading branch information
necauqua committed Jan 18, 2025
1 parent 8cf3e30 commit 39ff322
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 37 deletions.
4 changes: 2 additions & 2 deletions quartz/components/PageList.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { FullSlug, resolveRelative } from "../util/path"
import { FullSlug, resolveRelative, slugTag } from "../util/path"
import { QuartzPluginData } from "../plugins/vfile"
import { Date, getDate } from "./Date"
import { QuartzComponent, QuartzComponentProps } from "./types"
Expand Down Expand Up @@ -61,7 +61,7 @@ export const PageList: QuartzComponent = ({ cfg, fileData, allFiles, limit, sort
<li>
<a
class="internal tag-link"
href={resolveRelative(fileData.slug!, `tags/${tag}` as FullSlug)}
href={resolveRelative(fileData.slug!, `tags/${slugTag(tag)}` as FullSlug)}
>
{tag}
</a>
Expand Down
7 changes: 5 additions & 2 deletions quartz/components/RecentNotes.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { QuartzComponent, QuartzComponentConstructor, QuartzComponentProps } from "./types"
import { FullSlug, SimpleSlug, resolveRelative } from "../util/path"
import { FullSlug, SimpleSlug, resolveRelative, slugTag } from "../util/path"
import { QuartzPluginData } from "../plugins/vfile"
import { byDateAndAlphabetical } from "./PageList"
import style from "./styles/recentNotes.scss"
Expand Down Expand Up @@ -64,7 +64,10 @@ export default ((userOpts?: Partial<Options>) => {
<li>
<a
class="internal tag-link"
href={resolveRelative(fileData.slug!, `tags/${tag}` as FullSlug)}
href={resolveRelative(
fileData.slug!,
`tags/${slugTag(tag)}` as FullSlug,
)}
>
{tag}
</a>
Expand Down
7 changes: 4 additions & 3 deletions quartz/components/pages/TagContent.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { QuartzComponent, QuartzComponentConstructor, QuartzComponentProps } from "../types"
import style from "../styles/listPage.scss"
import { PageList, SortFn } from "../PageList"
import { FullSlug, getAllSegmentPrefixes, simplifySlug } from "../../util/path"
import { FullSlug, getAllSegmentPrefixes, simplifySlug, slugTag } from "../../util/path"
import { QuartzPluginData } from "../../plugins/vfile"
import { Root } from "hast"
import { htmlToJsx } from "../../util/jsx"
Expand Down Expand Up @@ -63,7 +63,8 @@ export default ((opts?: Partial<TagContentOptions>) => {
allFiles: pages,
}

const contentPage = allFiles.filter((file) => file.slug === `tags/${tag}`).at(0)
const tagSlug = slugTag(tag)
const contentPage = allFiles.filter((file) => file.slug === `tags/${tagSlug}`).at(0)

const root = contentPage?.htmlAst
const content =
Expand All @@ -74,7 +75,7 @@ export default ((opts?: Partial<TagContentOptions>) => {
return (
<div>
<h2>
<a class="internal tag-link" href={`../tags/${tag}`}>
<a class="internal tag-link" href={`../tags/${tagSlug}`}>
{tag}
</a>
</h2>
Expand Down
71 changes: 43 additions & 28 deletions quartz/plugins/emitters/tagPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
getAllSegmentPrefixes,
joinSegments,
pathToRoot,
slugTag,
} from "../../util/path"
import { defaultListPageLayout, sharedPageComponents } from "../../../quartz.layout"
import { TagContent } from "../../components"
Expand Down Expand Up @@ -64,7 +65,7 @@ export const TagPage: QuartzEmitterPlugin<Partial<TagPageOptions>> = (userOpts)
for (const tag of tags) {
graph.addEdge(
sourcePath,
joinSegments(ctx.argv.output, "tags", tag + ".html") as FilePath,
joinSegments(ctx.argv.output, "tags", slugTag(tag) + ".html") as FilePath,
)
}
}
Expand All @@ -80,42 +81,56 @@ export const TagPage: QuartzEmitterPlugin<Partial<TagPageOptions>> = (userOpts)
allFiles.flatMap((data) => data.frontmatter?.tags ?? []).flatMap(getAllSegmentPrefixes),
)

// add base tag
tags.add("index")

const tagDescriptions: Record<string, ProcessedContent> = Object.fromEntries(
const tagDescriptions: Map<FullSlug, { tag: string; content: ProcessedContent }> = new Map(
[...tags].map((tag) => {
const title =
tag === "index"
? i18n(cfg.locale).pages.tagContent.tagIndex
: `${i18n(cfg.locale).pages.tagContent.tag}: ${tag}`
return [
tag,
defaultProcessedContent({
slug: joinSegments("tags", tag) as FullSlug,
frontmatter: { title, tags: [] },
}),
]
const title = `${i18n(cfg.locale).pages.tagContent.tag}: ${tag}`
const slug = joinSegments("tags", slugTag(tag)) as FullSlug
const content = defaultProcessedContent({ slug, frontmatter: { title } })
return [slug, { tag, content }]
}),
)

// add base tag
tagDescriptions.set("tags/index" as FullSlug, {
tag: "index",
content: defaultProcessedContent({
slug: "tags/index" as FullSlug,
frontmatter: {
title: i18n(cfg.locale).pages.tagContent.tagIndex,
},
}),
})

let tagFolder: string | undefined

for (const [tree, file] of content) {
const slug = file.data.slug!
if (slug.startsWith("tags/")) {
const tag = slug.slice("tags/".length)
if (tags.has(tag)) {
tagDescriptions[tag] = [tree, file]
if (file.data.frontmatter?.title === tag) {
file.data.frontmatter.title = `${i18n(cfg.locale).pages.tagContent.tag}: ${tag}`
}
}
if (!slug.startsWith("tags/")) {
continue
}
const desc = tagDescriptions.get(slug)
if (!desc) {
continue
}
desc.content = [tree, file]
if (file.data.frontmatter?.title === desc.tag) {
file.data.frontmatter.title = `${i18n(cfg.locale).pages.tagContent.tag}: ${desc.tag}`
}
if (!tagFolder && file.data.relativePath) {
tagFolder = file.data.relativePath.split("/").at(0)
}
}

// this is a hack to make sure our virtual `tags/index` page has the same folder as the other tag pages
// so that the breadcrumbs render consistent capitalization etc
if (tagFolder) {
const path = `${tagFolder}/index.html` as FilePath
tagDescriptions.get("tags/index" as FullSlug)!.content[1].data.relativePath = path
}

for (const tag of tags) {
const slug = joinSegments("tags", tag) as FullSlug
const [tree, file] = tagDescriptions[tag]
const externalResources = pageResources(pathToRoot(slug), file.data, resources)
for (const [slug, desc] of tagDescriptions.entries()) {
const [tree, file] = desc.content
const externalResources = pageResources(pathToRoot(slug as FullSlug), file.data, resources)
const componentData: QuartzComponentProps = {
ctx,
fileData: file.data,
Expand Down
3 changes: 1 addition & 2 deletions quartz/plugins/transformers/ofm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -337,15 +337,14 @@ export const ObsidianFlavoredMarkdown: QuartzTransformerPlugin<Partial<Options>>
return false
}

tag = slugTag(tag)
if (file.data.frontmatter) {
const noteTags = file.data.frontmatter.tags ?? []
file.data.frontmatter.tags = [...new Set([...noteTags, tag])]
}

return {
type: "link",
url: base + `/tags/${tag}`,
url: `${base}/tags/${slugTag(tag)}`,
data: {
hProperties: {
className: ["tag-link"],
Expand Down

0 comments on commit 39ff322

Please sign in to comment.