Initial commit
This commit is contained in:
409
skills/release-post/references/content-guidelines.md
Normal file
409
skills/release-post/references/content-guidelines.md
Normal file
@@ -0,0 +1,409 @@
|
||||
# Content Guidelines for Release Posts
|
||||
|
||||
General best practices for release post content, regardless of blog platform. These guidelines are based primarily on Tidyverse blog conventions, which provide a principled approach to announcing package updates.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
1. [Post Structure](#post-structure)
|
||||
2. [Opening Style](#opening-style)
|
||||
3. [Section Organization](#section-organization)
|
||||
4. [Tone and Voice](#tone-and-voice)
|
||||
5. [Code Examples](#code-examples)
|
||||
6. [Acknowledgments](#acknowledgments)
|
||||
|
||||
## Post Structure
|
||||
|
||||
Standard structure for release posts:
|
||||
|
||||
```markdown
|
||||
[Frontmatter - see formatting guides]
|
||||
|
||||
# Package Version
|
||||
|
||||
[Opening paragraph with package description]
|
||||
|
||||
[Installation instructions]
|
||||
|
||||
[Overview paragraph about the release]
|
||||
|
||||
## Major Feature 1
|
||||
[Content...]
|
||||
|
||||
## Major Feature 2
|
||||
[Content...]
|
||||
|
||||
## Minor improvements
|
||||
[Bulleted list...]
|
||||
|
||||
## Acknowledgements
|
||||
[Contributor list]
|
||||
```
|
||||
|
||||
## Opening Style
|
||||
|
||||
### Opening Paragraph Pattern
|
||||
|
||||
Start with an announcement that establishes the package's core purpose:
|
||||
|
||||
> "We're [pleased/chuffed/stoked/thrilled/delighted/excited/...] to announce the release of [package] [version]. [Package] [core purpose description in one sentence]."
|
||||
|
||||
**Examples:**
|
||||
- "We're chuffed to announce the release of testthat 3.3.0. testthat makes it easy to turn your existing informal tests into formal, automated tests"
|
||||
- "We're pleased to announce the release of pkgdown 2.2.0. pkgdown is designed to make it quick and easy to build a beautiful and accessible website"
|
||||
- "We're excited to announce the new Shiny extension for VS Code!"
|
||||
|
||||
**Vocabulary variations:**
|
||||
- Choose an upbeat and random adjective with connotations of excitement.
|
||||
- Be interesting and bold, but above all positive and fun.
|
||||
|
||||
### Installation Instructions
|
||||
|
||||
Follow the opening with installation instructions as a code block:
|
||||
|
||||
**R packages:**
|
||||
```r
|
||||
install.packages("packagename")
|
||||
```
|
||||
|
||||
For multiple packages:
|
||||
```r
|
||||
install.packages(c("shiny", "bslib"))
|
||||
```
|
||||
|
||||
**Python packages:**
|
||||
```bash
|
||||
pip install packagename
|
||||
```
|
||||
|
||||
With extras:
|
||||
```bash
|
||||
pip install "packagename[extra]"
|
||||
```
|
||||
|
||||
### Overview Paragraph
|
||||
|
||||
Brief overview of the release following installation:
|
||||
|
||||
- Link to full release notes when available
|
||||
- Highlight focus areas: "This release focuses on [key themes]"
|
||||
- Set expectations: "This is a [major/minor] release with [X main features]"
|
||||
- Acknowledge breaking changes: "This release includes a number of new features... Some of these changes may require you to update your existing code"
|
||||
|
||||
## Section Organization
|
||||
|
||||
### Standard Section Hierarchy
|
||||
|
||||
Organize content in this order:
|
||||
|
||||
1. **Migration guide** (if breaking changes)
|
||||
- Put this first when there are breaking changes
|
||||
- Use clear before/after examples
|
||||
- Explain the rationale for changes
|
||||
|
||||
2. **Lifecycle changes** (if applicable but not breaking)
|
||||
- Soft deprecations
|
||||
- Deprecations
|
||||
- Defunct (removed) functions
|
||||
- Non-breaking behavioral changes
|
||||
|
||||
3. **Major new features** (primary content)
|
||||
- One section per major feature or theme
|
||||
- Use descriptive headings
|
||||
- Lead with what the feature does and why it matters
|
||||
- Include examples
|
||||
|
||||
4. **Minor improvements** or **Other new features**
|
||||
- Bulleted list of smaller enhancements
|
||||
- Brief explanations
|
||||
- Can group related items
|
||||
|
||||
5. **Acknowledgements** (always final)
|
||||
- Thank contributors
|
||||
- List all contributors with GitHub links
|
||||
|
||||
### Section Heading Style
|
||||
|
||||
- Use sentence case: "Lifecycle changes" not "Lifecycle Changes"
|
||||
- Be descriptive: "Easier `in_parallel()`" not just "New feature"
|
||||
- Include function names in backticks when relevant
|
||||
- Make headings scannable and informative
|
||||
|
||||
### Content Organization Within Sections
|
||||
|
||||
**For migration guides:**
|
||||
```markdown
|
||||
## Migrating to vX.Y.Z
|
||||
|
||||
### Setting the app theme
|
||||
|
||||
Prior to vX.Y.Z, you could...
|
||||
|
||||
[Before example]
|
||||
|
||||
**With packagename vX.Y.Z,** you now need to...
|
||||
|
||||
[After example]
|
||||
|
||||
Read about [the feature](#feature) below to learn why this change was needed.
|
||||
```
|
||||
|
||||
**For lifecycle changes:**
|
||||
```markdown
|
||||
## Lifecycle changes
|
||||
|
||||
* **Fully removed** after 5+ years of deprecation:
|
||||
* `function1()` - use `replacement1()` instead
|
||||
* `function2()` - use `replacement2()` instead
|
||||
|
||||
* **Newly deprecated** (soft-deprecation):
|
||||
* `function3()` is superseded by `function4()`
|
||||
* `function5()` is no longer recommended
|
||||
|
||||
* **Breaking changes**:
|
||||
* Brief description of the change and impact
|
||||
```
|
||||
|
||||
**For feature sections:**
|
||||
- Lead with a clear description of what the feature does
|
||||
- Provide context on why it's useful or what problem it solves
|
||||
- Include code examples showing usage
|
||||
- Explain configuration options if relevant
|
||||
- Link to relevant documentation
|
||||
|
||||
### Deep Dives on Features
|
||||
|
||||
Don't just list features from NEWS—research them and provide comprehensive explanations:
|
||||
|
||||
**Transform NEWS bullets into complete sections:**
|
||||
|
||||
1. **Research the feature**:
|
||||
- Read function documentation
|
||||
- Check related PRs and issues for context
|
||||
- Understand the motivation and use cases
|
||||
|
||||
2. **Add complete code examples**:
|
||||
- Show realistic usage, not just function signatures
|
||||
- Include comments explaining what's happening
|
||||
- Demonstrate the full workflow, not just isolated calls
|
||||
|
||||
3. **Explain the context**:
|
||||
- Why was this feature added?
|
||||
- What problem does it solve?
|
||||
- What are the practical use cases?
|
||||
- How does it fit into typical workflows?
|
||||
|
||||
4. **Show use cases and applications**:
|
||||
- Provide examples of when users would need this
|
||||
- Explain different configuration options
|
||||
- Show how features work together
|
||||
|
||||
**Example transformation:**
|
||||
|
||||
❌ **NEWS bullet approach:**
|
||||
```markdown
|
||||
## Bookmarking
|
||||
- Added `chat_restore()` for bookmarking support (#82)
|
||||
```
|
||||
|
||||
✅ **Deep dive approach:**
|
||||
```markdown
|
||||
### Bookmarking support
|
||||
|
||||
shinychat now supports Shiny's bookmarking feature for saving and restoring chat sessions.
|
||||
The new `chat_restore()` function saves the chat client state and restores the message history:
|
||||
|
||||
[Complete code example showing actual usage]
|
||||
|
||||
By default, `chat_restore()` automatically updates the bookmark when users submit messages
|
||||
and when the LLM completes its response. This means users can refresh the page or share a
|
||||
URL and pick up right where they left off.
|
||||
|
||||
For apps with large chat histories, you can use `enableBookmarking = "server"` to store
|
||||
state server-side without URL size limitations.
|
||||
```
|
||||
|
||||
**Research sources:**
|
||||
- Use `r-btw` tools to read R function documentation
|
||||
- Read GitHub PRs/issues linked in NEWS
|
||||
- Check package vignettes and articles
|
||||
- Look at example apps in the repository
|
||||
|
||||
**For improvements:**
|
||||
```markdown
|
||||
## Minor improvements
|
||||
|
||||
* Brief description of improvement with function name in backticks
|
||||
* Another improvement with relevant technical details
|
||||
* Performance gains quantified when possible (e.g., "2x faster")
|
||||
```
|
||||
|
||||
## Tone and Voice
|
||||
|
||||
### Writing Style
|
||||
|
||||
- **Conversational but professional**: "We're excited to announce" rather than "It is announced"
|
||||
- **Inclusive**: Use "we" and "you" rather than passive voice
|
||||
- **Enthusiastic but authentic**: Avoid over-the-top marketing language
|
||||
- **Technical precision**: Use exact function names, parameter names, and technical terms
|
||||
- **Focus on benefits**: Explain the "why" not just the "what"
|
||||
|
||||
### Avoiding Marketing Speak
|
||||
|
||||
Release posts should be friendly and instructional, not advertising. Watch for and remove:
|
||||
|
||||
**Superlatives and promotional adjectives:**
|
||||
- ❌ "powerful set of features", "rich, interactive displays", "beautiful interface"
|
||||
- ✅ "set of features", "interactive displays", "interface"
|
||||
|
||||
**Exaggerated benefit claims:**
|
||||
- ❌ "handles all the complexity of persisting state"
|
||||
- ✅ "saves the chat client state and restores the message history"
|
||||
|
||||
**Generic enthusiasm:**
|
||||
- ❌ "opens up exciting possibilities for building transparent, user-friendly AI applications"
|
||||
- ✅ Direct description of what the feature does
|
||||
|
||||
**Over-hyped capability statements:**
|
||||
- ❌ "give you fine-grained control over every aspect"
|
||||
- ✅ "lets you control the chat interface"
|
||||
|
||||
**Tone review checklist:**
|
||||
- [ ] Remove words like "powerful", "robust", "seamless", "elegant", "revolutionary"
|
||||
- [ ] Replace "makes it easy to" with direct descriptions of functionality
|
||||
- [ ] Prefer descriptive statements focusing on what the function does
|
||||
- [ ] Avoid overuse of phrases that sound like product marketing ("best-in-class", "production-ready")
|
||||
|
||||
|
||||
### Common Phrases
|
||||
|
||||
- "We're [emotion] to announce..."
|
||||
- "A big thank you to all the folks who helped make this release happen"
|
||||
- "You can see a full list of changes in the release notes"
|
||||
- "This makes it easier to..."
|
||||
- "We've improved..."
|
||||
- "This release focuses on..."
|
||||
- "Prior to vX.Y.Z, you had to..."
|
||||
- "With this release, you can now..."
|
||||
|
||||
### Technical Voice
|
||||
|
||||
- Use backticks for all code elements: `` `function()` ``, `` `argument` ``, `` `"value"` ``
|
||||
- Link to relevant documentation when helpful
|
||||
- Be specific about behavior: "returns `NULL`" not "returns nothing"
|
||||
- Explain technical decisions when they impact users
|
||||
- Acknowledge tradeoffs when present
|
||||
|
||||
## Code Examples
|
||||
|
||||
### Explain Concepts Before Code
|
||||
|
||||
For features that introduce new or unfamiliar concepts, explain the concept first before showing code:
|
||||
|
||||
**Pattern: Concept → How it works → Why it matters → Code**
|
||||
|
||||
1. **What is the feature/concept?** (1-2 sentences)
|
||||
2. **How does it work?** (Especially non-obvious aspects)
|
||||
3. **Why does it matter?** (Practical implications)
|
||||
4. **Show the code** (With examples)
|
||||
|
||||
**Key principles:**
|
||||
- Assume readers may not be familiar with the concept
|
||||
- Explain non-obvious aspects clearly
|
||||
- Connect concepts to practical outcomes
|
||||
- Use plain language before technical language
|
||||
|
||||
### Inline Code
|
||||
|
||||
- Function names: `` `map_chr()` ``
|
||||
- Arguments: `` `na.rm = TRUE` ``
|
||||
- Values: `` `NULL` ``, `` `TRUE` ``, `` `"string"` ``
|
||||
- File paths: `` `app.py` ``
|
||||
|
||||
### Code Block Principles
|
||||
|
||||
- Use realistic but simple examples
|
||||
- Include expected output when relevant
|
||||
- Show error messages for examples of better error handling
|
||||
- Format multi-line function calls with proper indentation
|
||||
- Add comments for clarity when needed: `# This does X`
|
||||
- Keep examples focused on the feature being demonstrated
|
||||
|
||||
### Before/After Examples
|
||||
|
||||
When showing improvements, use clear before/after structure:
|
||||
|
||||
```markdown
|
||||
Previously, you had to write:
|
||||
|
||||
[Code block showing old approach]
|
||||
|
||||
Now you can write:
|
||||
|
||||
[Code block showing new approach]
|
||||
```
|
||||
|
||||
Or for migration guides:
|
||||
|
||||
```markdown
|
||||
**Before:**
|
||||
|
||||
[Old code]
|
||||
|
||||
**After:**
|
||||
|
||||
[New code]
|
||||
```
|
||||
|
||||
## Acknowledgments
|
||||
|
||||
### When to Include
|
||||
|
||||
- **Always include** for package releases with external contributors
|
||||
- Optional for internal tooling announcements
|
||||
- Include at the end as the final section
|
||||
|
||||
### Section Format
|
||||
|
||||
```markdown
|
||||
## Acknowledgements
|
||||
|
||||
A big thank you to all [the folks/everyone] who [helped make this release happen/contributed to this release]:
|
||||
|
||||
[@username1](https://github.com/username1), [@username2](https://github.com/username2), ...
|
||||
```
|
||||
|
||||
### Fetching Contributors
|
||||
|
||||
Use `usethis::use_tidy_thanks()` in R:
|
||||
|
||||
```r
|
||||
# From last release to current
|
||||
usethis::use_tidy_thanks("owner/repo")
|
||||
|
||||
# From specific tag/SHA
|
||||
usethis::use_tidy_thanks("owner/repo", from = "v1.0.0")
|
||||
```
|
||||
|
||||
This generates properly formatted markdown for the contributor list that can be included verbatim.
|
||||
|
||||
## Transforming NEWS to Blog Content
|
||||
|
||||
When converting NEWS.md entries to blog post format:
|
||||
|
||||
1. **Expand context**: Technical bullets become paragraphs explaining why changes matter
|
||||
2. **Add examples**: Include code demonstrating new features or changes
|
||||
3. **Group thematically**: Combine scattered NEWS items into coherent sections
|
||||
4. **Use conversational tone**: Transform terse bullets into readable prose
|
||||
5. **Link proactively**: Add links to relevant documentation and resources
|
||||
6. **Focus on user impact**: Explain how changes affect typical usage
|
||||
7. **Highlight breaking changes**: Make migration paths clear and prominent
|
||||
|
||||
## Release Notes Link
|
||||
|
||||
Always include a link to full release notes:
|
||||
|
||||
```markdown
|
||||
You can see a full list of changes in the [release notes](url).
|
||||
```
|
||||
|
||||
This allows readers to find exhaustive details while keeping the blog post focused and readable.
|
||||
606
skills/release-post/references/shiny-formatting.md
Normal file
606
skills/release-post/references/shiny-formatting.md
Normal file
@@ -0,0 +1,606 @@
|
||||
# Shiny Blog Formatting Conventions
|
||||
|
||||
Shiny-specific formatting requirements for blog posts on shiny.posit.co. These conventions are for the Quarto-based Shiny blog.
|
||||
|
||||
## Frontmatter Format
|
||||
|
||||
Shiny blog posts use Quarto YAML frontmatter with this structure:
|
||||
|
||||
```yaml
|
||||
---
|
||||
title: Package Name Version
|
||||
description: &desc |
|
||||
Brief description of the package and release.
|
||||
author: "Author Name"
|
||||
date: "YYYY-MM-DD"
|
||||
|
||||
image: &img feature.png
|
||||
|
||||
open-graph:
|
||||
image: *img
|
||||
description: *desc
|
||||
twitter-card:
|
||||
image: *img
|
||||
description: *desc
|
||||
---
|
||||
```
|
||||
|
||||
### Required Fields
|
||||
|
||||
- **`title`**: Display title (no specific format required, flexible)
|
||||
- Can be: `"packagename version"`, `"Package Name x.y.z"`, or descriptive
|
||||
- Examples:
|
||||
- `"shinyswatch 0.7.0"`
|
||||
- `"Reintroducing the Shiny Extension for VS Code"`
|
||||
- `"Branded theming for Shiny for Python apps"`
|
||||
- **`description`**: Brief summary with YAML anchor for reuse
|
||||
- Use `&desc` anchor and `|` for multi-line
|
||||
- Reuse in social media cards with `*desc`
|
||||
- **`author`**: Author name in quotes (can be single string or array)
|
||||
- Single: `"Garrick Aden-Buie"`
|
||||
- Multiple: `["Author One", "Author Two"]`
|
||||
- **`date`**: ISO format in quotes `"YYYY-MM-DD"`
|
||||
- **`image`**: Path to featured image (relative to post directory)
|
||||
|
||||
### Social Media Cards
|
||||
|
||||
Use YAML anchors to avoid repeating the description:
|
||||
|
||||
```yaml
|
||||
description: &desc |
|
||||
Your description here that will be reused.
|
||||
|
||||
open-graph:
|
||||
description: *desc
|
||||
twitter-card:
|
||||
description: *desc
|
||||
```
|
||||
|
||||
The `&desc` creates an anchor, and `*desc` references it.
|
||||
|
||||
### Optional But Common Fields
|
||||
|
||||
- **`filters`**: Quarto filters to use
|
||||
- `shinylive` - For embedding Shinylive apps
|
||||
- `line-highlight` - For highlighting specific lines
|
||||
- **`engine`**: Quarto engine (`knitr`, `markdown`, `jupyter`)
|
||||
- **`freeze`**: Set to `true` if the post includes *any* computational output
|
||||
- **`format`**: HTML format options
|
||||
- `code-link: true` - Enable code linking
|
||||
- `anchor-sections: true` - Enable section anchors
|
||||
- `reference-location: document` or `section` - Where to place footnotes
|
||||
- **`code-annotations`**: Set to `hover` for hover annotations
|
||||
- **`editor`**: Editor options like `render-on-save: true`
|
||||
|
||||
### Image Options
|
||||
|
||||
Additional image control fields:
|
||||
|
||||
```yaml
|
||||
image: feature.svg
|
||||
imagealt: "Alternative text for image"
|
||||
image-header-disable: true # Don't show image in header
|
||||
```
|
||||
|
||||
### What's NOT Included
|
||||
|
||||
Unlike Tidyverse posts, Shiny posts do **not** include:
|
||||
|
||||
- `output: hugodown::hugo_document`
|
||||
- `slug` (filename determines URL)
|
||||
- `photo.url` and `photo.author` (different image structure)
|
||||
- Consistent `categories` field (optional, varies by post)
|
||||
|
||||
## Title Format
|
||||
|
||||
The main title can be flexible:
|
||||
|
||||
```markdown
|
||||
# packagename version
|
||||
```
|
||||
|
||||
Or more descriptive:
|
||||
|
||||
```markdown
|
||||
# Reintroducing the Shiny Extension for VS Code
|
||||
```
|
||||
|
||||
There's less rigid formatting for titles in Shiny posts.
|
||||
|
||||
## Lead Paragraphs
|
||||
|
||||
Shiny posts may use a lead paragraph div for emphasis:
|
||||
|
||||
```markdown
|
||||
::: lead
|
||||
**We're excited to announce the new Shiny extension for VS Code!**
|
||||
:::
|
||||
```
|
||||
|
||||
This creates a larger, emphasized opening paragraph.
|
||||
|
||||
## Code Formatting
|
||||
|
||||
### For Python Packages
|
||||
|
||||
Use bash code blocks for installation:
|
||||
|
||||
````markdown
|
||||
```bash
|
||||
pip install packagename
|
||||
```
|
||||
````
|
||||
|
||||
With extras:
|
||||
|
||||
````markdown
|
||||
```bash
|
||||
pip install "packagename[extra]"
|
||||
```
|
||||
````
|
||||
|
||||
### For R Packages
|
||||
|
||||
Use R code blocks:
|
||||
|
||||
````markdown
|
||||
```r
|
||||
install.packages("packagename")
|
||||
```
|
||||
````
|
||||
|
||||
For multiple packages:
|
||||
|
||||
````markdown
|
||||
```r
|
||||
install.packages(c("shiny", "bslib"))
|
||||
```
|
||||
````
|
||||
|
||||
### Code Block Attributes
|
||||
|
||||
Shiny posts use Quarto code block attributes:
|
||||
|
||||
````markdown
|
||||
```{.python filename="app.py"}
|
||||
from shiny import App
|
||||
|
||||
# code here
|
||||
```
|
||||
````
|
||||
|
||||
````markdown
|
||||
```{r install-bslib}
|
||||
#| eval: false
|
||||
install.packages("bslib")
|
||||
```
|
||||
````
|
||||
|
||||
### Line Highlighting
|
||||
|
||||
Use `# <<` comments to highlight lines (requires `line-highlight` filter):
|
||||
|
||||
````markdown
|
||||
```{.python filename="app.py"}
|
||||
from shiny.express import ui
|
||||
import shinyswatch
|
||||
|
||||
ui.page_opts(theme=shinyswatch.theme.darkly) # <<
|
||||
|
||||
# rest of code...
|
||||
```
|
||||
````
|
||||
|
||||
### Code Annotations
|
||||
|
||||
With `code-annotations: hover` in frontmatter, you can add annotations:
|
||||
|
||||
```python
|
||||
result = some_function() # <1>
|
||||
```
|
||||
|
||||
```markdown
|
||||
1. This annotation explains the line above
|
||||
```
|
||||
|
||||
## Tabsets for Multiple Variants
|
||||
|
||||
Shiny posts frequently use tabsets to show Express vs Core mode or Python vs R:
|
||||
|
||||
````markdown
|
||||
::: {.panel-tabset .shiny-mode-tabset group="shiny-app-mode"}
|
||||
#### Express
|
||||
|
||||
```{.python filename="app.py"}
|
||||
from shiny.express import ui
|
||||
# Express code
|
||||
```
|
||||
|
||||
#### Core
|
||||
|
||||
```{.python filename="app.py"}
|
||||
from shiny import ui
|
||||
# Core code
|
||||
```
|
||||
:::
|
||||
````
|
||||
|
||||
### Nested Tabsets
|
||||
|
||||
You can nest tabsets for Before/After within Express/Core:
|
||||
|
||||
````markdown
|
||||
::: {.panel-tabset group="shiny-app-mode"}
|
||||
#### Express
|
||||
|
||||
::: {.panel-tabset}
|
||||
##### Before
|
||||
|
||||
```python
|
||||
# old code
|
||||
```
|
||||
|
||||
##### After
|
||||
|
||||
```python
|
||||
# new code
|
||||
```
|
||||
:::
|
||||
|
||||
#### Core
|
||||
|
||||
::: {.panel-tabset}
|
||||
##### Before
|
||||
|
||||
```python
|
||||
# old code
|
||||
```
|
||||
|
||||
##### After
|
||||
|
||||
```python
|
||||
# new code
|
||||
```
|
||||
:::
|
||||
:::
|
||||
````
|
||||
|
||||
## Callouts
|
||||
|
||||
Quarto callouts for notes, tips, warnings:
|
||||
|
||||
```markdown
|
||||
::: {.callout-tip title="Writing brand.yml with the help of an LLM"}
|
||||
We know that writing YAML isn't everyone's cup of tea!
|
||||
...
|
||||
:::
|
||||
```
|
||||
|
||||
Types: `note`, `tip`, `warning`, `caution`, `important`
|
||||
|
||||
## Embedded Media
|
||||
|
||||
### Videos
|
||||
|
||||
````markdown
|
||||
::: column-page
|
||||
```{=html}
|
||||
<video controls>
|
||||
<source src="videos/demo.webm" type="video/webm">
|
||||
<source src="videos/demo.mp4" type="video/mp4">
|
||||
</video>
|
||||
```
|
||||
:::
|
||||
````
|
||||
|
||||
### Images with Attributes
|
||||
|
||||
```markdown
|
||||
{.shadow}
|
||||
```
|
||||
|
||||
Or with more attributes:
|
||||
|
||||
```markdown
|
||||
{fig-alt="Detailed alt text" fig-align="center" width="100%"}
|
||||
```
|
||||
|
||||
## Shinylive Examples
|
||||
|
||||
With the `shinylive` filter, you can embed live examples:
|
||||
|
||||
````markdown
|
||||
```{shinylive-python}
|
||||
#| standalone: true
|
||||
#| components: [editor, viewer]
|
||||
|
||||
## file: app.py
|
||||
from shiny.express import input, render, ui
|
||||
|
||||
# App code here
|
||||
```
|
||||
````
|
||||
|
||||
Or link to examples:
|
||||
|
||||
```markdown
|
||||
We've added a [complete branded theming example](https://shinylive.io/py/examples/#branded-theming) to shinylive.io.
|
||||
```
|
||||
|
||||
## Acknowledgements Section
|
||||
|
||||
Less consistent in Shiny posts. When present, variations include:
|
||||
|
||||
### Variation 1: Simple Thanks
|
||||
|
||||
```markdown
|
||||
## Thanks!
|
||||
|
||||
Thank you for trying out the Shiny extension for VS Code!
|
||||
If you find it helpful, please rate the extension on [the marketplace][Shiny extension].
|
||||
```
|
||||
|
||||
### Variation 2: Multiple Package Releases
|
||||
|
||||
```markdown
|
||||
## Release notes
|
||||
|
||||
**Big shout out to everyone involved!** 💙
|
||||
We'd want to extend a huge thank you to everyone who contributed pull requests, bug reports and feature requests.
|
||||
|
||||
#### bslib [v0.7.0](https://rstudio.github.io/bslib/news/index.html#bslib-070)
|
||||
|
||||
[List of contributors]
|
||||
|
||||
#### shiny [v1.8.1](https://shiny.posit.co/r/reference/shiny/1.8.1/upgrade.html)
|
||||
|
||||
[List of contributors]
|
||||
```
|
||||
|
||||
### Variation 3: Omitted
|
||||
|
||||
Some Shiny posts don't include acknowledgements, especially for announcements of tools rather than package releases.
|
||||
|
||||
### When Acknowledgements Are Included
|
||||
|
||||
Use similar format to Tidyverse:
|
||||
|
||||
```markdown
|
||||
## Acknowledgements
|
||||
|
||||
We'd like to thank everyone who contributed to this release:
|
||||
|
||||
[@user1](https://github.com/user1), [@user2](https://github.com/user2), and [@user3](https://github.com/user3).
|
||||
```
|
||||
|
||||
Or just reference the generator in code:
|
||||
|
||||
```markdown
|
||||
```{r}
|
||||
#| echo: false
|
||||
#| eval: false
|
||||
usethis::use_tidy_thanks("rstudio/bslib", from = "v0.6.1")
|
||||
```
|
||||
```
|
||||
|
||||
## CSS Customization
|
||||
|
||||
Shiny posts may include custom CSS in HTML blocks:
|
||||
|
||||
````markdown
|
||||
```{=html}
|
||||
<style>
|
||||
img { border-radius: 8px; }
|
||||
video {
|
||||
max-width: 100%;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
</style>
|
||||
```
|
||||
````
|
||||
|
||||
## Column Layouts
|
||||
|
||||
Use Quarto's column classes for wider content:
|
||||
|
||||
```markdown
|
||||
::: column-page
|
||||
[Wide content here]
|
||||
:::
|
||||
|
||||
::: column-body-outset
|
||||
[Slightly wider content]
|
||||
:::
|
||||
```
|
||||
|
||||
## Footnotes
|
||||
|
||||
Use standard markdown footnotes:
|
||||
|
||||
```markdown
|
||||
Text with a footnote[^footnote-key].
|
||||
|
||||
[^footnote-key]: This is the footnote text.
|
||||
```
|
||||
|
||||
With `reference-location: document` or `section` in frontmatter to control placement.
|
||||
|
||||
## Links and References
|
||||
|
||||
Define link references at the top or bottom of the file:
|
||||
|
||||
```markdown
|
||||
[brand.yml]: https://posit-dev.github.io/brand-yml
|
||||
[quarto]: https://quarto.org
|
||||
[shiny]: https://shiny.posit.co
|
||||
```
|
||||
|
||||
Then use them inline:
|
||||
|
||||
```markdown
|
||||
We're excited about [brand.yml] support!
|
||||
```
|
||||
|
||||
## Multi-Language Support (R and Python)
|
||||
|
||||
The Shiny blog often covers packages released for both R and Python (e.g., shiny, shinychat). Unlike Tidyverse posts which are language-specific, Shiny posts should show examples in both languages using Quarto tabsets.
|
||||
|
||||
### Use Tabsets Consistently
|
||||
|
||||
Every code example should include both R and Python variants using Quarto tabsets:
|
||||
|
||||
```markdown
|
||||
::: {.panel-tabset group="language"}
|
||||
## R
|
||||
|
||||
```r
|
||||
# R code here
|
||||
```
|
||||
|
||||
## Python
|
||||
|
||||
```python
|
||||
# Python code here
|
||||
```
|
||||
:::
|
||||
```
|
||||
|
||||
**Guidelines:**
|
||||
- Use `group="language"` to sync all language tabsets on the page
|
||||
- Provide equivalent functionality in both languages
|
||||
- Don't show R-only or Python-only examples unless the feature is language-specific
|
||||
- Keep examples parallel—if the R example shows 5 lines, the Python example should be similar
|
||||
|
||||
### Installation Instructions
|
||||
|
||||
Always show installation for both languages at the start of the post:
|
||||
|
||||
```markdown
|
||||
::: {.panel-tabset group="language"}
|
||||
## R
|
||||
|
||||
```r
|
||||
install.packages("packagename")
|
||||
```
|
||||
|
||||
## Python
|
||||
|
||||
```bash
|
||||
pip install packagename
|
||||
```
|
||||
:::
|
||||
```
|
||||
|
||||
### Language-Specific Features
|
||||
|
||||
When features differ between languages, be explicit about the differences:
|
||||
|
||||
```markdown
|
||||
::: {.panel-tabset group="language"}
|
||||
## R
|
||||
|
||||
In R, use `tool_annotations()` to customize display:
|
||||
|
||||
```r
|
||||
tool_annotations(title = "My Tool", icon = bsicons::bs_icon("star"))
|
||||
```
|
||||
|
||||
## Python
|
||||
|
||||
In Python, use the `._display` attribute:
|
||||
|
||||
```python
|
||||
my_tool._display = {"title": "My Tool", "icon": "star"}
|
||||
```
|
||||
:::
|
||||
```
|
||||
|
||||
### Version Information
|
||||
|
||||
Package versions often differ between R and Python. Be explicit:
|
||||
|
||||
- "Available in shinychat for R (v0.3.0) and shinychat for Python (v0.2.0 or later)"
|
||||
- Link to both language-specific documentation
|
||||
- Include separate release notes links:
|
||||
```markdown
|
||||
You can see the full list of changes in the [R release notes](url) and [Python release notes](url).
|
||||
```
|
||||
|
||||
### When to Use Multi-Language Tabsets
|
||||
|
||||
- **Always use** for packages that have both R and Python versions (shiny, shinychat, querychat, etc.)
|
||||
- **Don't use** for Python-only packages (shinyswatch) or R-only packages
|
||||
- **Don't use** for Tidyverse blog posts (which are built with hugodown/Hugo, not Quarto)
|
||||
|
||||
## Example Complete Frontmatter
|
||||
|
||||
### Python Package
|
||||
|
||||
```yaml
|
||||
---
|
||||
title: shinyswatch 0.7.0
|
||||
description: &desc Customizable shinyswatch themes and an improved theme picker round out shinyswatch v0.7.0.
|
||||
author: "Garrick Aden-Buie"
|
||||
date: "2024-07-19"
|
||||
|
||||
image: feature.jpg
|
||||
|
||||
open-graph:
|
||||
image: feature.jpg
|
||||
description: *desc
|
||||
twitter-card:
|
||||
image: feature.png
|
||||
description: *desc
|
||||
|
||||
filters:
|
||||
- line-highlight
|
||||
---
|
||||
```
|
||||
|
||||
### R Package with Full Options
|
||||
|
||||
```yaml
|
||||
---
|
||||
title: "Shiny for R updates: Extended tasks, JavaScript errors, and many bslib improvements"
|
||||
description: &desc |
|
||||
An overview of recent Shiny for R updates, including extended tasks, JavaScript errors, and many bslib improvements.
|
||||
author:
|
||||
- Carson Sievert
|
||||
date: "2024-03-27"
|
||||
|
||||
image: feature.png
|
||||
|
||||
open-graph:
|
||||
image: feature.png
|
||||
description: *desc
|
||||
twitter-card:
|
||||
image: feature.png
|
||||
description: *desc
|
||||
|
||||
editor:
|
||||
render-on-save: true
|
||||
|
||||
engine: knitr
|
||||
|
||||
filters:
|
||||
- shinylive
|
||||
|
||||
freeze: true
|
||||
|
||||
format:
|
||||
html:
|
||||
code-link: true
|
||||
anchor-sections: true
|
||||
reference-location: section
|
||||
|
||||
code-annotations: hover
|
||||
---
|
||||
```
|
||||
|
||||
## Examples of Well-Formatted Posts
|
||||
|
||||
Reference these posts for formatting examples:
|
||||
- [shinyswatch 0.7.0](https://shiny.posit.co/blog/posts/shinyswatch-0.7.0/)
|
||||
- [Shiny Extension for VS Code 1.0.0](https://shiny.posit.co/blog/posts/shiny-vscode-1.0.0/)
|
||||
- [Shiny for R 1.8.1](https://shiny.posit.co/blog/posts/shiny-r-1.8.1/)
|
||||
- [Branded theming for Shiny for Python](https://shiny.posit.co/blog/posts/shiny-python-1.2-brand-yml/)
|
||||
275
skills/release-post/references/tidyverse-formatting.md
Normal file
275
skills/release-post/references/tidyverse-formatting.md
Normal file
@@ -0,0 +1,275 @@
|
||||
# Tidyverse Blog Formatting Conventions
|
||||
|
||||
Tidyverse-specific formatting requirements for blog posts on tidyverse.org. These conventions are for the hugodown-based Tidyverse blog.
|
||||
|
||||
## Workflow for tidyverse.org Blog
|
||||
|
||||
When creating a blog post for the official `tidyverse/tidyverse.org` repository, follow these steps:
|
||||
|
||||
1. **Install hugodown** (if not already installed):
|
||||
```r
|
||||
pak::pkg_install("r-lib/hugodown")
|
||||
```
|
||||
|
||||
2. **Create a new post**:
|
||||
```r
|
||||
hugodown::use_tidy_post("short-name")
|
||||
```
|
||||
|
||||
This creates `content/blog/short-name/` containing an `index.Rmd` file.
|
||||
|
||||
Common patterns for `"short-name"`:
|
||||
- Package release: `lifecycle-1-0-0`, `parsnip-0-1-2`
|
||||
- Package release with specific topic: `dplyr-1-0-0-rowwise`, `parsnip-adjacent`, `dplyr-1-0-4-if-any`
|
||||
- Topic only: `self-cleaning-test-fixtures`, `taking-control-of-plot-scaling`
|
||||
|
||||
3. **Write and knit**:
|
||||
- Edit the generated `index.Rmd` file
|
||||
- Knit `index.Rmd` to generate `index.md`
|
||||
- Note: `.Rmd` files are only rendered when you explicitly knit them
|
||||
|
||||
4. **Preview the site**:
|
||||
```r
|
||||
hugodown::hugo_start()
|
||||
```
|
||||
This runs once per session and continues in the background to turn `.md` into `.html`.
|
||||
|
||||
5. **Check for outdated files** (if concerned):
|
||||
```r
|
||||
hugodown::site_outdated()
|
||||
```
|
||||
Lists all `.Rmd`s that need to be re-rendered.
|
||||
|
||||
6. **Add a photo**:
|
||||
Every blog post must be accompanied by a photo. If you don't have one in mind, try:
|
||||
- <https://unsplash.com>
|
||||
- <https://pexels.com>
|
||||
- Jenny Bryan's [free photo](https://github.com/jennybc/free-photos) link collection
|
||||
|
||||
7. **Submit PR**:
|
||||
- Every PR gets an automatic live preview via Netlify
|
||||
- Once merged, the preview becomes the live site
|
||||
|
||||
### Important Notes
|
||||
|
||||
- The site uses **hugodown** (not blogdown), which separates building into two steps:
|
||||
- hugodown generates `.md` from `.Rmd`
|
||||
- hugo generates `.html` from `.md`
|
||||
- Use `.Rmd` files (not `.Rmarkdown`)
|
||||
- Output should be `output: hugodown::hugo_document`
|
||||
- If updating an old post to use hugodown:
|
||||
- Rename from `.Rmarkdown` to `.Rmd`
|
||||
- Delete the `.markdown` file
|
||||
- Set `output: hugodown::hugo_document` in YAML metadata
|
||||
|
||||
### For Additional Context
|
||||
|
||||
If you need more details about the workflow or encounter issues, consult the `README.md` in the `tidyverse/tidyverse.org` repository.
|
||||
|
||||
## Frontmatter Format
|
||||
|
||||
Tidyverse blog posts use YAML frontmatter with this structure:
|
||||
|
||||
```yaml
|
||||
---
|
||||
output: hugodown::hugo_document
|
||||
slug: package-name-version
|
||||
title: package-name version
|
||||
date: YYYY-MM-DD
|
||||
author: Author Name
|
||||
description: >
|
||||
Brief description of the package and release
|
||||
photo:
|
||||
url: https://unsplash.com/photos/photo-id
|
||||
author: Photographer Name
|
||||
categories: [package-name]
|
||||
tags: [package-name, category]
|
||||
---
|
||||
```
|
||||
|
||||
### Required Fields
|
||||
|
||||
- **`output`**: Always `hugodown::hugo_document`
|
||||
- **`slug`**: URL slug using hyphens
|
||||
- Format: `packagename-x-y-z` (e.g., `ellmer-0-4-0`)
|
||||
- Replace dots with hyphens in version numbers
|
||||
- **`title`**: Display title with spaces
|
||||
- Format: `packagename x.y.z` (e.g., `ellmer 0.4.0`)
|
||||
- **`date`**: ISO format `YYYY-MM-DD`
|
||||
- **`author`**: Full name of primary author
|
||||
- **`description`**: Brief summary (can use `>` for multi-line)
|
||||
- **`photo`**: Featured image with attribution
|
||||
- `url`: Full URL to image (often Unsplash)
|
||||
- `author`: Photographer name for attribution
|
||||
- **`categories`**: Array with package name
|
||||
- **`tags`**: Array with package name and related tags
|
||||
|
||||
### Slug vs Title Convention
|
||||
|
||||
The slug is used in URLs and must be URL-safe:
|
||||
- Slug: `purrr-1-2-0` (hyphens, no dots)
|
||||
- Title: `purrr 1.2.0` (space, dots in version)
|
||||
|
||||
### Image Attribution
|
||||
|
||||
Featured images are typically from Unsplash with proper photographer attribution:
|
||||
|
||||
```yaml
|
||||
photo:
|
||||
url: https://unsplash.com/photos/abc123
|
||||
author: John Doe
|
||||
```
|
||||
|
||||
## Title Format
|
||||
|
||||
The main title uses a simple format with space between package name and version:
|
||||
|
||||
```markdown
|
||||
# packagename 1.2.0
|
||||
```
|
||||
|
||||
No "released" or "version" prefix. Just the package name and version number.
|
||||
|
||||
## Code Formatting
|
||||
|
||||
### Language Identifiers
|
||||
|
||||
Use triple backticks with `r` language identifier for R code:
|
||||
|
||||
````markdown
|
||||
```r
|
||||
library(packagename)
|
||||
|
||||
result <- function_name(
|
||||
arg1 = "value",
|
||||
arg2 = TRUE
|
||||
)
|
||||
```
|
||||
````
|
||||
|
||||
For installation:
|
||||
````markdown
|
||||
```r
|
||||
install.packages("packagename")
|
||||
```
|
||||
````
|
||||
|
||||
### Inline Code Elements
|
||||
|
||||
- Function names: `` `function()` ``
|
||||
- Packages: `` `{packagename}` `` when emphasizing it's a package
|
||||
- Arguments: `` `arg = value` ``
|
||||
- Values: `` `NULL` ``, `` `TRUE` ``, `` `"string"` ``
|
||||
|
||||
### Function Links
|
||||
|
||||
When linking to function documentation, use markdown links:
|
||||
|
||||
```markdown
|
||||
[`function_name()`](https://url-to-docs)
|
||||
```
|
||||
|
||||
## Section Structure
|
||||
|
||||
### Lifecycle Section Format
|
||||
|
||||
When including lifecycle changes, use this structure:
|
||||
|
||||
```markdown
|
||||
## Lifecycle changes
|
||||
|
||||
* **Fully removed** after 5+ years of deprecation:
|
||||
* `function1()` - use `replacement1()` instead
|
||||
* `function2()` - use `replacement2()` instead
|
||||
|
||||
* **Newly deprecated** (soft-deprecation):
|
||||
* `function3()` is superseded by `function4()`
|
||||
* `function5()` is no longer recommended
|
||||
|
||||
* **Breaking changes**:
|
||||
* Description of what changed and why
|
||||
```
|
||||
|
||||
Use bold for the lifecycle stage labels.
|
||||
|
||||
### Feature Sections
|
||||
|
||||
Use sentence case in headings:
|
||||
|
||||
```markdown
|
||||
## Easier `in_parallel()`
|
||||
|
||||
[Description of the feature...]
|
||||
```
|
||||
|
||||
Include function names in backticks when they're part of the heading.
|
||||
|
||||
## Acknowledgements Section
|
||||
|
||||
Always include as the final section:
|
||||
|
||||
```markdown
|
||||
## Acknowledgements
|
||||
|
||||
A big thank you to all the folks who helped make this release happen:
|
||||
|
||||
[@username1](https://github.com/username1), [@username2](https://github.com/username2), [@username3](https://github.com/username3), and [@username4](https://github.com/username4).
|
||||
```
|
||||
|
||||
### Formatting Rules
|
||||
|
||||
- Single paragraph format (not bulleted list)
|
||||
- GitHub handles as markdown links
|
||||
- Alphabetical order
|
||||
- Comma-separated with "and" before the last name
|
||||
- Period at the end
|
||||
|
||||
### Generating the List
|
||||
|
||||
Use `usethis::use_tidy_thanks()`:
|
||||
|
||||
```r
|
||||
# Fetch contributors since last release
|
||||
usethis::use_tidy_thanks("tidyverse/packagename")
|
||||
|
||||
# Or from specific tag
|
||||
usethis::use_tidy_thanks("tidyverse/packagename", from = "v1.0.0")
|
||||
```
|
||||
|
||||
This function outputs properly formatted markdown that can be copied directly into the blog post.
|
||||
|
||||
## Release Notes Link
|
||||
|
||||
Include a link to the full release notes (typically on pkgdown site):
|
||||
|
||||
```markdown
|
||||
You can see a full list of changes in the [release notes](https://packagename.tidyverse.org/news/).
|
||||
```
|
||||
|
||||
## Example Complete Frontmatter
|
||||
|
||||
```yaml
|
||||
---
|
||||
output: hugodown::hugo_document
|
||||
slug: purrr-1-2-0
|
||||
title: purrr 1.2.0
|
||||
date: 2025-11-04
|
||||
author: Hadley Wickham
|
||||
description: >
|
||||
purrr 1.2.0 includes deprecations and minor enhancements to
|
||||
functional programming tools in R.
|
||||
photo:
|
||||
url: https://unsplash.com/photos/xyz789
|
||||
author: Jane Photographer
|
||||
categories: [purrr]
|
||||
tags: [purrr, tidyverse]
|
||||
---
|
||||
```
|
||||
|
||||
## Examples of Well-Formatted Posts
|
||||
|
||||
Reference these posts for formatting examples:
|
||||
- [pkgdown 2.2.0](https://www.tidyverse.org/blog/2025/11/pkgdown-2-2-0/)
|
||||
- [testthat 3.3.0](https://www.tidyverse.org/blog/2025/11/testthat-3-3-0/)
|
||||
- [purrr 1.2.0](https://www.tidyverse.org/blog/2025/11/purrr-1-2-0/)
|
||||
- [ellmer 0.4.0](https://www.tidyverse.org/blog/2025/11/ellmer-0-4-0/)
|
||||
Reference in New Issue
Block a user