thingino-blog-publish
Use this skill when asked to write, publish, update, unpublish or fix an
article on the thingino blog.
The blog is a minimal Sinatra app that serves .md files from its
articles/ directory. Full app documentation lives in
DOCUMENTATION.md at the blog app root. If the local app root is
unknown, ask the user (commonly ~/www/thingino/blog).
When to use
- "Write a blog post about X" / "publish this on the blog".
- "Update / fix / unpublish the article about X".
- "Why doesn't my article show up?"
Key facts
- One
.md file = one article. No database, no admin UI, no restart —
files take effect on the next HTTP request.
- Publishing means committing the article to the blog repo and pushing
to the remote. The server pulls from the repo --- no scp, no manual
file copy. The blog app root is a git working copy.
Article rules
Filename: YYYY-MM-DD-url-slug.md (today's date, lowercase slug with
hyphens). The slug part becomes the URL: /url-slug.
Start the file with front matter (simple key: value lines, no YAML
nesting):
---
title: Human-readable headline
description: One-sentence summary under 160 characters.
author: <author name, if known>
---
Body is GFM Markdown. Start sections at ## — never add a leading
# H1 when title: is set (it would render twice).
Fenced code blocks with language tags get syntax highlighting.
description is used verbatim for SEO meta and feed summaries; keep
it under 160 characters, plain text.
Optional fields: date: (overrides filename date), slug:
(overrides filename slug), draft: true (hides article everywhere).
Images are served from the public/images/ directory (publicly
accessible). Place article images there and reference them as
/images/filename.webp. Prefer landscape .webp images at 600px
wide or less. See thingino-blog-write for full image guidelines.
Content style
- Match thingino voice: technical, concise, no marketing fluff.
- Brand is "Thingino" in prose (a proper noun); lowercase "thingino"
is logo/wordmark styling only.
- Prefer concrete commands, tables and short paragraphs over prose walls.
- Link to https://thingino.com and the GitHub repo
(https://github.com/themactep/thingino-firmware) where relevant.
Workflow
- Draft the article as
articles/YYYY-MM-DD-slug.md in the local blog
app root. For anything not explicitly approved for immediate
publication, include draft: true.
- Verify locally:
cd <blog-app-root> && bundle exec rackup -p 4567 &
curl -sI http://127.0.0.1:4567/<slug> → expect 200
(drafts correctly return 404; temporarily flip the flag to preview).
- Check rendered HTML for the title, date and body:
curl -s http://127.0.0.1:4567/<slug> | grep -E '<h1|<time'
- Stop the server afterwards (kill by port, see pitfalls).
- Publish (after user confirms final text):
- Ensure the article has no
draft: true flag (remove it if present).
- Commit and push:
cd <blog-app-root> && git add articles/YYYY-MM-DD-slug.md && git commit -m "..." && git push
- The user pulls on the server to make it live.
- Updates: edit the same file, commit, push. Unpublish: add
draft: true to the front matter, commit, push.
Pitfalls
- Never change the slug of a published article (breaks inbound links;
the app has no redirects). To adjust a filename without changing the
URL, pin the old slug with
slug: front matter.
- Front matter must start on line 1; both fences must be exactly
---.
- Slug chars are
[a-z0-9-] only — underscores, spaces and uppercase
in filenames are normalized, so verify the resulting URL rather than
assuming it.
- When killing a local test server, kill by port
(
ss -ltnp | grep 4567), not pkill -f rackup — the -f pattern
can match your own shell.
- After pushing, the article is live once the user pulls on the server.
No further action is needed from the agent.
1---2name: thingino-blog-publish3description: Write and publish articles to the thingino blog (Markdown files served by a Sinatra app, deployed via git push).4license: MIT5---6# thingino-blog-publish78Use this skill when asked to write, publish, update, unpublish or fix an9article on the thingino blog.1011The blog is a minimal Sinatra app that serves `.md` files from its12`articles/` directory. Full app documentation lives in13`DOCUMENTATION.md` at the blog app root. If the local app root is14unknown, ask the user (commonly `~/www/thingino/blog`).1516## When to use1718- "Write a blog post about X" / "publish this on the blog".19- "Update / fix / unpublish the article about X".20- "Why doesn't my article show up?"2122## Key facts2324- One `.md` file = one article. No database, no admin UI, no restart —25 files take effect on the next HTTP request.26- Publishing means committing the article to the blog repo and pushing27 to the remote. The server pulls from the repo --- no scp, no manual28 file copy. The blog app root is a git working copy.2930## Article rules31321. Filename: `YYYY-MM-DD-url-slug.md` (today's date, lowercase slug with33 hyphens). The slug part becomes the URL: `/url-slug`.342. Start the file with front matter (simple `key: value` lines, no YAML35 nesting):3637 ```markdown38 ---39 title: Human-readable headline40 description: One-sentence summary under 160 characters.41 author: <author name, if known>42 ---43 ```44453. Body is GFM Markdown. Start sections at `##` — never add a leading46 `# H1` when `title:` is set (it would render twice).474. Fenced code blocks with language tags get syntax highlighting.485. `description` is used verbatim for SEO meta and feed summaries; keep49 it under 160 characters, plain text.506. Optional fields: `date:` (overrides filename date), `slug:`51 (overrides filename slug), `draft: true` (hides article everywhere).527. Images are served from the `public/images/` directory (publicly53 accessible). Place article images there and reference them as54 `/images/filename.webp`. Prefer landscape `.webp` images at 600px55 wide or less. See `thingino-blog-write` for full image guidelines.5657## Content style58591. Match thingino voice: technical, concise, no marketing fluff.602. Brand is "Thingino" in prose (a proper noun); lowercase "thingino"61 is logo/wordmark styling only.623. Prefer concrete commands, tables and short paragraphs over prose walls.634. Link to https://thingino.com and the GitHub repo64 (https://github.com/themactep/thingino-firmware) where relevant.6566## Workflow67681. Draft the article as `articles/YYYY-MM-DD-slug.md` in the local blog69 app root. For anything not explicitly approved for immediate70 publication, include `draft: true`.712. Verify locally:72 - `cd <blog-app-root> && bundle exec rackup -p 4567 &`73 - `curl -sI http://127.0.0.1:4567/<slug>` → expect `200`74 (drafts correctly return `404`; temporarily flip the flag to preview).75 - Check rendered HTML for the title, date and body:76 `curl -s http://127.0.0.1:4567/<slug> | grep -E '<h1|<time'`77 - Stop the server afterwards (kill by port, see pitfalls).783. Publish (after user confirms final text):79 - Ensure the article has no `draft: true` flag (remove it if present).80 - Commit and push:81 `cd <blog-app-root> && git add articles/YYYY-MM-DD-slug.md && git commit -m "..." && git push`82 - The user pulls on the server to make it live.834. Updates: edit the same file, commit, push. Unpublish: add84 `draft: true` to the front matter, commit, push.8586## Pitfalls87881. Never change the slug of a published article (breaks inbound links;89 the app has no redirects). To adjust a filename without changing the90 URL, pin the old slug with `slug:` front matter.912. Front matter must start on line 1; both fences must be exactly `---`.923. Slug chars are `[a-z0-9-]` only — underscores, spaces and uppercase93 in filenames are normalized, so verify the resulting URL rather than94 assuming it.954. When killing a local test server, kill by port96 (`ss -ltnp | grep 4567`), not `pkill -f rackup` — the `-f` pattern97 can match your own shell.985. After pushing, the article is live once the user pulls on the server.99 No further action is needed from the agent.