Implement support for draft pages (#2392)

* feat: support draft pages

* implemented support for draft pages
* added integration test
* updated relevant documentation (english only)

* docs: explicitly mention "markdown draft pages"

* chore: add changeset

* chore: modify changeset

- changed type to 'patch'
- added more description
This commit is contained in:
Pranav Karawale 2022-01-20 01:48:51 +05:30 committed by GitHub
parent 9278ecdc4c
commit 24aa3245ae
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 141 additions and 9 deletions

View file

@ -0,0 +1,15 @@
---
'astro': patch
---
Support markdown draft pages.
Markdown draft pages are markdown pages which have `draft` set in their frontmatter. By default, these will not be built by Astro while running `astro build`. To disable this behavior, you need to set `buildOptions.drafts` to `true` or pass the `--drafts` flag while running `astro build`. An exaple of a markdown draft page is:
```markdown
---
# src/pages/blog-post.md
title: My Blog Post
draft: true
---
This is my blog post which is currently incomplete.
```

View file

@ -98,6 +98,7 @@ Markdown pages have a special frontmatter property for `layout`. This defines th
# src/pages/index.md
layout: ../../layouts/BaseLayout.astro
title: My cool page
draft: false
---
# Hello World!
@ -128,6 +129,7 @@ For Markdown files, the `content` prop also has an `astro` property which holds
"date": "Tuesday, July 27 2021",
"author": "Matthew Phillips",
"description": "Astro 0.18 is our biggest release since Astro launch.",
"draft": false,
**/
"astro": {
"headers": [
@ -159,6 +161,34 @@ Using images or videos follows Astro's normal import rules:
- Example: Image is located at `/public/assets/img/astonaut.png` → Markdown: `![Astronaut](assets/img/astronaut.png)`
- Or use `import` as explained on the [imports page](/en/guides/imports#other-assets) (when using Astro's Markdown Component)
### Markdown draft pages
Markdown pages which have the property `draft` set in their frontmatter are referred to as "draft pages". By default, Astro excludes these pages from the build when building the static version of your page (i.e `astro build`), which means that you can exclude draft/incomplete pages from the production build by setting `draft` to `true`. To enable building of draft pages, you can set `buildOptions.drafts` to `true` in the configuration file, or pass the `--drafts` flag when running `astro build`. Markdown pages which do not have the `draft` property set are not affected. An example of a markdown draft page can be:
```markdown
---
# src/pages/blog-post.md
title: My Blog Post
draft: true
---
This is my blog post which is currently incomplete.
```
An example of a markdown post which is not a draft:
```markdown
---
# src/pages/blog-post.md
title: My Blog Post
draft: false
---
This is my blog post...
```
> This feature only applies to local markdown pages, not the `<Markdown />` component, or remote markdown.
## Astro's Markdown Component
Astro has a dedicated component used to let you render your markdown as HTML components. This is a special component that is only exposed to `.astro` files. To use the `<Markdown>` component, within your frontmatter block use the following import statement:

View file

@ -61,7 +61,7 @@ The `renderers` option defines the framework renderers to be used by Astro.
#### buildOptions
The `buildOptions` option configures how a site is built, including its base URL (`buildOptions.site`), whether it includes a sitemap (`buildOptions.sitemap`), and whether its pages should be files (`path.html`) or directories (`path/index.html`) (`buildOptions.pageUrlFormat`).
The `buildOptions` option configures how a site is built, including its base URL (`buildOptions.site`), whether it includes a sitemap (`buildOptions.sitemap`), whether markdown draft pages should be included in the build (`buildOptions.drafts`), and whether its pages should be files (`path.html`) or directories (`path/index.html`) (`buildOptions.pageUrlFormat`).
#### devOptions

View file

@ -108,6 +108,13 @@ export interface AstroUserConfig {
* Default: 'directory'
*/
pageUrlFormat?: 'file' | 'directory';
/**
* Control if markdown draft pages should be included in the build.
* `true`: Include draft pages
* `false`: Exclude draft pages
* Default: false
*/
drafts?: boolean;
};
/** Options for the development server run with `astro dev`. */
devOptions?: {

View file

@ -26,6 +26,7 @@ interface CLIState {
port?: number;
config?: string;
experimentalStaticBuild?: boolean;
drafts?: boolean;
};
}
@ -39,6 +40,7 @@ function resolveArgs(flags: Arguments): CLIState {
config: typeof flags.config === 'string' ? flags.config : undefined,
hostname: typeof flags.hostname === 'string' ? flags.hostname : undefined,
experimentalStaticBuild: typeof flags.experimentalStaticBuild === 'boolean' ? flags.experimentalStaticBuild : false,
drafts: typeof flags.drafts === 'boolean' ? flags.drafts : false,
};
if (flags.version) {
@ -72,14 +74,15 @@ function printHelp() {
astro check Check your project for errors.
${colors.bold('Flags:')}
--config <path> Specify the path to the Astro config file.
--project-root <path> Specify the path to the project root folder.
--no-sitemap Disable sitemap generation (build only).
--experimental-static-build A more performant build that expects assets to be define statically.
--verbose Enable verbose logging
--silent Disable logging
--version Show the version number and exit.
--help Show this help message.
--config <path> Specify the path to the Astro config file.
--project-root <path> Specify the path to the project root folder.
--no-sitemap Disable sitemap generation (build only).
--experimental-static-build A more performant build that expects assets to be define statically.
--drafts Include markdown draft pages in the build.
--verbose Enable verbose logging
--silent Disable logging
--version Show the version number and exit.
--help Show this help message.
`);
}
@ -99,6 +102,7 @@ function mergeCLIFlags(astroConfig: AstroConfig, flags: CLIState['options']) {
if (typeof flags.port === 'number') astroConfig.devOptions.port = flags.port;
if (typeof flags.hostname === 'string') astroConfig.devOptions.hostname = flags.hostname;
if (typeof flags.experimentalStaticBuild === 'boolean') astroConfig.buildOptions.experimentalStaticBuild = flags.experimentalStaticBuild;
if (typeof flags.drafts === 'boolean') astroConfig.buildOptions.drafts = flags.drafts;
}
/** The primary CLI action */

View file

@ -85,6 +85,19 @@ class AstroBuilder {
routeCache: this.routeCache,
viteServer: this.viteServer,
});
// Filter pages by using conditions based on their frontmatter.
Object.entries(allPages).forEach(([page, data]) => {
if ('frontmatter' in data.preload[1]) {
// TODO: add better type inference to data.preload[1]
const frontmatter = (data.preload[1] as any).frontmatter;
if (Boolean(frontmatter.draft) && !this.config.buildOptions.drafts) {
debug(logging, 'build', timerMessage(`Skipping draft page ${page}`, timer.loadStart));
delete allPages[page];
}
}
});
debug(logging, 'build', timerMessage('All pages loaded', timer.loadStart));
// The names of each pages

View file

@ -59,6 +59,7 @@ export const AstroConfigSchema = z.object({
.optional()
.default('directory'),
experimentalStaticBuild: z.boolean().optional().default(false),
drafts: z.boolean().optional().default(false),
})
.optional()
.default({}),

View file

@ -0,0 +1,47 @@
import { expect } from 'chai';
import cheerio from 'cheerio';
import { loadFixture } from './test-utils.js';
describe('Astro Markdown with draft posts disabled', () => {
let fixture;
before(async () => {
fixture = await loadFixture({
projectRoot: './fixtures/astro-markdown-drafts/',
buildOptions: {
// drafts is false by default but added here for clarity
drafts: false,
sitemap: false,
},
});
await fixture.build();
});
it('Does not render the draft post', async () => {
try {
await fixture.readFile('/wip/index.html');
} catch (err) {
expect(err.code).to.equal('ENOENT');
}
});
});
describe('Astro Markdown with draft posts enabled', () => {
let fixture;
before(async () => {
fixture = await loadFixture({
projectRoot: './fixtures/astro-markdown-drafts/',
buildOptions: {
drafts: true,
sitemap: false,
},
});
await fixture.build();
});
it('Renders the draft post', async () => {
const html = await fixture.readFile('/wip/index.html');
const $ = cheerio.load(html);
expect($('h1').length).to.be.ok;
expect($('h1').text()).to.equal('WIP');
});
});

View file

@ -0,0 +1,7 @@
---
foo: bar
---
# Hello world
This should be visible.

View file

@ -0,0 +1,8 @@
---
foo: bar
draft: true
---
# WIP
This is a draft. Don't build me!