Instagram content generator

Maintainer-only tool — not wired into Pages CMS or the live site. Claude runs this after writing a new blog article: it extracts the key talking points itself, fills in article.json, and renders a branded slide set as PNGs. The site owner reviews the extracted points and can ask for text edits before (or after) generating, then downloads the images to post manually.

What it produces

For one article, two image sets:

Every point slide and the cover end with a “swipe to continue” hint, and the CTA slide closes with a full-size call to action back to the site.

Language

The tool auto-detects Persian vs. English from the article’s own text (title, category, headings, bodies, CTA line) — if any Persian/Arabic-script character appears anywhere, the whole set renders RTL in Persian; otherwise it renders LTR in English. This flips per-slide alignment (logo/category pill positions, bullet side, text alignment), switches the boilerplate strings the tool itself writes (swipe hint, “X of Y” counter, CTA heading) to match, and swaps the display font (Baloo Bhaijaan 2 for Persian, its Latin sibling Baloo 2 for English) — the user’s own title/heading/body text is never translated, only used exactly as typed.

Usage

python3 generate_instagram_content.py --config article.json --out-dir OUT_DIR

article.json shape (see sample_article.json):

{
  "title": "عنوان مقاله",
  "category": "دسته‌بندی مقاله",
  "image": "/assets/gallery/hero.jpg",
  "cta_text": "یک جمله کوتاه، مثلا معرفی کلاس مرتبط",
  "points": [
    { "heading": "تیتر نکته (کوتاه)", "body": "خط اول بولت\nخط دوم بولت" }
  ]
}

body is rendered as a bulleted list — each \n-separated line becomes its own bullet. A single line still works fine (renders as one bullet).

3–5 points works best — each becomes one slide. When there’s only one point, the “X از Y” counter pill is omitted entirely since it’s meaningless for a single slide. Claude writes this file by hand per article (pulling from the post’s lead and ## sections), so there’s no automated extraction step to review separately — the owner reviews the rendered slides themselves and asks for wording changes.

How it renders

Each slide is plain HTML/CSS (brand colors + the Baloo font pair) screenshotted with Playwright/Chromium at the exact target pixel size — the same approach used throughout this repo’s local testing, chosen because Chromium’s native RTL/Persian text shaping is far more reliable than hand-rolling it with a raster library. Local images must be loaded via a real file:// page (not page.set_content), since Chromium blocks file:// resource loads from non-file:// documents.

Requires: pip install playwright and the Chromium binary at /opt/pw-browsers/chromium-1194/chrome-linux/chrome (already present in this project’s dev environment).