mirror of
https://github.com/jackyzha0/quartz.git
synced 2025-12-19 19:04:06 -06:00
first draft at unlisted files
This commit is contained in:
parent
b4805a1031
commit
d446ee1f7d
@ -18,6 +18,7 @@ const config: QuartzConfig = {
|
|||||||
locale: "en-US",
|
locale: "en-US",
|
||||||
baseUrl: "quartz.jzhao.xyz",
|
baseUrl: "quartz.jzhao.xyz",
|
||||||
ignorePatterns: ["private", "templates", ".obsidian"],
|
ignorePatterns: ["private", "templates", ".obsidian"],
|
||||||
|
unlistedPatterns: [],
|
||||||
defaultDateType: "modified",
|
defaultDateType: "modified",
|
||||||
theme: {
|
theme: {
|
||||||
fontOrigin: "googleFonts",
|
fontOrigin: "googleFonts",
|
||||||
|
|||||||
@ -62,6 +62,8 @@ export interface GlobalConfiguration {
|
|||||||
analytics: Analytics
|
analytics: Analytics
|
||||||
/** Glob patterns to not search */
|
/** Glob patterns to not search */
|
||||||
ignorePatterns: string[]
|
ignorePatterns: string[]
|
||||||
|
/** Glob patterns to mark files as unlisted (hidden from listings but still accessible via direct link) */
|
||||||
|
unlistedPatterns?: string[]
|
||||||
/** Whether to use created, modified, or published as the default type of date */
|
/** Whether to use created, modified, or published as the default type of date */
|
||||||
defaultDateType: ValidDateType
|
defaultDateType: ValidDateType
|
||||||
/** Base URL to use for CNAME files, sitemaps, and RSS feeds that require an absolute URL.
|
/** Base URL to use for CNAME files, sitemaps, and RSS feeds that require an absolute URL.
|
||||||
|
|||||||
@ -50,7 +50,7 @@ export default ((opts?: Partial<BreadcrumbOptions>) => {
|
|||||||
displayClass,
|
displayClass,
|
||||||
ctx,
|
ctx,
|
||||||
}: QuartzComponentProps) => {
|
}: QuartzComponentProps) => {
|
||||||
const trie = (ctx.trie ??= trieFromAllFiles(allFiles))
|
const trie = (ctx.trie ??= trieFromAllFiles(allFiles, ctx.cfg))
|
||||||
const slugParts = fileData.slug!.split("/")
|
const slugParts = fileData.slug!.split("/")
|
||||||
const pathNodes = trie.ancestryChain(slugParts)
|
const pathNodes = trie.ancestryChain(slugParts)
|
||||||
|
|
||||||
|
|||||||
@ -30,7 +30,7 @@ export default ((opts?: Partial<FolderContentOptions>) => {
|
|||||||
const FolderContent: QuartzComponent = (props: QuartzComponentProps) => {
|
const FolderContent: QuartzComponent = (props: QuartzComponentProps) => {
|
||||||
const { tree, fileData, allFiles, cfg } = props
|
const { tree, fileData, allFiles, cfg } = props
|
||||||
|
|
||||||
const trie = (props.ctx.trie ??= trieFromAllFiles(allFiles))
|
const trie = (props.ctx.trie ??= trieFromAllFiles(allFiles, props.ctx.cfg))
|
||||||
const folder = trie.findNode(fileData.slug!.split("/"))
|
const folder = trie.findNode(fileData.slug!.split("/"))
|
||||||
if (!folder) {
|
if (!folder) {
|
||||||
return null
|
return null
|
||||||
|
|||||||
@ -7,6 +7,7 @@ import { QuartzEmitterPlugin } from "../types"
|
|||||||
import { toHtml } from "hast-util-to-html"
|
import { toHtml } from "hast-util-to-html"
|
||||||
import { write } from "./helpers"
|
import { write } from "./helpers"
|
||||||
import { i18n } from "../../i18n"
|
import { i18n } from "../../i18n"
|
||||||
|
import { isUnlisted } from "../filters/unlisted"
|
||||||
|
|
||||||
export type ContentIndexMap = Map<FullSlug, ContentDetails>
|
export type ContentIndexMap = Map<FullSlug, ContentDetails>
|
||||||
export type ContentDetails = {
|
export type ContentDetails = {
|
||||||
@ -102,6 +103,11 @@ export const ContentIndex: QuartzEmitterPlugin<Partial<Options>> = (opts) => {
|
|||||||
for (const [tree, file] of content) {
|
for (const [tree, file] of content) {
|
||||||
const slug = file.data.slug!
|
const slug = file.data.slug!
|
||||||
const date = getDate(ctx.cfg.configuration, file.data) ?? new Date()
|
const date = getDate(ctx.cfg.configuration, file.data) ?? new Date()
|
||||||
|
|
||||||
|
if(isUnlisted(file.data, cfg)) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
if (opts?.includeEmptyFiles || (file.data.text && file.data.text !== "")) {
|
if (opts?.includeEmptyFiles || (file.data.text && file.data.text !== "")) {
|
||||||
linkIndex.set(slug, {
|
linkIndex.set(slug, {
|
||||||
slug,
|
slug,
|
||||||
|
|||||||
@ -14,6 +14,7 @@ import { BuildCtx } from "../../util/ctx"
|
|||||||
import { Node } from "unist"
|
import { Node } from "unist"
|
||||||
import { StaticResources } from "../../util/resources"
|
import { StaticResources } from "../../util/resources"
|
||||||
import { QuartzPluginData } from "../vfile"
|
import { QuartzPluginData } from "../vfile"
|
||||||
|
import { isUnlisted } from "../filters/unlisted"
|
||||||
|
|
||||||
async function processContent(
|
async function processContent(
|
||||||
ctx: BuildCtx,
|
ctx: BuildCtx,
|
||||||
@ -74,7 +75,7 @@ export const ContentPage: QuartzEmitterPlugin<Partial<FullPageLayout>> = (userOp
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
async *emit(ctx, content, resources) {
|
async *emit(ctx, content, resources) {
|
||||||
const allFiles = content.map((c) => c[1].data)
|
const allFiles = content.map((c) => c[1].data).filter(f => !isUnlisted(f, ctx.cfg.configuration))
|
||||||
let containsIndex = false
|
let containsIndex = false
|
||||||
|
|
||||||
for (const [tree, file] of content) {
|
for (const [tree, file] of content) {
|
||||||
@ -98,7 +99,7 @@ export const ContentPage: QuartzEmitterPlugin<Partial<FullPageLayout>> = (userOp
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
async *partialEmit(ctx, content, resources, changeEvents) {
|
async *partialEmit(ctx, content, resources, changeEvents) {
|
||||||
const allFiles = content.map((c) => c[1].data)
|
const allFiles = content.map((c) => c[1].data).filter(f => !isUnlisted(f, ctx.cfg.configuration))
|
||||||
|
|
||||||
// find all slugs that changed or were added
|
// find all slugs that changed or were added
|
||||||
const changedSlugs = new Set<string>()
|
const changedSlugs = new Set<string>()
|
||||||
|
|||||||
@ -20,6 +20,7 @@ import { write } from "./helpers"
|
|||||||
import { i18n, TRANSLATIONS } from "../../i18n"
|
import { i18n, TRANSLATIONS } from "../../i18n"
|
||||||
import { BuildCtx } from "../../util/ctx"
|
import { BuildCtx } from "../../util/ctx"
|
||||||
import { StaticResources } from "../../util/resources"
|
import { StaticResources } from "../../util/resources"
|
||||||
|
import { isUnlisted } from "../filters/unlisted"
|
||||||
interface FolderPageOptions extends FullPageLayout {
|
interface FolderPageOptions extends FullPageLayout {
|
||||||
sort?: (f1: QuartzPluginData, f2: QuartzPluginData) => number
|
sort?: (f1: QuartzPluginData, f2: QuartzPluginData) => number
|
||||||
}
|
}
|
||||||
@ -129,7 +130,7 @@ export const FolderPage: QuartzEmitterPlugin<Partial<FolderPageOptions>> = (user
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
async *emit(ctx, content, resources) {
|
async *emit(ctx, content, resources) {
|
||||||
const allFiles = content.map((c) => c[1].data)
|
const allFiles = content.map((c) => c[1].data).filter(f => !isUnlisted(f, ctx.cfg.configuration))
|
||||||
const cfg = ctx.cfg.configuration
|
const cfg = ctx.cfg.configuration
|
||||||
|
|
||||||
const folders: Set<SimpleSlug> = new Set(
|
const folders: Set<SimpleSlug> = new Set(
|
||||||
@ -146,7 +147,7 @@ export const FolderPage: QuartzEmitterPlugin<Partial<FolderPageOptions>> = (user
|
|||||||
yield* processFolderInfo(ctx, folderInfo, allFiles, opts, resources)
|
yield* processFolderInfo(ctx, folderInfo, allFiles, opts, resources)
|
||||||
},
|
},
|
||||||
async *partialEmit(ctx, content, resources, changeEvents) {
|
async *partialEmit(ctx, content, resources, changeEvents) {
|
||||||
const allFiles = content.map((c) => c[1].data)
|
const allFiles = content.map((c) => c[1].data).filter(f => !isUnlisted(f, ctx.cfg.configuration))
|
||||||
const cfg = ctx.cfg.configuration
|
const cfg = ctx.cfg.configuration
|
||||||
|
|
||||||
// Find all folders that need to be updated based on changed files
|
// Find all folders that need to be updated based on changed files
|
||||||
|
|||||||
@ -12,6 +12,7 @@ import { write } from "./helpers"
|
|||||||
import { i18n, TRANSLATIONS } from "../../i18n"
|
import { i18n, TRANSLATIONS } from "../../i18n"
|
||||||
import { BuildCtx } from "../../util/ctx"
|
import { BuildCtx } from "../../util/ctx"
|
||||||
import { StaticResources } from "../../util/resources"
|
import { StaticResources } from "../../util/resources"
|
||||||
|
import { isUnlisted } from "../filters/unlisted"
|
||||||
|
|
||||||
interface TagPageOptions extends FullPageLayout {
|
interface TagPageOptions extends FullPageLayout {
|
||||||
sort?: (f1: QuartzPluginData, f2: QuartzPluginData) => number
|
sort?: (f1: QuartzPluginData, f2: QuartzPluginData) => number
|
||||||
@ -122,7 +123,7 @@ export const TagPage: QuartzEmitterPlugin<Partial<TagPageOptions>> = (userOpts)
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
async *emit(ctx, content, resources) {
|
async *emit(ctx, content, resources) {
|
||||||
const allFiles = content.map((c) => c[1].data)
|
const allFiles = content.map((c) => c[1].data).filter(f => !isUnlisted(f, ctx.cfg.configuration))
|
||||||
const cfg = ctx.cfg.configuration
|
const cfg = ctx.cfg.configuration
|
||||||
const [tags, tagDescriptions] = computeTagInfo(allFiles, content, cfg.locale)
|
const [tags, tagDescriptions] = computeTagInfo(allFiles, content, cfg.locale)
|
||||||
|
|
||||||
@ -131,7 +132,7 @@ export const TagPage: QuartzEmitterPlugin<Partial<TagPageOptions>> = (userOpts)
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
async *partialEmit(ctx, content, resources, changeEvents) {
|
async *partialEmit(ctx, content, resources, changeEvents) {
|
||||||
const allFiles = content.map((c) => c[1].data)
|
const allFiles = content.map((c) => c[1].data).filter(f => !isUnlisted(f, ctx.cfg.configuration))
|
||||||
const cfg = ctx.cfg.configuration
|
const cfg = ctx.cfg.configuration
|
||||||
|
|
||||||
// Find all tags that need to be updated based on changed files
|
// Find all tags that need to be updated based on changed files
|
||||||
|
|||||||
27
quartz/plugins/filters/unlisted.ts
Normal file
27
quartz/plugins/filters/unlisted.ts
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import { minimatch } from "minimatch"
|
||||||
|
import { QuartzPluginData } from "../vfile"
|
||||||
|
import { GlobalConfiguration } from "../../cfg"
|
||||||
|
|
||||||
|
export function isUnlisted(
|
||||||
|
fileData: QuartzPluginData,
|
||||||
|
cfg: GlobalConfiguration,
|
||||||
|
unlistedPatterns?: string[]
|
||||||
|
): boolean {
|
||||||
|
const unlistedFlag: boolean =
|
||||||
|
fileData?.frontmatter?.unlisted === true ||
|
||||||
|
fileData?.frontmatter?.unlisted === "true"
|
||||||
|
|
||||||
|
if (unlistedFlag) return true
|
||||||
|
|
||||||
|
const patterns = unlistedPatterns ?? cfg.unlistedPatterns
|
||||||
|
if (patterns && patterns.length > 0 && fileData.slug) {
|
||||||
|
const slug = fileData.slug as string
|
||||||
|
for (const pattern of patterns) {
|
||||||
|
if (minimatch(slug, pattern)) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
@ -146,6 +146,7 @@ declare module "vfile" {
|
|||||||
socialDescription: string
|
socialDescription: string
|
||||||
publish: boolean | string
|
publish: boolean | string
|
||||||
draft: boolean | string
|
draft: boolean | string
|
||||||
|
unlisted: boolean | string
|
||||||
lang: string
|
lang: string
|
||||||
enableToc: string
|
enableToc: string
|
||||||
cssclasses: string[]
|
cssclasses: string[]
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import { QuartzConfig } from "../cfg"
|
import { QuartzConfig } from "../cfg"
|
||||||
|
import { isUnlisted } from "../plugins/filters/unlisted"
|
||||||
import { QuartzPluginData } from "../plugins/vfile"
|
import { QuartzPluginData } from "../plugins/vfile"
|
||||||
import { FileTrieNode } from "./fileTrie"
|
import { FileTrieNode } from "./fileTrie"
|
||||||
import { FilePath, FullSlug } from "./path"
|
import { FilePath, FullSlug } from "./path"
|
||||||
@ -31,10 +32,16 @@ export interface BuildCtx {
|
|||||||
incremental: boolean
|
incremental: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export function trieFromAllFiles(allFiles: QuartzPluginData[]): FileTrieNode<BuildTimeTrieData> {
|
export function trieFromAllFiles(
|
||||||
|
allFiles: QuartzPluginData[],
|
||||||
|
cfg?: QuartzConfig
|
||||||
|
): FileTrieNode<BuildTimeTrieData> {
|
||||||
const trie = new FileTrieNode<BuildTimeTrieData>([])
|
const trie = new FileTrieNode<BuildTimeTrieData>([])
|
||||||
allFiles.forEach((file) => {
|
allFiles.forEach((file) => {
|
||||||
if (file.frontmatter) {
|
if (file.frontmatter) {
|
||||||
|
if (cfg && isUnlisted(file, cfg.configuration)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
trie.add({
|
trie.add({
|
||||||
...file,
|
...file,
|
||||||
slug: file.slug!,
|
slug: file.slug!,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user