From 74c5371f8c7639ff047c8c0c7c12a7fc420cf96d Mon Sep 17 00:00:00 2001 From: astra-intelligence Date: Sat, 17 Oct 2026 10:25:18 +0000 Subject: [PATCH 1/2] Add Open Graph / social preview tags + OG image to docs docs.pytest.org had zero og:* and twitter:* meta tags, so every link shared on X/Twitter, LinkedIn, Slack, Discord, or iMessage rendered a blank preview card. - Add a furo page.html override (doc/en/_templates/page.html) emitting og:site_name/type/title/description/image(+width/height) and twitter:card/title/description/image on every page. - Add a 1200x630 OG image (doc/en/_static/og-image.png) generated with Pillow-only tools/make-og-image.py (reproducible), using the project's own pytest1.png logo. Co-Authored-By: Paperclip --- doc/en/_static/og-image.png | Bin 0 -> 41022 bytes doc/en/_templates/page.html | 16 +++++++ tools/make-og-image.py | 90 ++++++++++++++++++++++++++++++++++++ 3 files changed, 106 insertions(+) create mode 100644 doc/en/_static/og-image.png create mode 100644 doc/en/_templates/page.html create mode 100644 tools/make-og-image.py diff --git a/doc/en/_static/og-image.png b/doc/en/_static/og-image.png new file mode 100644 index 0000000000000000000000000000000000000000..4639aa31e9ffaea3446a7876d1634e7e8bff2400 GIT binary patch literal 41022 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 + + + + + + + + + + +{% endblock extrahead %} \ No newline at end of file diff --git a/tools/make-og-image.py b/tools/make-og-image.py new file mode 100644 index 00000000000..34cfaa869e4 --- /dev/null +++ b/tools/make-og-image.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python3 +"""Generate the 1200x630 Open Graph image for docs.pytest.org. + +Pillow-only, reproducible. Run from the repo root: + python tools/make-og-image.py +Output: doc/en/_static/og-image.png + +Design: white ground, the project's own pytest1.png logo scaled on top, +official tagline, section pills, docs.pytest.org domain chip. +""" +from pathlib import Path +from PIL import Image, ImageDraw, ImageFont + +ROOT = Path(__file__).resolve().parents[1] +LOGO = ROOT / "doc" / "en" / "_static" / "pytest1.png" +OUT = ROOT / "doc" / "en" / "_static" / "og-image.png" + +W, H = 1200, 630 +GROUND = (255, 255, 255) +ACCENT = (250, 179, 14) # pytest yellow +INK = (34, 34, 34) +GREY = (110, 110, 110) +PILL_BG = (245, 245, 245) +PILL_FG = (51, 51, 51) +CHIP_BG = (250, 179, 14) +CHIP_FG = (34, 34, 34) + +FONT_DIR = Path("/usr/share/fonts/truetype/dejavu/") +FONT_BOLD = FONT_DIR / "DejaVuSans-Bold.ttf" +FONT_REG = FONT_DIR / "DejaVuSans.ttf" + + +def font(path, size): + return ImageFont.truetype(str(path), size) + + +def text_w(draw, s, f): + b = draw.textbbox((0, 0), s, font=f) + return b[2] - b[0] + + +def main(): + img = Image.new("RGB", (W, H), GROUND) + draw = ImageDraw.Draw(img) + + # Accent bar along the top. + draw.rectangle([0, 0, W, 10], fill=ACCENT) + + # Logo: the project's own pytest1.png (1500x1500, transparent bg, contains + # the bar-chart mark + "pytest" wordmark). Scale to fit fully on the card. + logo = Image.open(LOGO).convert("RGBA") + logo_w = 400 + logo_h = int(logo.height * logo_w / logo.width) + logo = logo.resize((logo_w, logo_h), Image.LANCZOS) + img.paste(logo, ((W - logo_w) // 2, 15), logo) + + # Tagline. + tagline = "helps you write better programs" + f_tag = font(FONT_REG, 40) + draw.text(((W - text_w(draw, tagline, f_tag)) / 2, 430), tagline, + font=f_tag, fill=GREY) + + # Section pills. + pills = ["Getting started", "How-to guides", "Reference", "Explanations", "Examples"] + f_pill = font(FONT_BOLD, 26) + gap = 16 + pw = [text_w(draw, p, f_pill) + 40 for p in pills] + total = sum(pw) + gap * (len(pills) - 1) + x = (W - total) / 2 + for p, wdt in zip(pills, pw): + draw.rounded_rectangle([x, 485, x + wdt, 485 + 52], radius=26, fill=PILL_BG) + draw.text((x + 20, 485 + 11), p, font=f_pill, fill=PILL_FG) + x += wdt + gap + + # Domain chip. + chip = "docs.pytest.org" + f_chip = font(FONT_BOLD, 30) + cw = text_w(draw, chip, f_chip) + 56 + cx = (W - cw) / 2 + cy = 555 + draw.rounded_rectangle([cx, cy, cx + cw, cy + 56], radius=28, fill=CHIP_BG) + draw.text((cx + 28, cy + 11), chip, font=f_chip, fill=CHIP_FG) + + OUT.parent.mkdir(parents=True, exist_ok=True) + img.save(OUT, optimize=True) + print(f"wrote {OUT} {img.size}") + + +if __name__ == "__main__": + main() \ No newline at end of file From 04553c4418af86eae0ae20a4b527baab07851590 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sat, 17 Oct 2026 10:27:10 +0000 Subject: [PATCH 2/2] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- doc/en/_templates/page.html | 2 +- tools/make-og-image.py | 26 ++++++++++++++++++++------ 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/doc/en/_templates/page.html b/doc/en/_templates/page.html index 9206a8e6b6e..5405f25320c 100644 --- a/doc/en/_templates/page.html +++ b/doc/en/_templates/page.html @@ -13,4 +13,4 @@ -{% endblock extrahead %} \ No newline at end of file +{% endblock extrahead %} diff --git a/tools/make-og-image.py b/tools/make-og-image.py index 34cfaa869e4..d7ddc1c1e55 100644 --- a/tools/make-og-image.py +++ b/tools/make-og-image.py @@ -8,8 +8,15 @@ Design: white ground, the project's own pytest1.png logo scaled on top, official tagline, section pills, docs.pytest.org domain chip. """ + +from __future__ import annotations + from pathlib import Path -from PIL import Image, ImageDraw, ImageFont + +from PIL import Image +from PIL import ImageDraw +from PIL import ImageFont + ROOT = Path(__file__).resolve().parents[1] LOGO = ROOT / "doc" / "en" / "_static" / "pytest1.png" @@ -17,7 +24,7 @@ W, H = 1200, 630 GROUND = (255, 255, 255) -ACCENT = (250, 179, 14) # pytest yellow +ACCENT = (250, 179, 14) # pytest yellow INK = (34, 34, 34) GREY = (110, 110, 110) PILL_BG = (245, 245, 245) @@ -57,11 +64,18 @@ def main(): # Tagline. tagline = "helps you write better programs" f_tag = font(FONT_REG, 40) - draw.text(((W - text_w(draw, tagline, f_tag)) / 2, 430), tagline, - font=f_tag, fill=GREY) + draw.text( + ((W - text_w(draw, tagline, f_tag)) / 2, 430), tagline, font=f_tag, fill=GREY + ) # Section pills. - pills = ["Getting started", "How-to guides", "Reference", "Explanations", "Examples"] + pills = [ + "Getting started", + "How-to guides", + "Reference", + "Explanations", + "Examples", + ] f_pill = font(FONT_BOLD, 26) gap = 16 pw = [text_w(draw, p, f_pill) + 40 for p in pills] @@ -87,4 +101,4 @@ def main(): if __name__ == "__main__": - main() \ No newline at end of file + main()