Riĉaj Ligiloj por Maldiligentaj Programistoj

Kiam mi dividas blogligilon en Twitter aŭ Slack, ĝi aperas kiel plata teksto. Neniu antaŭvida bildo. Nur URL kiel granda.org/en/2026/01/02/claude-code-on-the-go/.

Mi bezonis Open Graph bildojn. La kutima aliro: permane krei 1200x630 bildon por ĉiu afiŝo. Tio estas teda. Mi petis Claude aŭtomatigi ĝin.

flowchart LR
    Push[git push] --> GHA[GitHub Actions]
    GHA --> Hugo[Hugo Server]
    GHA --> PW[Playwright]
    PW -->|screenshot| Hugo
    PW --> IMG[OG Image]
    IMG --> Commit[git commit]
    Commit --> Deploy[Deploy]
flowchart TB
    Push[git push] --> GHA[GitHub Actions]
    GHA --> Hugo[Hugo Server]
    GHA --> PW[Playwright]
    PW -->|screenshot| Hugo
    PW --> IMG[OG Image]
    IMG --> Commit[git commit]
    Commit --> Deploy[Deploy]

La Agordo

Mi klarigis al Claude la problemon: afiŝoj bezonas sociajn antaŭvidajn bildojn, sed mi ne volas krei ilin permane. Ekrankopiи la artikolan enhavon, konservi ĝin kiel OG-bildon, aŭtomate ĝisdatigi la antaŭmaterialon.

Kion Claude Konstruis

KomponantoCelo
generate-og-image.jsPlaywright-skripto por ekrankopii afiŝojn
generate-og-images.ymlGitHub Action ekigita ĉe afiŝŝanĝoj
baseof.html ŝanĝojKondiĉaj og:image metaj etikedoj

La Playwright-skripto lanĉas senkapecon Chrome, navigi al la afiŝo, devigas helan reĝimon, kaŝas la ĉapon kaj piedpaĝon, kaj ekrankopiи ĉe 1200x630:

const browser = await chromium.launch({ headless: true });
const context = await browser.newContext({
  viewport: { width: 1200, height: 630 },
  deviceScaleFactor: 2, // Retina for crisp text
});

// Force light mode, hide nav
await page.evaluate(() => {
  document.documentElement.setAttribute("data-theme", "light");
  document.querySelector("header").style.display = "none";
  document.querySelector("footer").style.display = "none";
});

await page.screenshot({ path: outputPath, type: "png" });

La GitHub Action ekigas ĉe iu .en.md dosierŝanĝo, startigas Hugo, rulas la skripton, kaj komisas la generitan bildon reen al la deponejo:

on:
  push:
    branches: [main]
    paths:
      - "content/posts/**/*.md"

steps:
  - name: Start Hugo server
    run: hugo server --bind 0.0.0.0 --port 1313 &

  - name: Generate OG images
    run: node scripts/generate-og-image.js "$file"

  - name: Commit changes
    run: |
      git add static/images/posts/ content/posts/
      git commit -m "Generate Open Graph images for blog posts"
      git push

La ŝablono kondiĉe inkluzivas la bildon kiam la antaŭmaterialo havas image kampon:

{{- if .Params.image -}}
<meta property="og:image" content="{{ $canonical }}{{ .Params.image }}">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:image" content="{{ $canonical }}{{ .Params.image }}">
{{- else -}}
<meta name="twitter:card" content="summary">
{{- end -}}

404: Slug Ne Trovita

Unua rulado. Playwright ekrankopiis malplenan paĝon. La URL revenigis 404.

La skripto konstruis la URL el la dosiernomo: automatic-blog-translations.en.md/en/2025/12/23/automatic-blog-translations/

Sed Hugo ne uzas la dosiernomon por slug. Ĝi uzas la titolon. La efektiva URL estis /en/2025/12/23/automatic-blog-translations-with-claude-and-github-actions/.

Mi povus reimplementi la slugify-algoritmon de Hugo en JavaScript. Anstataŭe: demandi Hugo.

const output = execSync("hugo list all", { encoding: "utf8" });
// CSV output includes the exact permalink Hugo generates

Unu linio. Neniuj limkazoj. Hugo jam konas siajn proprajn URL-ojn.

Kio Sekvas

La nuna implemento nur generas bildojn por anglaj afiŝoj. Tradukitaj versioj referencas la saman bildan vojon, kio funkcias, sed ĝi signifas ke la OG-bildo ĉiam montras anglan tekston eĉ kiam oni dividas hispanan aŭ japanan version.

Vera i18n-subteno venas en la sekva PR. Nuntempe, ĉiu afiŝo ricevas socian bildon, kio estas pli bona ol neniu.

La Konkludo

Ĉi tio bezonis 14 minutojn por konstrui kaj senerarigi. Nun ĉiu afiŝo aŭtomate ricevas socian antaŭvidan bildon. Neniu permana laboro por afiŝo. La aŭtomatigo repagus sin post kelkaj afiŝoj.

Sendu la funkciantan version, malkovru la brecĝojn, ripetu.


Rilataj afiŝoj: