Skip to content

Commit

Permalink
feat: add support for draft blog posts
Browse files Browse the repository at this point in the history
  • Loading branch information
HiDeoo committed May 2, 2024
1 parent ed23ebd commit eebbbcf
Show file tree
Hide file tree
Showing 9 changed files with 217 additions and 15 deletions.
40 changes: 40 additions & 0 deletions docs/src/content/docs/blog/succedere-velut-consumptis-ferat.1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
---
title: Pertimuit munere
date: 2020-07-24
draft: true
excerpt: Cras ultrices nibh eget purus fringilla, non rutrum erat posuere. Cras mattis nisi ut lectus sollicitudin venenatis. Nullam vehicula nisl at fringilla congue. Donec id velit et massa gravida pretium.
tags:
- Placeholder
authors:
- hideoo
---

## Nec loci quicquid ex vinctorum pelle sumpsisse

Lorem markdownum **et** saepe, congerit, carmina tanta carior: est digna iamque proximus invita? _Ora tamen_, insula Parthaoniae famulus illo precor [facerent tenebat](http://www.rediitat.org/vetustas)?

1. Seducta sic
2. Nubila et vivunt legit audax tamen dabant
3. Vix nostra sanguine
4. Neque descenderat perque
5. Tinctus interdictae putri frustraque
6. Et dulci retentis tellus ruitque cum

Illa concipiunt hos mediis pulvis nigra: aratri nulla: dixit iam moveri in patriam arvo. Dimotis ad ulla et viro in sulcis vultus, cane. Ave ferrum, an demptis sine, arbor se iniqui quondam et levem celebrandaque. Pulvis [aptos celer quoque](http://www.sed.com/da) rapida, patiar Actaeas? Promissa iam, cratera, an ager furit cum.

## Scelus fumantis domus ita priscum nervosque iacebas

Regnique ludunt ab soceri versat, quo contudit cernit vertitur cantus cumulum constituit ager. Potes Panomphaeo sive limite quaerit et sorores adde qui hunc sic: liceat fuit longis locorum dea?

Neque Iovi, toto fine labor: casside prior, hunc pectore **huius surgit** gente. Peti his quare Arcades miserantibus caput corpora temptant cremabis refugam.

- Amor amoris in luce Iuno tellus quo
- Sit est coepisse Gradivo sollicitatque tulit viridesque
- Haeret igne voracior nuda discreta
- Poscit adventuque deceant
- Invitusque aut raptae
- Cadavera invia fecundior non prohibent iungit

Sub nomen iniustaque minora, silvis sternuntur me [urbe](http://numen-tunc.org/), enituntur. Vite levata plaustri iuvat Delphos, noluit ferrum ipse pariterque annoso. Percutimurque arma frementis templis, **tulit cetera corporibus** praemia faciam annis, et.

Voce spectabat nutricis, erit querno dextra stetit tamen nullae inferiora. Ea fronde ad ipsa sol est meo sexangula Numam, parvis denique excusare: e. In falli digna nutrit tamen sumit osse obstruat, inpune lacrimis torsi ostendens est talia spolium faciem.
59 changes: 59 additions & 0 deletions docs/src/content/docs/blog/succedere-velut-consumptis-ferat.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
---
title: Succedere velut consumptis ferat
date: 2020-12-30
draft: true
excerpt: Donec aliquam, nunc sed consectetur porta, nibh odio convallis dolor, ut auctor risus augue ac ligula. Ut blandit tempus nulla eget congue. Aliquam id dapibus diam, quis aliquam nulla. Morbi mollis tincidunt urna, sodales facilisis libero molestie sed. Nunc sed dignissim orci, id tempor ligula. Nullam erat augue, sodales eget sollicitudin eget, pulvinar in lectus. Fusce ac sapien tellus. Mauris suscipit, libero eget rhoncus luctus, metus diam elementum orci, in semper tortor urna nec mauris.
tags:
- WIP
authors:
- hideoo
---

## Rudibusque positos tegitur qua pugnat Lucifer habitatis

Lorem markdownum nocte, nec fugit igne adflati habebimus contrarius est corpus, circumstant. Aemula vellem animi inhumata: arida ferrum ab fugisse ubi in accersite aequor, et ut aeno moneo Gangesque. Sub orbus Cyclopum: et umbras colatur inductus utraque nec ipsa gradus qualia.

Est quantum primo! Summa vaccam quae, fuerant noctis atque inplevit pressa, fronti. Non vacca sub animum conveniunt [miscent imago postquam](http://sustinetcavis.org/oppositumque.php) qualemve cerebrum: et ut attrahit invenit. Quaeritur hic misit, haesissem [debebunt](http://verum.org/) venenis ira fugit unco criminis, _huic ille_ qua duobus!

## Tam omnes per corpora genus et sole

Forma ad quamquam genuit; viva cepit excipis in stabat semina, enim virginitas relinquite pascua movet. Quisquis regia, nostri? Suos in rictus deus inmortalis Phryges [feruntur](http://www.dumque-nubibus.io/in) adplauso avem madidos.

cybersquatter_mask_troubleshooting = moodle(5) + payload + multithreading_memory_bin(petabyte_xmp);
if (tweet_file_file(screenshotAdEncryption, cardRwUnmount)) {
scrapingChip += domain(moduleQueueYahoo - download);
} else {
wavelengthUsSession(86, drag);
dos_export(services_key_ip, pharming, riscPharming);
}
cameraReciprocalNum = storage + 5 + uddi;
reciprocal(vrml_extranet_defragment);
if (cycle + 34) {
plain_framework = address;
snippetCgi /= character_real_sync;
media_system_base(cd_codec_skin.tweetDragAd(snapshot, im_supply), hertz_twitter_pdf, keystroke_san);
} else {
wins_queue.ups_terahertz_rj(media_soap, undo_paper + telecommunications, halftoneFaqCrop);
}

## Atria tela solemus silvis pallentia

Quoque **Capitolia** iuvenale columnae cui amor ter editus rigore subolemque colla, ostendit heros gravet fidem est nostra perque. [Cadavera iubendo](http://quam.io/) excepi letique. Verendus alvo genuit caesis, dedit vitta balistave Nescierat tremens.

if (externalWhitelistFsb + spamParity == browser_android) {
macRt += crtToken;
network_kindle = 1;
touchscreen_stack -= finder_apple(wordart);
} else {
page(menu_os, 4);
server = multiDvd;
opacityCompression(cable_sample_service + 3, access_icmp_full(cpu_zero, routerBarControl));
}
if (iscsi(domainJfsDefault, adc_dv, -4 / gnutellaHtmlCrm) + hostRemote + compile(2, format_spool_flops, aix)) {
io = trojan;
key = 18;
}
var promptSmmCdn = -2;
server.serialAddRgb = website(3, bitmap, cardPointBar.dvi_dcim_cdn(iteration, handleDatabase, cross));

Mori dapes, corporibus lecto Lucifer ventus faciem; _non in_ crimenque Acheloia
14 changes: 14 additions & 0 deletions docs/src/content/docs/guides/frontmatter.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,3 +81,17 @@ authors:
- Bob
---
```

### `draft`

**Type:** `boolean`
**Default:** `false`

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

```md
---
draft: true
---
```
25 changes: 24 additions & 1 deletion packages/starlight-blog/components/Metadata.astro
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ import Author from './Author.astro'
interface Props {
entry: StarlightBlogEntry
showBadges?: boolean
}
const { entry } = Astro.props
const { entry, showBadges = true } = Astro.props
const { authors, date } = getBlogEntryMetadata(entry)
const hasAuthors = authors.length > 0
Expand All @@ -26,6 +27,13 @@ const hasAuthors = authors.length > 0
</div>
) : null
}
{
showBadges && entry.data?.draft && (
<div class="badges">
<span class="draft">Draft</span>
</div>
)
}
</div>

<style>
Expand All @@ -44,4 +52,19 @@ const hasAuthors = authors.length > 0
flex-wrap: wrap;
gap: 0.75rem 1rem;
}

.badges {
margin-top: 0.25rem;
}

.draft {
background-color: var(--sl-color-orange-low);
border: 1px solid var(--sl-color-orange);
border-radius: 0.3rem;
color: var(--sl-color-orange-high);
font-size: var(--sl-text-body-sm);
line-height: var(--sl-line-height-headings);
margin-inline: 0.2rem;
padding: 0.25rem 0.5rem 0.35rem;
}
</style>
10 changes: 7 additions & 3 deletions packages/starlight-blog/libs/content.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,12 @@ export function getBlogEntryMetadata(entry: StarlightBlogEntry): StarlightBlogEn
}

export async function getBlogEntries() {
const entries = await getCollection<StarlightEntryData>('docs', ({ id }) => {
return id.startsWith(`${config.prefix}/`) && id !== `${config.prefix}/index.mdx`
const entries = await getCollection<StarlightEntryData>('docs', ({ id, data }) => {
return (
id.startsWith(`${config.prefix}/`) &&
id !== `${config.prefix}/index.mdx` &&
(import.meta.env.MODE !== 'production' || data.draft === false)
)
})

validateBlogEntries(entries)
Expand Down Expand Up @@ -151,7 +155,7 @@ function getAuthorFromConfig(id: string): StarlightBlogAuthor {
return author
}

type StarlightEntryData = z.infer<ReturnType<typeof blogSchema>> & { title: string }
type StarlightEntryData = z.infer<ReturnType<typeof blogSchema>> & { draft?: boolean; title: string }
type StarlightEntry = AstroCollectionEntry<StarlightEntryData>

export type StarlightBlogEntry = StarlightEntry & {
Expand Down
2 changes: 1 addition & 1 deletion packages/starlight-blog/overrides/MarkdownContent.astro
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ if (isBlogPost) {
---

<StarlightMarkdownContent {...Astro.props}>
{isBlogPost && blogEntry ? <Metadata entry={blogEntry.entry} /> : null}
{isBlogPost && blogEntry ? <Metadata entry={blogEntry.entry} showBadges={false} /> : null}
<slot />
{
isBlogPost && blogEntry ? (
Expand Down
2 changes: 1 addition & 1 deletion packages/starlight-blog/playwright.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export default defineConfig({
},
webServer: [
{
command: 'pnpm run dev',
command: 'pnpm run build && pnpm run preview',
cwd: '../../docs',
reuseExistingServer: !process.env['CI'],
url: 'http://localhost:4321',
Expand Down
61 changes: 52 additions & 9 deletions packages/starlight-blog/tests/e2e/blog.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,14 @@ test('should add links to recent posts in the sidebar', async ({ blogPage }) =>
expect(await group.getByRole('link').count()).toBe(10)
})

test('should not add recent draft blog posts in the sidebar', async ({ blogPage }) => {
await blogPage.goto()

const group = blogPage.page.getByRole('group').filter({ hasText: 'Recent posts' })

await expect(group.getByRole('link', { exact: true, name: 'Succedere velut consumptis ferat' })).not.toBeVisible()
})

test('should add links to tags in the sidebar', async ({ blogPage }) => {
await blogPage.goto()

Expand All @@ -89,16 +97,37 @@ test('should add links to tags in the sidebar', async ({ blogPage }) => {

await expect(group.getByText(groupName, { exact: true })).toBeVisible()

expect(await group.getByRole('link').count()).toBe(8)
const links = group.getByRole('link')

expect(await links.count()).toBe(8)

await expect(group.getByRole('link').nth(0)).toContainText('Starlight')
await expect(group.getByRole('link').nth(1)).toContainText('Example')
await expect(group.getByRole('link').nth(2)).toContainText('Placeholder')
await expect(group.getByRole('link').nth(3)).toContainText('Amazing Content')
await expect(group.getByRole('link').nth(4)).toContainText('Demo')
await expect(group.getByRole('link').nth(5)).toContainText('Ipsum')
await expect(group.getByRole('link').nth(6)).toContainText('Lorem')
await expect(group.getByRole('link').nth(7)).toContainText('Test')
await expect(links.nth(0)).toContainText('Starlight')
await expect(links.nth(1)).toContainText('Example')
await expect(links.nth(2)).toContainText('Placeholder')
await expect(links.nth(3)).toContainText('Amazing Content')
await expect(links.nth(4)).toContainText('Demo')
await expect(links.nth(5)).toContainText('Ipsum')
await expect(links.nth(6)).toContainText('Lorem')
await expect(links.nth(7)).toContainText('Test')
})

test('should not add links to tags from draft blog posts in the sidebar', async ({ blogPage }) => {
await blogPage.goto()

await expect(
blogPage.page.getByRole('group').filter({ hasText: 'Tags' }).getByRole('link', { exact: true, name: 'WIP (1)' }),
).not.toBeVisible()
})

test('should not count tags from draft blog posts in the sidebar', async ({ blogPage }) => {
await blogPage.goto()

await expect(
blogPage.page
.getByRole('group')
.filter({ hasText: 'Tags' })
.getByRole('link', { exact: true, name: 'Placeholder (2)' }),
).toBeVisible()
})

test('should display a preview of each posts', async ({ blogPage }) => {
Expand Down Expand Up @@ -148,3 +177,17 @@ test('should render markdown content in custom excerpt', async ({ blogPage }) =>

await expect(articles.first().locator('strong').getByText('vestibulum')).toBeVisible()
})

test('should not list draft blog posts in production', async ({ blogPage }) => {
await blogPage.goto()

await expect(
blogPage.page.getByRole('article').getByRole('link', { exact: true, name: 'Succedere velut consumptis ferat' }),
).not.toBeVisible()

await blogPage.goto(2)

await expect(
blogPage.page.getByRole('article').getByRole('link', { exact: true, name: 'Pertimuit munere' }),
).not.toBeVisible()
})
19 changes: 19 additions & 0 deletions packages/starlight-blog/tests/e2e/tags.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,27 @@ test('should display a preview of each posts with proper tag', async ({ tagsPage
}
})

test('should not include draft blog posts', async ({ tagsPage }) => {
const tag = 'Placeholder'
const count = 2

await tagsPage.goto(tag.toLowerCase())

await expect(tagsPage.page.getByText(`${count} posts with the tag “${tag}”`, { exact: true })).toBeVisible()

const articles = tagsPage.page.getByRole('article')

expect(await articles.count()).toBe(count)
})

test('should not display a link to edit this page', async ({ tagsPage }) => {
await tagsPage.goto('starlight')

await expect(tagsPage.page.getByText('Edit page')).not.toBeVisible()
})

test('should not generate pages for tags with only draft blog posts', async ({ tagsPage }) => {
const response = await tagsPage.goto('wip')

expect(response?.ok()).toBe(false)
})

0 comments on commit eebbbcf

Please sign in to comment.