Skip to content

Commit

Permalink
Add support for draft documentation pages (#1613)
Browse files Browse the repository at this point in the history
Co-authored-by: Luiz Ferraz <luiz@lferraz.com>
Co-authored-by: liruifengv <liruifeng1024@gmail.com>
Co-authored-by: Chris Swithinbank <357379+delucis@users.noreply.github.com>
Co-authored-by: Chris Swithinbank <swithinbank@gmail.com>
  • Loading branch information
5 people committed Apr 30, 2024
1 parent ca0678c commit 61493e5
Show file tree
Hide file tree
Showing 44 changed files with 162 additions and 29 deletions.
5 changes: 5 additions & 0 deletions .changeset/six-vans-trade.md
@@ -0,0 +1,5 @@
---
'@astrojs/starlight': minor
---

Adds new `draft` frontmatter option to exclude a page from production builds.
1 change: 1 addition & 0 deletions docs/src/content/docs/guides/pages.mdx
Expand Up @@ -105,6 +105,7 @@ The following properties differ from Markdown frontmatter:
- The [`slug`](/reference/frontmatter/#slug) property is not supported and is automatically set based on the custom page’s URL.
- The [`editUrl`](/reference/frontmatter/#editurl) option requires a URL to display an edit link.
- The [`sidebar`](/reference/frontmatter/#sidebar) frontmatter property for customizing how the page appears in [autogenerated link groups](/reference/configuration/#sidebar) is not available. Pages using the `<StarlightPage />` component are not part of a collection and cannot be added to an autogenerated sidebar group.
- The [`draft`](/reference/frontmatter/#draft) option only displays a [notice](/reference/overrides/#draftcontentnotice) that the page is a draft but does not automatically exclude it from production builds.

##### `sidebar`

Expand Down
15 changes: 15 additions & 0 deletions docs/src/content/docs/reference/frontmatter.md
Expand Up @@ -268,6 +268,21 @@ pagefind: false
---
```

### `draft`

**type:** `boolean`
**default:** `false`

Set whether this page should be considered a draft and not be included in [production builds](https://docs.astro.build/en/reference/cli-reference/#astro-build) and [autogenerated link groups](/guides/sidebar/#autogenerated-groups). Set to `true` to mark a page as a draft and make it only visible during development.

```md
---
# src/content/docs/example.md
# Exclude this page from production builds
draft: true
---
```

### `sidebar`

**type:** [`SidebarConfig`](#sidebarconfig)
Expand Down
6 changes: 6 additions & 0 deletions docs/src/content/docs/reference/overrides.md
Expand Up @@ -338,6 +338,12 @@ Component containing the `<h1>` element for the current page.

Implementations should ensure they set `id="_top"` on the `<h1>` element as in the default implementation.

#### `DraftContentNotice`

**Default component:** [`DraftContentNotice.astro`](https://github.com/withastro/starlight/blob/main/packages/starlight/components/DraftContentNotice.astro)

Notice displayed to users during development when the current page is marked as a draft.

#### `FallbackContentNotice`

**Default component:** [`FallbackContentNotice.astro`](https://github.com/withastro/starlight/blob/main/packages/starlight/components/FallbackContentNotice.astro)
Expand Down
1 change: 1 addition & 0 deletions packages/starlight/__tests__/basics/config-errors.test.ts
Expand Up @@ -17,6 +17,7 @@ test('parses valid config successfully', () => {
"components": {
"Banner": "@astrojs/starlight/components/Banner.astro",
"ContentPanel": "@astrojs/starlight/components/ContentPanel.astro",
"DraftContentNotice": "@astrojs/starlight/components/DraftContentNotice.astro",
"EditLink": "@astrojs/starlight/components/EditLink.astro",
"FallbackContentNotice": "@astrojs/starlight/components/FallbackContentNotice.astro",
"Footer": "@astrojs/starlight/components/Footer.astro",
Expand Down
20 changes: 19 additions & 1 deletion packages/starlight/__tests__/basics/routing.test.ts
Expand Up @@ -8,7 +8,7 @@ vi.mock('astro:content', async () =>
docs: [
['404.md', { title: 'Not found' }],
['index.mdx', { title: 'Home page' }],
['guides/authoring-content.md', { title: 'Authoring content' }],
['guides/authoring-content.md', { title: 'Authoring content', draft: true }],
],
})
);
Expand Down Expand Up @@ -41,3 +41,21 @@ test('routes have locale data added', () => {
expect(route.locale).toBeUndefined();
}
});

test('routes includes drafts except in production', async () => {
expect(routes.find((route) => route.id === 'guides/authoring-content.md')).toBeTruthy();

// Reset the modules registry so that re-importing `utils/routing.ts` re-evaluates the module and
// re-computes the routes. Re-importing the module is necessary because top-level imports cannot
// be re-evaluated.
vi.resetModules();
// Set the mode to production.
vi.stubEnv('MODE', 'production');
// Re-import the module to re-evaluate it.
const { routes: prodRoutes } = await import('../../utils/routing');

expect(prodRoutes.find((route) => route.id === 'guides/authoring-content.md')).toBeFalsy();

vi.unstubAllEnvs();
vi.resetModules();
});
8 changes: 7 additions & 1 deletion packages/starlight/__tests__/test-utils.ts
Expand Up @@ -53,7 +53,13 @@ export async function mockedAstroContent({
const mockDicts = i18n.map((dict) => mockDict(...dict));
return {
...mod,
getCollection: (collection: 'docs' | 'i18n') => (collection === 'i18n' ? mockDicts : mockDocs),
getCollection: (
collection: 'docs' | 'i18n',
filter?: (entry: ReturnType<typeof mockDoc> | ReturnType<typeof mockDict>) => unknown
) => {
const entries = collection === 'i18n' ? mockDicts : mockDocs;
return filter ? entries.filter(filter) : entries;
},
};
}

Expand Down
31 changes: 31 additions & 0 deletions packages/starlight/components/ContentNotice.astro
@@ -0,0 +1,31 @@
---
import { Icons } from '../components/Icons';
import Icon from '../user-components/Icon.astro';
interface Props {
icon: keyof typeof Icons;
label: string;
}
const { icon, label } = Astro.props;
---

<p class="sl-flex">
<Icon name={icon} size="1.5em" color="var(--sl-color-orange-high)" />
<span>{label}</span>
</p>

<style>
p {
border: 1px solid var(--sl-color-orange);
padding: 0.75em 1em;
background-color: var(--sl-color-orange-low);
color: var(--sl-color-orange-high);
width: max-content;
max-width: 100%;
align-items: center;
gap: 0.75em;
font-size: var(--sl-text-body-sm);
line-height: var(--sl-line-height-headings);
}
</style>
8 changes: 8 additions & 0 deletions packages/starlight/components/DraftContentNotice.astro
@@ -0,0 +1,8 @@
---
import ContentNotice from './ContentNotice.astro';
import type { Props } from '../props';
const { labels } = Astro.props;
---

<ContentNotice icon="warning" label={labels['page.draft']} />
23 changes: 2 additions & 21 deletions packages/starlight/components/FallbackContentNotice.astro
@@ -1,27 +1,8 @@
---
import Icon from '../user-components/Icon.astro';
import ContentNotice from './ContentNotice.astro';
import type { Props } from '../props';
const { labels } = Astro.props;
---

<p class="sl-flex">
<Icon name={'warning'} size="1.5em" color="var(--sl-color-orange-high)" /><span
>{labels['i18n.untranslatedContent']}</span
>
</p>

<style>
p {
border: 1px solid var(--sl-color-orange);
padding: 0.75em 1em;
background-color: var(--sl-color-orange-low);
color: var(--sl-color-orange-high);
width: max-content;
max-width: 100%;
align-items: center;
gap: 0.75em;
font-size: var(--sl-text-body-sm);
line-height: var(--sl-line-height-headings);
}
</style>
<ContentNotice icon="warning" label={labels['i18n.untranslatedContent']} />
2 changes: 2 additions & 0 deletions packages/starlight/components/Page.astro
Expand Up @@ -11,6 +11,7 @@ import '../style/util.css';
import Banner from 'virtual:starlight/components/Banner';
import ContentPanel from 'virtual:starlight/components/ContentPanel';
import FallbackContentNotice from 'virtual:starlight/components/FallbackContentNotice';
import DraftContentNotice from 'virtual:starlight/components/DraftContentNotice';
import Footer from 'virtual:starlight/components/Footer';
import Head from 'virtual:starlight/components/Head';
import Header from 'virtual:starlight/components/Header';
Expand Down Expand Up @@ -101,6 +102,7 @@ const pagefindEnabled =
<>
<ContentPanel {...Astro.props}>
<PageTitle {...Astro.props} />
{Astro.props.entry.data.draft && <DraftContentNotice {...Astro.props} />}
{Astro.props.isFallback && <FallbackContentNotice {...Astro.props} />}
</ContentPanel>
<ContentPanel {...Astro.props}>
Expand Down
4 changes: 4 additions & 0 deletions packages/starlight/package.json
Expand Up @@ -98,6 +98,10 @@
"types": "./components/FallbackContentNotice.astro.tsx",
"import": "./components/FallbackContentNotice.astro"
},
"./components/DraftContentNotice.astro": {
"types": "./components/DraftContentNotice.astro.tsx",
"import": "./components/DraftContentNotice.astro"
},
"./components/Page.astro": {
"types": "./components/Page.astro.tsx",
"import": "./components/Page.astro"
Expand Down
6 changes: 6 additions & 0 deletions packages/starlight/schema.ts
Expand Up @@ -103,6 +103,12 @@ const StarlightFrontmatterSchema = (context: SchemaContext) =>

/** Pagefind indexing for this page - set to false to disable. */
pagefind: z.boolean().default(true),

/**
* Indicates that this page is a draft and will not be included in production builds.
* Note that the page will still be available when running Astro in development mode.
*/
draft: z.boolean().default(false),
});
/** Type of Starlight’s default frontmatter schema. */
type DefaultSchema = ReturnType<typeof StarlightFrontmatterSchema>;
Expand Down
9 changes: 9 additions & 0 deletions packages/starlight/schemas/components.ts
Expand Up @@ -202,6 +202,15 @@ export function ComponentConfigSchema() {
.string()
.default('@astrojs/starlight/components/FallbackContentNotice.astro'),

/**
* Notice displayed to users on draft pages. Only used in development mode.
*
* @see {@link https://github.com/withastro/starlight/blob/main/packages/starlight/components/DraftContentNotice.astro `DraftContentNotice` default implementation}
*/
DraftContentNotice: z
.string()
.default('@astrojs/starlight/components/DraftContentNotice.astro'),

/**
* Component rendered at the top of the page when `hero` is set in frontmatter. The default
* implementation shows a large title, tagline, and call-to-action links alongside an optional image.
Expand Down
6 changes: 6 additions & 0 deletions packages/starlight/schemas/i18n.ts
Expand Up @@ -123,6 +123,12 @@ function starlightI18nSchema() {
.string()
.describe('Label shown on the “next page” pagination arrow in the page footer.'),

'page.draft': z
.string()
.describe(
'Development-only notice informing users they are on a page that is a draft which will not be included in production builds.'
),

'404.text': z.string().describe('Text shown on Starlight’s default 404 page'),
'aside.tip': z.string().describe('Text shown on the tip aside variant'),
'aside.note': z.string().describe('Text shown on the note aside variant'),
Expand Down
1 change: 1 addition & 0 deletions packages/starlight/translations/ar.json
Expand Up @@ -18,6 +18,7 @@
"page.lastUpdated": "اخر تحديث:",
"page.previousLink": "السابق",
"page.nextLink": "التالي",
"page.draft": "This content is a draft and will not be included in production builds.",
"404.text": "الصفحة غير موجودة. تأكد من الرابط أو ابحث بإستعمال شريط البحث.",
"aside.note": "ملحوظة",
"aside.tip": "نصيحة",
Expand Down
1 change: 1 addition & 0 deletions packages/starlight/translations/cs.json
Expand Up @@ -18,6 +18,7 @@
"page.lastUpdated": "Poslední aktualizace:",
"page.previousLink": "Předchozí",
"page.nextLink": "Další",
"page.draft": "This content is a draft and will not be included in production builds.",
"404.text": "Stránka nenalezena. Zkontrolujte adresu URL nebo zkuste použít vyhledávací pole.",
"aside.note": "Note",
"aside.tip": "Tip",
Expand Down
1 change: 1 addition & 0 deletions packages/starlight/translations/da.json
Expand Up @@ -18,6 +18,7 @@
"page.lastUpdated": "Sidst opdateret:",
"page.previousLink": "Forrige",
"page.nextLink": "Næste",
"page.draft": "This content is a draft and will not be included in production builds.",
"404.text": "Siden er ikke fundet. Tjek din URL eller prøv søgelinjen.",
"aside.note": "Note",
"aside.tip": "Tip",
Expand Down
1 change: 1 addition & 0 deletions packages/starlight/translations/de.json
Expand Up @@ -18,6 +18,7 @@
"page.lastUpdated": "Zuletzt bearbeitet:",
"page.previousLink": "Vorherige Seite",
"page.nextLink": "Nächste Seite",
"page.draft": "This content is a draft and will not be included in production builds.",
"404.text": "Seite nicht gefunden. Überprüfe die URL oder nutze die Suchleiste.",
"aside.note": "Hinweis",
"aside.tip": "Tipp",
Expand Down
1 change: 1 addition & 0 deletions packages/starlight/translations/en.json
Expand Up @@ -18,6 +18,7 @@
"page.lastUpdated": "Last updated:",
"page.previousLink": "Previous",
"page.nextLink": "Next",
"page.draft": "This content is a draft and will not be included in production builds.",
"404.text": "Page not found. Check the URL or try using the search bar.",
"aside.note": "Note",
"aside.tip": "Tip",
Expand Down
1 change: 1 addition & 0 deletions packages/starlight/translations/es.json
Expand Up @@ -18,6 +18,7 @@
"page.lastUpdated": "Última actualización:",
"page.previousLink": "Página anterior",
"page.nextLink": "Siguiente página",
"page.draft": "This content is a draft and will not be included in production builds.",
"404.text": "Página no encontrada. Verifica la URL o intenta usar la barra de búsqueda.",
"aside.note": "Nota",
"aside.tip": "Consejo",
Expand Down
1 change: 1 addition & 0 deletions packages/starlight/translations/fa.json
Expand Up @@ -18,6 +18,7 @@
"page.lastUpdated": "آخرین به‌روزرسانی:",
"page.previousLink": "قبلی",
"page.nextLink": "بعدی",
"page.draft": "This content is a draft and will not be included in production builds.",
"404.text": "صفحه یافت نشد. لطفاً URL را بررسی کنید یا از جستجو استفاده نمایید.",
"aside.note": "یادداشت",
"aside.tip": "نکته",
Expand Down
1 change: 1 addition & 0 deletions packages/starlight/translations/fr.json
Expand Up @@ -18,6 +18,7 @@
"page.lastUpdated": "Dernière mise à jour :",
"page.previousLink": "Précédent",
"page.nextLink": "Suivant",
"page.draft": "Ce contenu est une ébauche et ne sera pas inclus dans la version de production.",
"404.text": "Page non trouvée. Vérifiez l’URL ou essayez d’utiliser la barre de recherche.",
"aside.note": "Note",
"aside.tip": "Astuce",
Expand Down
1 change: 1 addition & 0 deletions packages/starlight/translations/gl.json
Expand Up @@ -18,6 +18,7 @@
"page.lastUpdated": "Última actualización:",
"page.previousLink": "Anterior",
"page.nextLink": "Seguinte",
"page.draft": "This content is a draft and will not be included in production builds.",
"404.text": "Paxina non atopada. Comproba a URL ou intenta usar a barra de busca.",
"aside.note": "Note",
"aside.tip": "Tip",
Expand Down
1 change: 1 addition & 0 deletions packages/starlight/translations/he.json
Expand Up @@ -18,6 +18,7 @@
"page.lastUpdated": "עדכון אחרון:",
"page.previousLink": "הקודם",
"page.nextLink": "הבא",
"page.draft": "This content is a draft and will not be included in production builds.",
"404.text": "הדף לא נמצא. אנא בדקו את כתובת האתר או נסו להשתמש בסרגל החיפוש.",
"aside.note": "Note",
"aside.tip": "Tip",
Expand Down
1 change: 1 addition & 0 deletions packages/starlight/translations/hi.json
Expand Up @@ -18,6 +18,7 @@
"page.lastUpdated": "आखिरी अद्यतन:",
"page.previousLink": "पिछला",
"page.nextLink": "अगला",
"page.draft": "This content is a draft and will not be included in production builds.",
"404.text": "यह पृष्ठ नहीं मिला। URL जांचें या खोज बार का उपयोग करने का प्रयास करें।",
"aside.note": "टिप्पणी",
"aside.tip": "संकेत",
Expand Down
1 change: 1 addition & 0 deletions packages/starlight/translations/id.json
Expand Up @@ -18,6 +18,7 @@
"page.lastUpdated": "Terakhir diperbaharui:",
"page.previousLink": "Sebelumnya",
"page.nextLink": "Selanjutnya",
"page.draft": "This content is a draft and will not be included in production builds.",
"404.text": "Halaman tidak ditemukan. Cek kembali kolom URL atau gunakan fitur pencarian.",
"aside.note": "Catatan",
"aside.tip": "Tips",
Expand Down
1 change: 1 addition & 0 deletions packages/starlight/translations/it.json
Expand Up @@ -18,6 +18,7 @@
"page.lastUpdated": "Ultimo aggiornamento:",
"page.previousLink": "Indietro",
"page.nextLink": "Avanti",
"page.draft": "This content is a draft and will not be included in production builds.",
"404.text": "Pagina non trovata. Verifica l'URL o prova a utilizzare la barra di ricerca.",
"aside.note": "Nota",
"aside.tip": "Consiglio",
Expand Down
1 change: 1 addition & 0 deletions packages/starlight/translations/ja.json
Expand Up @@ -18,6 +18,7 @@
"page.lastUpdated": "最終更新日:",
"page.previousLink": "前へ",
"page.nextLink": "次へ",
"page.draft": "This content is a draft and will not be included in production builds.",
"404.text": "ページが見つかりません。 URL を確認するか、検索バーを使用してみてください。",
"aside.note": "ノート",
"aside.tip": "ヒント",
Expand Down
1 change: 1 addition & 0 deletions packages/starlight/translations/ko.json
Expand Up @@ -18,6 +18,7 @@
"page.lastUpdated": "마지막 업데이트:",
"page.previousLink": "이전",
"page.nextLink": "다음",
"page.draft": "This content is a draft and will not be included in production builds.",
"404.text": "페이지를 찾을 수 없습니다. URL을 확인하거나 검색 막대를 사용해 보세요.",
"aside.note": "노트",
"aside.tip": "",
Expand Down
1 change: 1 addition & 0 deletions packages/starlight/translations/nb.json
Expand Up @@ -18,6 +18,7 @@
"page.lastUpdated": "Sist oppdatert:",
"page.previousLink": "Forrige",
"page.nextLink": "Neste",
"page.draft": "This content is a draft and will not be included in production builds.",
"404.text": "Siden ble ikke funnet. Sjekk URL-en eller prøv å bruke søkefeltet.",
"aside.note": "Note",
"aside.tip": "Tip",
Expand Down
1 change: 1 addition & 0 deletions packages/starlight/translations/nl.json
Expand Up @@ -18,6 +18,7 @@
"page.lastUpdated": "Laatst bewerkt:",
"page.previousLink": "Vorige",
"page.nextLink": "Volgende",
"page.draft": "This content is a draft and will not be included in production builds.",
"404.text": "Pagina niet gevonden. Controleer de URL of probeer de zoekbalk.",
"aside.note": "Opmerking",
"aside.tip": "Tip",
Expand Down
1 change: 1 addition & 0 deletions packages/starlight/translations/pl.json
Expand Up @@ -18,6 +18,7 @@
"page.lastUpdated": "Ostatnia aktualizacja:",
"page.previousLink": "Poprzednia strona",
"page.nextLink": "Następna strona",
"page.draft": "This content is a draft and will not be included in production builds.",
"404.text": "Nie znaleziono. Sprawdź URL lub użyj wyszukiwarki.",
"aside.note": "Notatka",
"aside.tip": "Wskazówka",
Expand Down
1 change: 1 addition & 0 deletions packages/starlight/translations/pt.json
Expand Up @@ -18,6 +18,7 @@
"page.lastUpdated": "Última atualização:",
"page.previousLink": "Anterior",
"page.nextLink": "Próximo",
"page.draft": "Esse conteúdo é um rascunho e não será incluído em builds de produção.",
"404.text": "Página não encontrada. Verifique o URL ou tente usar a barra de pesquisa.",
"aside.note": "Nota",
"aside.tip": "Dica",
Expand Down

0 comments on commit 61493e5

Please sign in to comment.