Add localized social creatives for release announcements - #349
Draft
strider-dunadan wants to merge 3 commits into
Draft
Add localized social creatives for release announcements#349strider-dunadan wants to merge 3 commits into
strider-dunadan wants to merge 3 commits into
Conversation
A release post becomes branded images, one set per language, described by a post.toml slide script that is the only file written by hand. social_translate.py runs the slide copy through the same DeepL path as translate_md.py, so terminology and register match the news post the images accompany; only prose is translated, since media paths, themes, badge names and the short URL are identifiers. social_build.py renders each slide through headless Chrome and downsamples with Pillow, writing a contact sheet per language because a build that succeeded is not a build that looks right. Renders stay out of content/: Zola publishes every file beside an index.md as a page asset and picks the first one for the OpenGraph preview. They stay out of git too, at ~40 MB a release, and are rebuilt from the slide scripts. Two things the layout has to survive. Translations run a third longer than English, so an auto-fit pass shrinks the type scale until the slide fits, measured against the slide's real children rather than scrollHeight — the corner watermark is an absolutely positioned pseudo-element hanging below the canvas, and counting it as overflow shrinks every green slide to the floor. And the html overflow is set explicitly, or the body's propagates to the viewport, the watermark enlarges the scroll area instead of being clipped, and every right-to-left slide comes out shifted sideways. The July release ships as the first real run, in twelve languages.
Each channel gets the images in its own language, falling back to English for a language that was not rendered — and the summary names the language actually picked, so the fallback is visible before anything is sent rather than after. A news folder maps to its social folder by name, content/news/2026-07-23/620 to social/2026-07-23-620, so no flag is needed for the usual case; --creatives points somewhere else and --no-creatives sends the raw screenshots as before. A post that has creatives never mixes them with its raw screenshots: silently falling back for one channel would send an unbranded album to that channel and branded ones to the rest, so a missing render is an error instead. --to redirects every selected post to one channel, which makes it possible to rehearse a release on a throwaway group without touching the real twelve.
An iOS screenshot gets an iPhone, an Android one an Android phone: their own corner radius, rim and side buttons, and the camera cutout drawn back in. The platform is read off the eyebrow when `device` is not given, which works in every language because iOS and Android stay Latin in translation. The cutout is not decoration over the screenshot. It is a hole in the display that neither system draws into, so the shot has an empty gap in its status bar exactly where the hardware sits; putting it back is what makes the frame read as the device it is, and leaving it out is what made every phone look alike. Its size is a share of the screen taken off the real hardware, so it holds at any rendered size. The generic `phone` frame keeps no cutout — it exists for a screenshot whose device is unknown. The screenshot now sits inside the frame rather than being the frame: side buttons need a box to hang off, and a box-shadow has none. The frame is handed the screenshot's own aspect ratio, so it is exactly the size the image would have been and the fit-inside behaviour is still the image's own. Signed-off-by: strider-dunadan <emerald.dunadan@gmail.com>
Deploying organicmaps with
|
| Latest commit: |
b6dc428
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://501d287e.organicmaps.pages.dev |
| Branch Preview URL: | https://strider-social-creatives.organicmaps.pages.dev |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
A release post becomes branded images, one set per Telegram channel language,
handed to the poster that already exists.
.claude/skills/om-post/— the skill: workflow, copywriting and layoutreferences,
assets/brand.csstools/social_post.py— thepost.tomlschema: what is prose, what is anidentifier, where a slide's screenshot comes from
tools/social_translate.py— slide copy through the same DeepL path astranslate_md.py: glossary, formality, tidy passestools/social_build.py— headless Chrome at 2x, Pillow downsample, a contactsheet per language
tools/telegram_post_all.py— picks the creatives up per channelsocial/2026-07-23-620/is the July release as the first real run: 7 slides,12 languages.
How to use it
Install once:
pip install -r tools/requirements-social.txt, plus aChrome-family browser. Everything runs from the repository root.
A news folder maps to its social folder by name —
content/news/2026-08-25/630→social/2026-08-25-630— which is how theposter finds the images with no flag. Keep the name.
Iterating:
--langs ruand--slide 3on the build,--only 4x5to skip theInstagram formats.
--no-creativesrestores the previous behaviour of postingthe raw screenshots.
The translations are DeepL drafts and need the same proofreading pass as a
translated news post — that is the step between rendering and posting, not an
optional one.
Why
The channels have been getting raw screenshots. Canvas size, brand colour,
which screenshot region survives the crop, and which language each channel is
served are now encoded once instead of redone by hand every release.