51 lines
1.7 KiB
TypeScript
51 lines
1.7 KiB
TypeScript
import { BREADCRUMB_PAGE_TYPE_PARENTS } from '#base_modules/WebManager/config/general'
|
|
|
|
/**
|
|
* Utility functions that identify candidate pages for buildBreadcrumbs database queries.
|
|
* Breadcrumbs climb hierarchically from a target page to the home page.
|
|
* To avoid querying all published pages in a locale, queries are filtered down to two
|
|
* predictable sets of candidates:
|
|
* 1. Path-based ancestors: The small chain of parent paths above the target page.
|
|
* 2. Group-key ancestors: Static relationships where pages belong to a specific parent
|
|
* type regardless of location (e.g., blog-item under blog).
|
|
*/
|
|
|
|
export const BREADCRUMB_PARENT_GROUP_KEYS = [
|
|
...new Set(Object.values(BREADCRUMB_PAGE_TYPE_PARENTS)),
|
|
]
|
|
|
|
/**
|
|
* The paths a page can climb to, nearest parent first, ending at the home page (`''`).
|
|
*
|
|
* 'blog/post/hello' → ['blog/post', 'blog', '']
|
|
* 'about' → ['']
|
|
* '' → ['']
|
|
*
|
|
* The page's own path is never included — a page cannot be its own parent.
|
|
*/
|
|
export function ancestorPaths(path: string) {
|
|
const segments = path.split('/').filter(Boolean)
|
|
const paths: string[] = []
|
|
|
|
for (let depth = segments.length - 1; depth >= 1; depth--) {
|
|
paths.push(segments.slice(0, depth).join('/'))
|
|
}
|
|
|
|
paths.push('')
|
|
|
|
return paths
|
|
}
|
|
|
|
/**
|
|
* True when `path` is an already loaded path or an ancestor of one. Only false after a
|
|
* group-key jump to another branch, never during a path climb.
|
|
*/
|
|
export function ancestorsAlreadyLoaded(path: string, loadedPaths: Iterable<string>) {
|
|
for (const loaded of loadedPaths) {
|
|
// The trailing slash keeps 'blog' from matching 'blogging'; '' matches every path.
|
|
if (loaded === path || loaded.startsWith(path === '' ? '' : `${path}/`)) return true
|
|
}
|
|
|
|
return false
|
|
}
|