init commit for iPAL-kit plugin
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
import type { I18nConfig } from '../i18n/index.js'
|
||||
import type { SystemPageRole } from './types.js'
|
||||
|
||||
import { buildLocalizedPath, getLocalizedSlugs } from '../i18n/index.js'
|
||||
|
||||
/**
|
||||
* The shape we need from an assigned system-page document: its localized slug
|
||||
* field, as returned by Payload when the parent is read with `locale: 'all'`.
|
||||
*
|
||||
* The plugin doesn't know the client's Pages type, so it depends only on this
|
||||
* minimal contract.
|
||||
*/
|
||||
type AssignedPage = {
|
||||
slug?: null | Record<string, unknown>
|
||||
}
|
||||
|
||||
type GetSystemPagePathArgs = {
|
||||
config: I18nConfig
|
||||
/**
|
||||
* Slug that represents the site root. Defaults to 'home'. When the assigned
|
||||
* page's slug in the target locale equals this, the path collapses to the
|
||||
* locale root (/pl, /en).
|
||||
*/
|
||||
homeSlug?: string
|
||||
/** Target locale to build the path for. */
|
||||
locale: string
|
||||
/**
|
||||
* The resolved system-page assignment from SiteSettings — the related
|
||||
* document object (not just an ID), read with `locale: 'all'` so its slug
|
||||
* is a locale→value map. Pass null/undefined if the role is unassigned.
|
||||
*/
|
||||
page: AssignedPage | null | undefined
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves a system-page assignment to a locale-aware path.
|
||||
*
|
||||
* Bridges the Pages module (which document plays a role) and the i18n module
|
||||
* (how that document's localized slug becomes a URL). This is what powers
|
||||
* "visit /pl → serve the homepage": read SiteSettings.homepage, pass the
|
||||
* related document here, get /pl/strona-glowna (or /pl if it's the home slug).
|
||||
*
|
||||
* Returns undefined when the role is unassigned or the assigned page has no
|
||||
* slug in the target locale — the caller decides the fallback (e.g. 404,
|
||||
* redirect to default locale).
|
||||
*
|
||||
* @example
|
||||
* const settings = await payload.findGlobal({ slug: 'site-settings', locale: 'all', depth: 1 })
|
||||
* getSystemPagePath({ page: settings.homepage, locale: 'pl', config })
|
||||
* // → '/pl' (home slug collapses to root)
|
||||
* getSystemPagePath({ page: settings.privacyPolicy, locale: 'en', config })
|
||||
* // → '/en/privacy-policy'
|
||||
*/
|
||||
export function getSystemPagePath({
|
||||
config,
|
||||
homeSlug = 'home',
|
||||
locale,
|
||||
page,
|
||||
}: GetSystemPagePathArgs): string | undefined {
|
||||
if (!page?.slug) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
const slugs = getLocalizedSlugs({ config, slugField: page.slug })
|
||||
return buildLocalizedPath({ config, homeSlug, locale, slugs })
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
export { getSystemPagePath } from './getSystemPagePath.js'
|
||||
export { buildSystemPagesFields } from './systemPagesFields.js'
|
||||
export type { PagesOption, SystemPageRole } from './types.js'
|
||||
export { ALL_SYSTEM_PAGE_ROLES } from './types.js'
|
||||
@@ -0,0 +1,43 @@
|
||||
import type { Field, RelationshipField } from 'payload'
|
||||
|
||||
import type { PagesOption, SystemPageRole } from './types.js'
|
||||
|
||||
import { ALL_SYSTEM_PAGE_ROLES } from './types.js'
|
||||
|
||||
/** Admin-facing labels per role. */
|
||||
const ROLE_LABELS: Record<SystemPageRole, string> = {
|
||||
cookiePolicy: 'Cookie Policy',
|
||||
homepage: 'Homepage',
|
||||
privacyPolicy: 'Privacy Policy',
|
||||
}
|
||||
|
||||
/** Admin descriptions per role. */
|
||||
const ROLE_DESCRIPTIONS: Record<SystemPageRole, string> = {
|
||||
cookiePolicy: 'Page linked from the cookie consent banner.',
|
||||
homepage: 'Page served at the locale root (e.g. /pl, /en).',
|
||||
privacyPolicy: 'Page linked as the privacy policy.',
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds one relationship field per configured system-page role.
|
||||
*
|
||||
* Each field points at the client's Pages collection (via the provided slug)
|
||||
* and holds a single document reference. The referenced document's slug is
|
||||
* localized, so the same assignment resolves to /pl/strona-glowna and
|
||||
* /en/home at runtime — role assignment is locale-agnostic, path resolution
|
||||
* is locale-aware (see getSystemPagePath).
|
||||
*/
|
||||
export function buildSystemPagesFields(pages: PagesOption): Field[] {
|
||||
const roles = pages.roles?.length ? pages.roles : [...ALL_SYSTEM_PAGE_ROLES]
|
||||
|
||||
return roles.map((role): RelationshipField => ({
|
||||
name: role,
|
||||
type: 'relationship',
|
||||
admin: {
|
||||
description: ROLE_DESCRIPTIONS[role],
|
||||
},
|
||||
label: ROLE_LABELS[role],
|
||||
maxDepth: 1,
|
||||
relationTo: pages.slug,
|
||||
}))
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/**
|
||||
* Built-in "system page" roles — documents from the client's Pages
|
||||
* collection that the site references by function rather than by slug.
|
||||
*/
|
||||
export type SystemPageRole = 'cookiePolicy' | 'homepage' | 'privacyPolicy'
|
||||
|
||||
/**
|
||||
* All system roles in a stable order (used when no subset is configured).
|
||||
*/
|
||||
export const ALL_SYSTEM_PAGE_ROLES: readonly SystemPageRole[] = [
|
||||
'homepage',
|
||||
'privacyPolicy',
|
||||
'cookiePolicy',
|
||||
]
|
||||
|
||||
/**
|
||||
* Plugin option enabling system-page assignments in SiteSettings.
|
||||
*
|
||||
* The plugin doesn't own the Pages collection — the client creates it in
|
||||
* their own project. This option hands the plugin the collection's slug so
|
||||
* it can build relationship fields pointing at it. No hardcoding: the slug
|
||||
* always comes from the client.
|
||||
*/
|
||||
export type PagesOption = {
|
||||
/**
|
||||
* Which system roles to expose as assignable fields.
|
||||
* Defaults to all roles when omitted.
|
||||
*/
|
||||
roles?: SystemPageRole[]
|
||||
/** Slug of the client's Pages collection, e.g. 'pages'. */
|
||||
slug: string
|
||||
}
|
||||
Reference in New Issue
Block a user