Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
e0027c6
add blog post writing skill
cderv Apr 13, 2026
3344860
draft blog post: chrome-headless-shell announcement
cderv Apr 13, 2026
6f661d5
add thumbnail design guide to blog post skill
cderv Apr 13, 2026
5d0fa3a
add thumbnail and icon attribution to blog post
cderv Apr 13, 2026
a8d7a00
update thumbnail guide with HTML/CSS creation method
cderv Apr 13, 2026
bc057f5
show draft pages in PR deploy previews
cderv Apr 13, 2026
5294bd1
detect draft pages in PR previews and warn before merge
cderv Apr 13, 2026
156ed2b
extract draft detection into reusable composite action
cderv Apr 13, 2026
958b0eb
simplify draft warning in PR comment to avoid duplicate links
cderv Apr 13, 2026
1211644
document draft-check workflow and detect-drafts action in README
cderv Apr 13, 2026
9a28438
document pr-preview profile in README
cderv Apr 13, 2026
87d53c8
fix review findings: shell injection, POSIX grep, .md coverage, CI wo…
cderv Apr 13, 2026
a003539
update thumbnail background to Quarto blue (#5286ab)
cderv Apr 13, 2026
112a051
shorten blog post description for listing card
cderv Apr 13, 2026
51e909e
address review feedback: light thumbnail, remove platform examples
cderv Apr 14, 2026
b19127a
fix file:// example in thumbnail guide to include --allow-file-access
cderv Apr 14, 2026
0e3048f
add prerequisites section to thumbnail guide for tool availability
cderv Apr 14, 2026
bf8d21b
remove draft: true from chrome-headless-shell blog post
cderv Apr 14, 2026
c07f2f5
note in thumbnail guide: always use PNG, never SVG directly
cderv Apr 14, 2026
80ca8f1
update blog post date to 2026-04-14 and rename directory to match
cderv Apr 14, 2026
b007ec6
add publish-date script for blog post date + directory rename
cderv Apr 14, 2026
d88e5c4
add README to _tools/ documenting project scripts
cderv Apr 14, 2026
c571ff2
note renv/pipenv setup in _tools README
cderv Apr 14, 2026
eeff9ff
fix publish-date: rename dir even when date matches, rename before write
cderv Apr 14, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
160 changes: 160 additions & 0 deletions .claude/skills/blog-post/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
---
name: quarto-blog-post
description: Use when writing, drafting, or editing blog posts for quarto.org, creating Quarto feature or release announcements, or reviewing blog post drafts for the Quarto website.
---

# Quarto Blog Post

Write blog posts for `quarto.org/blog` matching the voice, structure, and conventions
from 40+ existing posts.

## Setup

1. `ls docs/blog/posts/` — browse existing posts for reference
2. Read `docs/blog/posts/_metadata.yml` — inherited by all posts (Giscus comments,
title-block-banner, left TOC, signup widget, `search: false`)
3. If the post covers a Quarto feature, read the relevant docs page for accurate
terminology and linking.

## File Structure

```
docs/blog/posts/YYYY-MM-DD-slug/
index.qmd # The post (required)
thumbnail.png # Listing card image (required)
*.png, *.jpg # Additional images
_contribs.md # Contributor list (release posts only)
```

Directory name: `YYYY-MM-DD-slug` — date matches frontmatter, slug is short kebab-case.

## Frontmatter

```yaml
---
title: "Post Title"
description: |
One to three sentences for listing cards and social sharing.
author: Author Name
date: "YYYY-MM-DD"
categories:
- Category1
- Category2
image: thumbnail.png
image-alt: "Descriptive alt text for the thumbnail."
---
```

**title**: Short. Release posts: `"Quarto X.Y"`. Backtick code spans OK.

**description**: Self-contained summary (makes sense without the title). Always `|` block scalar.

**author**: Plain string for staff (`Charlotte Wickham`). Two authors: `Name and Name`.
Guest authors use structured form with `name:` and optional `url:`.

**date**: ISO 8601 `"YYYY-MM-DD"`. Must match directory name.

**categories**: 2-3 per post. Use existing values — scan recent posts to check. Common:
`Releases`, `Quarto X.Y`, `Features`, `Authoring`, `Learn`, `Workshop`, `Conference`,
`Tip`, `Extensions`, `Tables`, `Teaching`, `Jupyter`.

**image / image-alt**: `thumbnail.png` preferred. `image-alt` is mandatory.
See `references/thumbnail-guide.md` for dimensions, visual style, and design patterns.

**Optional**: `lightbox: true` (many screenshots), `draft: true` (while developing).
Do not use `subtitle:` (phased out after 2023).

## Post Types

Identify the type before writing — it determines structure, opening, and closing.
Read `references/post-types.md` for detailed structure guidance per type.

| Type | When | Key trait |
|------|------|-----------|
| **Release** | New Quarto version ships | Most structured: features → Other Highlights → Acknowledgements |
| **Feature** | Spotlight a specific capability | Concept-driven sections, docs links |
| **How-to** | Tutorial or walkthrough | Problem → solution, sequential steps |
| **News** | Short announcement, roundup | Very short, layout-heavy, minimal prose |

## Writing Voice

**First-person plural**: "We" for team work, "you" for the reader.

**Warm, not marketing**: "We're excited about this feature" — good.
"This groundbreaking capability" — bad. Collegial tone, sharing with practitioners.

**Direct openers**: Get to the point immediately. No "In this blog post, we will..."
preambles. State what happened or what the feature does, then elaborate.

**Technical accuracy**: Use exact terminology from the docs. Link to docs rather than
trying to replicate them — the post introduces, the docs page is the reference.

**Thank contributors**: Call out external contributors warmly inline.

## Technical Conventions

### Images

Every image must have `fig-alt=` text — non-negotiable accessibility standard.

```markdown
![](screenshot.png){fig-alt="Description of what the screenshot shows."}
```

Multi-image layouts use Quarto's layout system (`{layout-ncol="2"}`).
For many images, add `{.lightbox group="name"}`.

### Code Blocks

Always specify language. Use `filename=` labels for file content or terminal commands:

````markdown
```{.yaml filename="_quarto.yml"}
project:
type: website
```
````

### Links

Every feature mentioned links to its docs page. Pattern: explain briefly, show example,
then link. Use site-root-relative paths: `[Feature](/docs/path.qmd)`.

### Callouts

Use sparingly: `.callout-tip` for post origin context, `.callout-warning` for caveats,
`.callout-note` for prerequisites. Release posts typically skip callouts.

### Shortcodes

- `{{< prerelease-callout X.Y type="blog" >}}` — pre-release banner (auto-disappears)
- `{{< video URL >}}` — video embed
- `{{< include file.md >}}` — include generated content

## Workflow

1. **Identify post type** → read `references/post-types.md` for that type
2. **Create directory**: `docs/blog/posts/YYYY-MM-DD-slug/`
3. **Write frontmatter** per schema above
4. **Draft body** following type-specific structure
5. **Add images** with `fig-alt=` on every one
6. **Link to docs** for every feature mentioned
7. **Create thumbnail** (or note one is needed)
8. **Review**: direct opener? code blocks fenced with language? all images alt-texted?
docs links present? closing matches type convention? categories correct?

## Publishing

When ready to publish, set the post date to today and rename the directory:

```bash
quarto run _tools/publish-date.ts docs/blog/posts/YYYY-MM-DD-slug
```

This updates `date:` in frontmatter and renames the directory to match. Run it
on the day you intend to merge — avoids manual date edits if the publish date slips.

## PR Workflow

PR to `main` first. On merge, auto-backport creates cherry-pick PR to `prerelease`.
Push branches to `upstream` remote (quarto-dev/quarto-web), not `origin`.
99 changes: 99 additions & 0 deletions .claude/skills/blog-post/references/post-types.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# Post Type Reference

Detailed structure guidance for each blog post type. Read the section that matches
your post — you rarely need all four.

## Release Announcements

The most structured type. Readers expect consistency across releases.

**Opening**: One direct sentence announcing the release, immediately followed by
download and changelog links. No preamble.

```markdown
Quarto 1.9 is out! You can get the current release from the
[download page](/docs/download/index.qmd). Read the full
[changelog](https://github.com/quarto-dev/quarto-cli/releases/tag/v1.9)
for a complete list of changes.
```

**Feature sections**: Each major feature gets a `##` heading named after the feature
(not "What's New"). Order by importance. Each section:
- Explain in 2-3 sentences
- Code example or screenshot (or both)
- Link to docs: "Learn more at [Feature Name](/docs/path)."

**Other Highlights**: `## Other Highlights` bundles smaller improvements. Format:

```markdown
- [Feature Name](/docs/path)---Short description of what it does.
```

Note the em-dash (`---`) between link and description.

**Dependency updates**: List bundled tool updates (Pandoc, Typst, Deno) after Other
Highlights if applicable.

**Closing**: Always `## Acknowledgements`. Thank contributors. Recent releases use
`{{< include _contribs.md >}}`. Release posts with emoji thumbnails include OpenMoji
attribution at the very end.

**Categories**: Always `Quarto X.Y` + `Releases`.

---

## Feature Announcements

Spotlight a specific feature, often published before the corresponding release. More
varied structure than release posts.

**Opening**: If unreleased, add prerelease callout at the very top:

```markdown
{{< prerelease-callout 1.10 type="blog" >}}
```

Then a direct statement of what the feature does. Get to the point — readers clicked
because the title caught their interest.

**Body**: Organize around the feature's concepts, not a "what's new" list. `##`
headings name the concept being explained.

Problem/Solution framing works well for features that address a pain point: explain
the problem first, then show how the feature solves it.

**Closing**: Link to the documentation. "Learn more on the [Feature Name](/docs/path)
page." No acknowledgements section.

---

## Technical How-to Posts

Tutorial-style walkthroughs.

**Opening**: If based on a talk or repost, start with a `.callout-tip` providing context
and linking the original source. Then frame the use case — what problem does the reader
have?

**Body**: Walk through steps sequentially. Heading names can be conversational — verbs
and questions are fine ("Create the content", "Why are we doing this?"). Use numbered
sub-steps when sequence matters.

Show before/after comparisons with `{layout-ncol="2"}` divs.

**Closing**: Brief summary of what was covered, or a "Learn more" section with resource
links. No acknowledgements.

---

## News/Community Posts

Short announcements, conference roundups, workshop materials. The lightest type.

**Opening**: One direct summary sentence.

**Body**: Often visual grids rather than prose. Conference roundups use
`{layout="[70,30]"}` divs pairing descriptions with thumbnails. Video posts embed
with `{{< video >}}`.

**Closing**: May have no explicit closing — the content structure speaks for itself.
Loading
Loading