Skip to content

Commit d0bb395

Browse files
HeyItsGilbertclaude
andcommitted
feat(theme): add GitHub-style alert admonitions
Render `> [!NOTE]` / `[!TIP]` / `[!IMPORTANT]` / `[!WARNING]` / `[!CAUTION]` blockquotes as styled callouts via a Goldmark blockquote render hook, with a plain-blockquote fallback for ordinary quotes. Limited to GitHub's five canonical alert types so the same Markdown renders identically in a GitHub issue/PR and on the site, matching the article submission flow. Styling ships in a theme-owned stylesheet. Also adds the how-to-write contributor guide, which dogfoods [!IMPORTANT] and [!TIP]. See docs/adr/0004-github-alert-admonitions.md. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 11dbe87 commit d0bb395

5 files changed

Lines changed: 343 additions & 0 deletions

File tree

Lines changed: 212 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,212 @@
1+
---
2+
title: "How to Write for PowerShell.org"
3+
description: "Two ways to submit an article to PowerShell.org, best practices that get you published faster, and why claiming an author page is worth five minutes of your time."
4+
author: Gilbert Sanchez
5+
authors:
6+
- Gilbert Sanchez
7+
date: "2026-06-23T00:00:00+00:00"
8+
categories:
9+
- Tutorials
10+
tags:
11+
- contributing
12+
- community
13+
- writing
14+
---
15+
16+
There's a thought that stops a lot of good articles: *who am I to write for
17+
PowerShell.org?*
18+
19+
It's our brains safety net from the (highly unlikely) possibility of getting
20+
denied. Or worse! Accepted! And now we're forever on the hook to be an expert.
21+
But it's not true.
22+
23+
You don't need to be an **MVP**. You don't need a **blog**, a **following**, or
24+
a **clever opinion** about the pipeline. You need one thing you figured out that
25+
the documentation didn't explain well. The `-Filter` quirk that cost you and
26+
afternoon. The script that finally tamed a chore you'd been doing by hand for a
27+
year. If it helped you, it'll help someone else who's about to lose the same
28+
afternoon.
29+
30+
> [!IMPORTANT]
31+
> And here's the part that should lower your blood pressure: **nothing you submit
32+
> goes live unreviewed**.
33+
34+
A maintainer reads every submission, helps shape it, and
35+
edits for clarity and formatting before it publishes. You are not flipping a
36+
switch that broadcasts your rough draft to the world. You're starting a
37+
conversation with people who want you to succeed.
38+
39+
So let's get you published. There are two ways in, so pick the one that matches
40+
how comfortable you are with Git because both land in the same place.
41+
42+
## Path A: The GitHub issue (no Git required)
43+
44+
If "fork the repo" already made you tense up, this path is for you. You'll never
45+
touch a command line.
46+
47+
Open the [guest blog post
48+
form](https://github.com/PowerShellOrg/PowerShellOrgWebsite/issues/new?template=guest-blog-post.yml)
49+
and fill it out. The form does the structuring for you. It asks for exactly what
50+
we need and nothing else:
51+
52+
- **Article title** and **your name** as you'd like it displayed.
53+
- **Submission type**, and this is the part people miss: you can choose *"Pitch
54+
-- I'd like feedback before writing."* You don't have to show up with a
55+
finished draft. Float the idea first, and a maintainer will tell you if it's a
56+
fit and help you shape the angle before you spend the writing time.
57+
- **Description**, one or two sentences. This becomes your SEO blurb and social
58+
card, so it earns its keep.
59+
- **Category** and **tags** (more on choosing these well below).
60+
- **Article content**, where you paste your full Markdown if you have a draft.
61+
Leave it blank if you're pitching.
62+
63+
Submit it, and the rest happens in the issue thread. That's the whole path. No
64+
branches, no merge conflicts, no Git vocabulary.
65+
66+
## Path B: The pull request (for the Git-comfortable)
67+
68+
If you already live in Git, you can submit the article directly and watch it
69+
flow through the same review.
70+
71+
1. Fork the repo and create a branch for your article.
72+
2. Add a Markdown file in `content/articles/` using the date-slug naming
73+
convention:
74+
75+
```
76+
content/articles/YYYY-MM-DD-your-article-slug.md
77+
```
78+
79+
3. Start it with this front matter:
80+
81+
```
82+
---
83+
title: "Your Article Title"
84+
description: "A 1-2 sentence summary used for SEO, social cards, and the article list."
85+
author: Your Name
86+
authors:
87+
- Your Name
88+
date: "YYYY-MM-DDT00:00:00+00:00"
89+
categories:
90+
- Category Name
91+
tags:
92+
- tag1
93+
- tag2
94+
---
95+
96+
Your article in Markdown goes here.
97+
```
98+
99+
4. Open a pull request with a short description, and we'll review it there.
100+
101+
> [!TIP]
102+
> Let VS Code do the boring part. Install the [Front Matter
103+
> CMS](https://frontmatter.codes/) extension, open the repo, and run **"Create
104+
> content"** in the `content/articles` folder. It scaffolds the
105+
> `YYYY-MM-DD-slug.md` filename and every front-matter field for you, and it
106+
> gives you a form for the title, description, category, and tags instead of a
107+
> wall of YAML you can typo. It turns the single most error-prone step into a
108+
> fill-in-the-blanks. If you only adopt one tool from this article, make it this
109+
> one.
110+
111+
## Best practices that get you published faster
112+
113+
None of these are gates. They're the small things that mean a maintainer spends
114+
their time on your ideas instead of your formatting.
115+
116+
- **Open by telling readers what they'll walk away with.** A two-sentence intro
117+
that promises a payoff beats a warm-up paragraph every time.
118+
- **Write in Markdown, and fence your code with a language hint.** Use `
119+
```powershell ` so your samples get syntax highlighting instead of a gray
120+
slab.
121+
- **Run your code before you paste it.** A snippet that works on the first try
122+
is the difference between a reader trusting you and a reader closing the tab.
123+
- **Keep the title concrete.** "Speed up your console with PSReadLine predictive
124+
IntelliSense" tells me what I'm getting. "PowerShell tips" tells me nothing.
125+
126+
That's the bar. It's lower than the one in your head.
127+
128+
## Categories and tags are how people find you
129+
130+
It's tempting to treat these as paperwork and pick whatever's first in the list.
131+
Don't. They're the difference between an article that's read once and one that
132+
keeps getting found.
133+
134+
Pick the single **category** that fits best. The current set:
135+
136+
> Announcements - Books - DevOps - Events - Graph - In Case You Missed It -
137+
> News - PowerShell Summit - PowerShell for Admins - PowerShell for Developers -
138+
> Scripting Games - Tips and Tricks - Tools - Training - Tutorials
139+
140+
Category is the big bucket. It's how someone browsing "PowerShell for Admins"
141+
stumbles onto your piece months from now. **Tags** are the specific hooks: the
142+
cmdlets, modules, and concepts your article actually touches (`psreadline`,
143+
`regex`, `azure`, `pester`). Three to five honest, specific tags beat a dozen
144+
vague ones. Tag what's really in the article, not every PowerShell word you can
145+
think of, and your post surfaces next to its actual neighbors.
146+
147+
## Claim your author page
148+
149+
Once you're credited on an article, you can give yourself a real author page at
150+
`/authors/<your-name>/`: an avatar, a tagline, a short bio, and links back to
151+
your own site and socials. Every article you write points back to it. It's a
152+
small, durable corner of the PowerShell community that's *yours*, and it builds
153+
with each post.
154+
155+
It's opt-in. Skip it and your byline still works exactly as before. But it takes
156+
about five minutes, so why leave it on the table? You can see an example of mine
157+
at the bottom.
158+
159+
Your profile is a single file at `content/authors/<slug>/_index.md`. The one
160+
rule that trips people up: the `<slug>` has to match your byline exactly
161+
(lowercased, spaces to hyphens), or the page attaches to nothing.
162+
163+
So let the helper script handle it:
164+
165+
```powershell
166+
./tools/new-author.ps1 "Jane Doe"
167+
```
168+
169+
That scaffolds `content/authors/jane-doe/_index.md` with every field commented.
170+
Fill in what you want, delete the rest:
171+
172+
```yaml
173+
---
174+
title: "Jane Doe" # required -- keep this as your byline name
175+
preferred_name: "Jane" # optional -- changes only how your name displays
176+
tagline: "Cloud automation, mostly."
177+
gravatar_hash: "..." # MD5 of your lowercased email -- keeps your email private
178+
github: "https://github.com/janedoe"
179+
website: "https://janedoe.dev"
180+
# twitter / mastodon / linkedin / bluesky also supported
181+
---
182+
183+
Your bio in Markdown goes here.
184+
```
185+
186+
One thoughtful detail worth calling out: you can set an avatar **without**
187+
putting your email address in a public repo. Store the MD5 hash of your
188+
lowercased email as `gravatar_hash`, and Gravatar serves your picture while your
189+
email stays private:
190+
191+
```powershell
192+
$email = "jane@example.com"
193+
[System.BitConverter]::ToString(
194+
[System.Security.Cryptography.MD5]::Create().ComputeHash(
195+
[System.Text.Encoding]::UTF8.GetBytes($email.Trim().ToLowerInvariant())
196+
)
197+
).Replace("-", "").ToLowerInvariant()
198+
```
199+
200+
And if your name ever changes, `./tools/new-author.ps1 "Old Name" -To "New Name"`
201+
rewrites your byline across every article and adds a redirect so your old
202+
profile URL keeps working. Open a PR with the result.
203+
204+
## Your turn
205+
206+
The whole point of PowerShell.org is that it's built by the people who use
207+
PowerShell, and that includes you. You don't have to be sure it's good enough.
208+
That's literally what the review is for. Pitch the idea, paste the draft, or
209+
send the PR, and you won't be doing it alone. There's a community on the other
210+
side of that submit button that wants to help you get it across the line.
211+
212+
[Start here.](https://github.com/PowerShellOrg/PowerShellOrgWebsite/issues/new?template=guest-blog-post.yml)
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# Admonitions are GitHub-style alerts, capped at GitHub's five canonical types
2+
3+
Callouts on the site are authored with GitHub's alert syntax — `> [!NOTE]`,
4+
`> [!TIP]`, `> [!IMPORTANT]`, `> [!WARNING]`, `> [!CAUTION]` — and rendered by a
5+
Goldmark blockquote render hook (`themes/powershell-community/layouts/_markup/render-blockquote.html`)
6+
into styled callouts, with the look defined in
7+
`themes/powershell-community/static/css/alerts.css`.
8+
9+
The load-bearing constraint is the **contribution model**: an [[Author]] submits
10+
an article either as plain Markdown pasted into a GitHub issue (the no-Git path)
11+
or as a Markdown file in a pull request. In both, the Markdown is read on GitHub
12+
*before* it is ever read on the site. The admonition syntax therefore has to
13+
render identically in both places. GitHub natively renders exactly five alert
14+
types and nothing else; any sixth type degrades on GitHub to a plain blockquote
15+
with a literal `[!SUCCESS]` first line. So the syntax choice and the type set are
16+
the same decision: pick the form GitHub already understands, and support only the
17+
types GitHub renders.
18+
19+
## Considered options
20+
21+
- **Hugo shortcodes** (`{{< note >}}…{{< /note >}}`, matching the existing
22+
`terminal` shortcode) — rejected. It is the established convention here, but a
23+
shortcode renders as literal `{{< note >}}` text in a GitHub issue or PR diff,
24+
which is exactly where submissions are first read. It also asks plain-Markdown
25+
authors to learn a Hugo-specific construct.
26+
- **GitHub-style alerts, full Blowfish vocabulary** (~14 types + aliases like
27+
`tldr`, `hint`, `done`) — rejected. The richer palette renders on the site but
28+
silently breaks the GitHub round-trip for every type beyond the canonical five.
29+
An author who learns `[!SUCCESS]` from our docs and sees a broken blockquote in
30+
their own issue is a worse outcome than not having `success` at all.
31+
- **Front Matter CMS snippets** — not an alternative to the above so much as a
32+
layer on top; a snippet still has to emit *some* markup. Deferred. If added
33+
later it should emit the `> [!NOTE]` syntax, not a shortcode.
34+
- **GitHub-style alerts, canonical five only** — chosen. The same Markdown reads
35+
correctly in the issue form, the PR diff, and the published page.
36+
37+
## Consequences
38+
39+
- **The vocabulary is capped at five** (`note`, `tip`, `important`, `warning`,
40+
`caution`). This is a deliberate ceiling, not an oversight — a future
41+
maintainer who wants `[!SUCCESS]` or `[!QUOTE]` is reintroducing the GitHub
42+
degradation this record exists to prevent. The render hook keeps a type→icon
43+
map so adding a type is mechanically a one-line change; the reason *not* to is
44+
recorded here.
45+
- **The `terminal` shortcode convention was deliberately not extended.** Callouts
46+
and code-terminals now use two different mechanisms (render hook vs. shortcode).
47+
That inconsistency is intentional: `terminal` is site-only chrome with no GitHub
48+
round-trip to honor, whereas callouts must survive it.
49+
- **The render hook owns every blockquote on the site.** It must branch on
50+
`.Type == "alert"` and fall through to a plain `<blockquote>` for ordinary
51+
quotes, or all non-alert blockquotes break. Plain blockquotes-as-containers
52+
(e.g. the category list in the contributor guide) stay plain by design.
53+
- Styling lives in its own theme-owned stylesheet (`static/css/alerts.css`,
54+
linked from `baseof.html`) rather than the inline `<style>` block, but is still
55+
shipped inside the theme so the feature — hook plus styles — stays
56+
self-contained.

themes/powershell-community/layouts/_default/baseof.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
<link href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css" rel="stylesheet">
4040
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">
4141
<link href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.24.1/themes/prism-tomorrow.min.css" rel="stylesheet">
42+
<link href="/css/alerts.css" rel="stylesheet">
4243
{{ with .Site.Params.algolia }}<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@algolia/algoliasearch-netlify-frontend@1/dist/algoliasearchNetlify.css" />{{ end }}
4344

4445
<!-- Custom CSS -->
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
{{- /* Blockquote render hook.
2+
Renders GitHub-style alerts (`> [!NOTE]`, `[!TIP]`, `[!IMPORTANT]`,
3+
`[!WARNING]`, `[!CAUTION]`) as styled callouts, and falls through to a
4+
plain blockquote for everything else. We deliberately support only
5+
GitHub's five canonical alert types so the same Markdown renders
6+
identically on GitHub (issue submissions, PRs) and on the site — see
7+
docs/adr/0004-github-alert-admonitions.md.
8+
Styling lives in static/css/alerts.css. */ -}}
9+
{{- if eq .Type "alert" -}}
10+
{{- $type := .AlertType | lower -}}
11+
{{- $icons := dict
12+
"note" "fa-circle-info"
13+
"tip" "fa-lightbulb"
14+
"important" "fa-bullhorn"
15+
"warning" "fa-triangle-exclamation"
16+
"caution" "fa-circle-exclamation" -}}
17+
{{- $labels := dict
18+
"note" "Note"
19+
"tip" "Tip"
20+
"important" "Important"
21+
"warning" "Warning"
22+
"caution" "Caution" -}}
23+
{{- $icon := index $icons $type | default "fa-circle-info" -}}
24+
{{- $label := .AlertTitle | default (index $labels $type | default (title $type)) -}}
25+
<div class="ps-alert ps-alert-{{ $type }}" role="note">
26+
<p class="ps-alert-title"><i class="fas {{ $icon }}" aria-hidden="true"></i>{{ $label }}</p>
27+
<div class="ps-alert-body">{{ .Text }}</div>
28+
</div>
29+
{{- else -}}
30+
<blockquote>{{ .Text }}</blockquote>
31+
{{- end -}}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/* GitHub-style alert / admonition callouts.
2+
Emitted by layouts/_markup/render-blockquote.html for the five canonical
3+
GitHub alert types. Colors mirror GitHub's light-mode alert palette so the
4+
on-site rendering reads the same as the GitHub issue/PR preview an author
5+
submits from. */
6+
7+
.ps-alert {
8+
--ps-alert-color: #57606a;
9+
--ps-alert-bg: #f6f8fa;
10+
margin: 1.5rem 0;
11+
padding: 0.75rem 1rem;
12+
border: 1px solid #d0d7de;
13+
border-left: 4px solid var(--ps-alert-color);
14+
border-radius: 0.5rem;
15+
background: var(--ps-alert-bg);
16+
}
17+
18+
.ps-alert-title {
19+
display: flex;
20+
align-items: center;
21+
gap: 0.5rem;
22+
margin: 0 0 0.25rem;
23+
font-weight: 600;
24+
font-style: normal;
25+
color: var(--ps-alert-color);
26+
}
27+
28+
.ps-alert-title i {
29+
width: 1em;
30+
text-align: center;
31+
}
32+
33+
/* Keep inner Markdown (.prose adds top/bottom margins to p/ul/etc.) flush
34+
with the callout padding. */
35+
.ps-alert-body > :first-child { margin-top: 0; }
36+
.ps-alert-body > :last-child { margin-bottom: 0; }
37+
38+
/* Type variants — left-border + icon color and a matching tinted background. */
39+
.ps-alert-note { --ps-alert-color: #0969da; --ps-alert-bg: #ddf4ff; }
40+
.ps-alert-tip { --ps-alert-color: #1a7f37; --ps-alert-bg: #dafbe1; }
41+
.ps-alert-important { --ps-alert-color: #8250df; --ps-alert-bg: #fbefff; }
42+
.ps-alert-warning { --ps-alert-color: #9a6700; --ps-alert-bg: #fff8c5; }
43+
.ps-alert-caution { --ps-alert-color: #cf222e; --ps-alert-bg: #ffebe9; }

0 commit comments

Comments
 (0)