summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHiDeoo2023-07-11 12:25:51 +0200
committerGitHub2023-07-11 12:25:51 +0200
commit69b7d4c23761a45dc2b9ea75c6c9c904a885ba5d (patch)
treef0d09f6418bd36078d47ea142e01dbd9e01c8c6d
parent5db3e6ea2e5cb7d9552fc54567811358851fb533 (diff)
downloadIT.starlight-69b7d4c23761a45dc2b9ea75c6c9c904a885ba5d.tar.gz
IT.starlight-69b7d4c23761a45dc2b9ea75c6c9c904a885ba5d.tar.bz2
IT.starlight-69b7d4c23761a45dc2b9ea75c6c9c904a885ba5d.zip
Add pagination configuration (#303)
Co-authored-by: Chris Swithinbank <swithinbank@gmail.com>
-rw-r--r--.changeset/green-jars-march.md5
-rw-r--r--docs/src/content/docs/reference/configuration.md9
-rw-r--r--docs/src/content/docs/reference/frontmatter.md42
-rw-r--r--packages/starlight/components/Footer.astro5
-rw-r--r--packages/starlight/schema.ts12
-rw-r--r--packages/starlight/schemas/prevNextLink.ts20
-rw-r--r--packages/starlight/utils/navigation.ts55
-rw-r--r--packages/starlight/utils/user-config.ts8
8 files changed, 151 insertions, 5 deletions
diff --git a/.changeset/green-jars-march.md b/.changeset/green-jars-march.md
new file mode 100644
index 00000000..eb6d1171
--- /dev/null
+++ b/.changeset/green-jars-march.md
@@ -0,0 +1,5 @@
+---
+"@astrojs/starlight": minor
+---
+
+Add new global `pagination` option defaulting to `true` to define whether or not the previous and next page links are shown in the footer. A page can override this setting or the link text and/or URL using the new `prev` and `next` frontmatter fields.
diff --git a/docs/src/content/docs/reference/configuration.md b/docs/src/content/docs/reference/configuration.md
index 3ea91414..275d9eb8 100644
--- a/docs/src/content/docs/reference/configuration.md
+++ b/docs/src/content/docs/reference/configuration.md
@@ -367,3 +367,12 @@ interface HeadConfig {
Control whether the footer shows when the page was last updated.
By default, this feature relies on your repository’s Git history and may not be accurate on some deployment platforms performing [shallow clones](https://git-scm.com/docs/git-clone#Documentation/git-clone.txt---depthltdepthgt). A page can override this setting or the Git-based date using the [`lastUpdated` frontmatter field](/reference/frontmatter/#lastupdated).
+
+### `pagination`
+
+**type:** `boolean`
+**default:** `true`
+
+Define if the footer should include previous and next page links.
+
+A page can override this setting or the link text and/or URL using the [`prev`](/reference/frontmatter/#prev) and [`next`](/reference/frontmatter/#next) frontmatter fields.
diff --git a/docs/src/content/docs/reference/frontmatter.md b/docs/src/content/docs/reference/frontmatter.md
index 14dded59..ede73997 100644
--- a/docs/src/content/docs/reference/frontmatter.md
+++ b/docs/src/content/docs/reference/frontmatter.md
@@ -146,3 +146,45 @@ title: Page with a custom last update date
lastUpdated: 2022-08-09
---
```
+
+### `prev`
+
+**type:** `boolean | string | { link?: string; label?: string }`
+
+Overrides the [global `pagination` option](/reference/configuration/#pagination). If a string is specified, the generated link text will be replaced and if an object is specified, both the link and the text will can be overridden.
+
+```md
+---
+# Hide the previous page link
+prev: false
+---
+```
+
+```md
+---
+# Override the previous page link text
+prev: Continue the tutorial
+---
+```
+
+```md
+---
+# Override both the previous page link and text
+prev:
+ link: /unrelated-page/
+ label: Check out this other page
+---
+```
+
+### `next`
+
+**type:** `boolean | string | { link?: string; label?: string }`
+
+Same as [`prev`](#prev) but for the next page link.
+
+```md
+---
+# Hide the next page link
+next: false
+---
+``` \ No newline at end of file
diff --git a/packages/starlight/components/Footer.astro b/packages/starlight/components/Footer.astro
index d5925c1f..d040bb68 100644
--- a/packages/starlight/components/Footer.astro
+++ b/packages/starlight/components/Footer.astro
@@ -14,7 +14,10 @@ interface Props extends LocaleData {
}
const { entry, dir, lang, locale, sidebar } = Astro.props;
-const prevNextLinks = getPrevNextLinks(sidebar);
+const prevNextLinks = getPrevNextLinks(sidebar, config.pagination, {
+ prev: entry.data.prev,
+ next: entry.data.next
+});
---
<footer>
diff --git a/packages/starlight/schema.ts b/packages/starlight/schema.ts
index 4bdbbc60..22077abf 100644
--- a/packages/starlight/schema.ts
+++ b/packages/starlight/schema.ts
@@ -1,5 +1,6 @@
import { z } from 'astro/zod';
import { HeadConfigSchema } from './schemas/head';
+import { PrevNextLinkConfigSchema } from './schemas/prevNextLink';
import { TableOfContentsSchema } from './schemas/tableOfContents';
import { Icons } from './components/Icons';
export { i18nSchema } from './schemas/i18n';
@@ -119,5 +120,16 @@ export function docsSchema() {
* Overrides the `lastUpdated` global config or the date generated from the Git history.
*/
lastUpdated: z.union([z.date(), z.boolean()]).optional(),
+
+ /**
+ * The previous navigation link configuration.
+ * Overrides the `pagination` global config or the link text and/or URL.
+ */
+ prev: PrevNextLinkConfigSchema(),
+ /**
+ * The next navigation link configuration.
+ * Overrides the `pagination` global config or the link text and/or URL.
+ */
+ next: PrevNextLinkConfigSchema(),
});
}
diff --git a/packages/starlight/schemas/prevNextLink.ts b/packages/starlight/schemas/prevNextLink.ts
new file mode 100644
index 00000000..b84c7917
--- /dev/null
+++ b/packages/starlight/schemas/prevNextLink.ts
@@ -0,0 +1,20 @@
+import { z } from 'astro/zod';
+
+export const PrevNextLinkConfigSchema = () =>
+ z
+ .union([
+ z.boolean(),
+ z.string(),
+ z
+ .object({
+ /** The navigation link URL. */
+ link: z.string().optional(),
+ /** The navigation link text. */
+ label: z.string().optional(),
+ })
+ .strict(),
+ ])
+ .optional();
+
+export type PrevNextLinkUserConfig = z.input<ReturnType<typeof PrevNextLinkConfigSchema>>;
+export type PrevNextLinkConfig = z.output<ReturnType<typeof PrevNextLinkConfigSchema>>;
diff --git a/packages/starlight/utils/navigation.ts b/packages/starlight/utils/navigation.ts
index 3bf72173..d096e9c1 100644
--- a/packages/starlight/utils/navigation.ts
+++ b/packages/starlight/utils/navigation.ts
@@ -9,6 +9,7 @@ import type {
SidebarItem,
SidebarLinkItem,
} from './user-config';
+import type { PrevNextLinkConfig } from '../schemas/prevNextLink';
export interface Link {
type: 'link';
@@ -234,17 +235,63 @@ export function flattenSidebar(sidebar: SidebarEntry[]): Link[] {
);
}
-/** Get previous/next pages in the sidebar if there are any. */
-export function getPrevNextLinks(sidebar: SidebarEntry[]): {
+/** Get previous/next pages in the sidebar or the ones from the frontmatter if any. */
+export function getPrevNextLinks(
+ sidebar: SidebarEntry[],
+ paginationEnabled: boolean,
+ config: {
+ prev?: PrevNextLinkConfig;
+ next?: PrevNextLinkConfig;
+ }
+): {
prev: Link | undefined;
next: Link | undefined;
} {
const entries = flattenSidebar(sidebar);
const currentIndex = entries.findIndex((entry) => entry.isCurrent);
- const prev = entries[currentIndex - 1];
- const next = currentIndex > -1 ? entries[currentIndex + 1] : undefined;
+ const prev = applyPrevNextLinkConfig(
+ entries[currentIndex - 1],
+ paginationEnabled,
+ config.prev
+ );
+ const next = applyPrevNextLinkConfig(
+ currentIndex > -1 ? entries[currentIndex + 1] : undefined,
+ paginationEnabled,
+ config.next
+ );
return { prev, next };
}
+/** Apply a prev/next link config to a navigation link. */
+function applyPrevNextLinkConfig(
+ link: Link | undefined,
+ paginationEnabled: boolean,
+ config: PrevNextLinkConfig | undefined
+): Link | undefined {
+ // Explicitly remove the link.
+ if (config === false) return undefined;
+ // Use the generated link if any.
+ else if (config === true) return link;
+ // If a link exists, update its label if needed.
+ else if (typeof config === 'string' && link) {
+ return { ...link, label: config };
+ } else if (typeof config === 'object') {
+ if (link) {
+ // If a link exists, update both its label and href if needed.
+ return {
+ ...link,
+ label: config.label ?? link.label,
+ href: config.link ?? link.href,
+ }
+ } else if (config.link && config.label) {
+ // If there is no link and the frontmatter contains both a URL and a label,
+ // create a new link.
+ return makeLink(config.link, config.label, config.link);
+ }
+ }
+ // Otherwise, if the global config is enabled, return the generated link if any.
+ return paginationEnabled ? link : undefined;
+}
+
/** Remove the extension from a path. */
const stripExtension = (path: string) => path.replace(/\.\w+$/, '');
diff --git a/packages/starlight/utils/user-config.ts b/packages/starlight/utils/user-config.ts
index 4d692d85..d29c8788 100644
--- a/packages/starlight/utils/user-config.ts
+++ b/packages/starlight/utils/user-config.ts
@@ -252,6 +252,14 @@ const UserConfigSchema = z.object({
.default(false)
.describe(
'Define if the last update date should be visible in the page footer.'
+ ),
+
+ /** Define if the previous and next page links should be visible in the page footer. */
+ pagination: z
+ .boolean()
+ .default(true)
+ .describe(
+ 'Define if the previous and next page links should be visible in the page footer.'
),
});