Writing posts¶
Posts are written in Markdown. The editor — My blogs → your blog → New post — has a Preview toggle that renders exactly what readers will see — the preview and the published page go through the same renderer, so what you see really is what you get.
What Markdown supports¶
Headings, bold, italic, links, images, lists, tables, blockquotes,
horizontal rules, inline code and fenced code blocks.
```python
Post.objects.order_by("-published_at", "-id")
```
Fenced blocks keep their language label, so a downstream project can add syntax highlighting without changing anything here.
What it doesn't support, and why¶
Raw HTML is shown as text, not rendered. If you type <div> you will see
<div> on the page. This is deliberate: posts can be written by people and by
AI agents through the API, and a renderer that executes whatever HTML it is
given is the classic way a site ends up running someone else's JavaScript.
Links using javascript: or data: are stripped for the same reason.
If you need something Markdown can't express, put it in a template rather than a post body.
Titles and headings¶
Your post's title is already shown as the page heading, so you don't need to
repeat it. If the body opens with a heading identical to the title, it is
dropped automatically — handy when publishing a runbook page, where an opening
# Heading is the norm. A different opening heading is kept.
The slug¶
The slug is the last part of the URL: /blog/field-notes/my-post/. Leave it
blank and it's derived from the title. A few words are reserved because the
blog's own URLs use them (feed, tag, archive, search, subscribe,
newsletter); if you pick one, a number is appended rather than the save
failing.
Changing the slug of a published post breaks existing links. There is a
permanent alternative that survives retitling: /blog/p/<uid>/, shown on the
post's detail page.
Excerpt¶
The one- or two-sentence summary used in lists, feeds, search results, the newsletter preview and link previews on social sites. Leave it blank and the first paragraph is used.
Cover image¶
JPEG, PNG, GIF or WebP, up to 5MB. Alt text is required when you set one — a cover with no description is invisible to anyone using a screen reader, and the form will not save without it.
Tags¶
Comma-separated, created as you type them. Tags belong to one blog, so two
blogs can both have "ops" without sharing it. Each tag gets a page at
/blog/<blog>/tag/<tag>/.
Publishing¶
A post is a draft until you publish it. On the post's page:
- Publish now — live immediately.
- Schedule — pick a date and time; a background job publishes it. (This
needs a worker running; if one isn't,
/smallstack/status/says so.) - Return to draft — takes it off the site and the feeds.
- Archive — removes it from lists and feeds, but its URL keeps working for anyone who already linked to it.
While a post is unpublished, only you and staff can open its public URL, and you'll see a Draft preview banner so there's no doubt about what a reader would get. Everyone else gets a 404.