Skip to content

Commit 269d082

Browse files
committed
Refactor social card generation
1 parent c6a7f39 commit 269d082

11 files changed

+230
-117
lines changed

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -286,4 +286,7 @@ $RECYCLE.BIN/
286286
# Windows shortcuts
287287
*.lnk
288288

289-
# End of https://www.toptal.com/developers/gitignore/api/windows,linux,python,pycharm,visualstudiocode
289+
# End of https://www.toptal.com/developers/gitignore/api/windows,linux,python,pycharm,visualstudiocode
290+
291+
# Assets that are built by sphinx
292+
docs/tmp

dev-requirements.txt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,3 @@ wheel==0.37.1
33
pytest==7.1.3
44
beautifulsoup4==4.11.1
55
setuptools==65.4.1
6-
furo
7-
myst-parser

docs/requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
myst-parser==0.18.1
22
furo==2022.9.29
33
sphinx==5.2.3
4+
sphinx-design
45
./
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
"""
2+
A helper script to test out what social previews look like.
3+
I should remove this when I'm happy with the result.
4+
"""
5+
# %load_ext autoreload
6+
# %autoreload 2
7+
8+
from pathlib import Path
9+
from textwrap import dedent
10+
from sphinxext.opengraph.socialcards import render_social_card, MAX_CHAR_PAGE_TITLE, MAX_CHAR_DESCRIPTION
11+
import random
12+
13+
here = Path(__file__).parent
14+
15+
# Dummy lorem text
16+
lorem = """
17+
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum
18+
""".split() # noqa
19+
20+
kwargs_fig = dict(
21+
image=here / "../source/_static/og-logo.png",
22+
image_mini=here / "../../sphinxext/opengraph/_static/sphinx-logo-shadow.png",
23+
)
24+
25+
print("Generating previews of social media cards...")
26+
plt_objects = None
27+
embed_text = []
28+
for perm in range(20):
29+
# Create dummy text description and pagetitle for this iteration
30+
random.shuffle(lorem)
31+
title = " ".join(lorem[:100])
32+
title = title[: MAX_CHAR_PAGE_TITLE - 3] + "..."
33+
34+
random.shuffle(lorem)
35+
desc = " ".join(lorem[:100])
36+
desc = desc[: MAX_CHAR_DESCRIPTION - 3] + "..."
37+
38+
path_tmp = Path(here / "../tmp")
39+
path_tmp.mkdir(exist_ok=True)
40+
path_out = Path(path_tmp / f"num_{perm}.png")
41+
42+
plt_objects = render_social_card(
43+
path=path_out,
44+
site_title="Sphinx Social Card Demo",
45+
page_title=title,
46+
description=desc,
47+
siteurl="sphinxext-opengraph.readthedocs.io",
48+
plt_objects=plt_objects,
49+
kwargs_fig=kwargs_fig
50+
)
51+
52+
path_examples_page_folder = here / ".."
53+
embed_text.append(
54+
dedent(
55+
f"""
56+
````{{grid-item}}
57+
```{{image}} ../{path_out.relative_to(path_examples_page_folder)}
58+
```
59+
````
60+
"""
61+
)
62+
)
63+
64+
embed_text = "\n".join(embed_text)
65+
embed_text = f"""
66+
`````{{grid}} 2
67+
:gutter: 5
68+
69+
{embed_text}
70+
`````
71+
"""
72+
73+
# Write markdown text that we can use to embed these images in the docs
74+
(here / "../tmp/embed.txt").write_text(embed_text)
75+
76+
print("Done generating previews of social media cards...")

docs/source/_static/og-logo.png

-7.49 KB
Loading

docs/source/conf.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#
1313
import os
1414
import sys
15+
from subprocess import run
1516

1617
sys.path.insert(0, os.path.abspath("../.."))
1718

@@ -33,6 +34,7 @@
3334
# ones.
3435
extensions = [
3536
"myst_parser",
37+
"sphinx_design",
3638
"sphinxext.opengraph",
3739
]
3840

@@ -64,4 +66,8 @@
6466
"site_url": "sphinxext-opengraph.readthedocs.io",
6567
# "image": "TODO: add another image to test",
6668
# "line_color": "#4078c0",
67-
}
69+
}
70+
71+
# Generate sample social media preview images
72+
path_script = os.path.abspath("../script/generate_social_card_previews.py")
73+
run(f"python {path_script}", shell=True)

docs/source/socialcards.md

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,8 @@ These cards display metadata about the page that you link to, and are meant to c
66
See [the opengraph.xyz website](https://www.opengraph.xyz/) for a way to preview what your social media cards look like.
77
Here's an example of what the card for this page looks like:
88

9-
% This causes an *expected* warning because the image doesn't exist relative
10-
% to the source file, but it does exist relative to the built HTML file.
11-
% So we expect Sphinx to say the image doesn't exist but it'll look correct in HTML.
12-
```{image} /_images/social_previews/summary_socialcards.png
9+
% This is auto-generated at build time
10+
```{image} ../tmp//num_0.png
1311
:width: 500
1412
```
1513

@@ -33,4 +31,11 @@ Below is a summary of these options.
3331
- **`site_url`**: Set a custom site URL.
3432
- **`image`**: Over-ride the top-right image (by default, `html_logo` is used).
3533
- **`line_color`**: Color of the border line at the bottom of the card, in hex format.
36-
% TODO: add an over-ride for each part of the card.
34+
% TODO: add an over-ride for each part of the card.
35+
36+
## Example social cards
37+
38+
Below are several social cards to give an idea for how this extension behaves with different length and size of text.
39+
40+
```{include} ../tmp/embed.txt
41+
```

noxfile.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,9 @@
77
@nox.session
88
def docs(session):
99
session.install("-e", ".")
10-
session.install("-r", "dev-requirements.txt")
10+
session.install("-r", "docs/requirements.txt")
1111
if "live" in session.posargs:
12+
session.install("ipython")
1213
session.install("sphinx-autobuild")
1314
session.run(*split("sphinx-autobuild -b html docs/source docs/build/html"))
1415
else:

sphinxext/opengraph/__init__.py

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
from .descriptionparser import get_description
1010
from .metaparser import get_meta_description
1111
from .titleparser import get_title
12-
from .socialcards import setup_social_card_matplotlib_objects, render_social_card
12+
from .socialcards import create_social_card, DEFAULT_SOCIAL_CONFIG
1313

1414
import os
1515

@@ -52,9 +52,6 @@ def get_tags(
5252
tags = {}
5353
meta_tags = {} # For non-og meta tags
5454

55-
# Social card preview configuration for later use
56-
config_social = app.env.ogp_social_cards_config
57-
5855
# Set length of description
5956
try:
6057
desc_len = int(
@@ -138,7 +135,12 @@ def get_tags(
138135
ogp_use_first_image = False
139136
ogp_image_alt = fields.get("og:image:alt")
140137
fields.pop("og:image", None)
141-
elif app.env.ogp_social_cards_config["enable"] is True:
138+
# This will only be False if the user explicitly sets it
139+
elif app.config.ogp_social_cards.get("enable") is not False:
140+
# Set up our configuration and update it with new information
141+
config_social = DEFAULT_SOCIAL_CONFIG.copy()
142+
config_social.update(app.config.ogp_social_cards)
143+
142144
# Description
143145
description_max_length = config_social.get(
144146
"description_max_length", DEFAULT_DESCRIPTION_LENGTH_SOCIAL_CARDS - 3
@@ -158,9 +160,10 @@ def get_tags(
158160
elif isinstance(site_url, str):
159161
url_text = site_url
160162

161-
# Render the card in a `_static` folder using the matplotlib objects
162-
image_path = render_social_card(
163+
# Plot an image with the given metadata to the output path
164+
image_path = create_social_card(
163165
app,
166+
config_social,
164167
site_name,
165168
pagetitle,
166169
description,
@@ -172,12 +175,7 @@ def get_tags(
172175

173176
# Link the image in our page metadata
174177
url = app.config.ogp_site_url.strip("/")
175-
176-
# Add a hash to the image based on metadata to bust caches
177-
# ref: https://developer.twitter.com/en/docs/twitter-for-websites/cards/guides/troubleshooting-cards#refreshing_images # noqa
178-
hash = hashlib.sha1((site_name + pagetitle + description).encode()).hexdigest()
179-
image_url = f"{url}/{image_path}?{hash}"
180-
178+
image_url = f"{url}/{image_path}"
181179
else:
182180
image_url = config["ogp_image"]
183181
ogp_use_first_image = config["ogp_use_first_image"]
@@ -266,9 +264,6 @@ def setup(app: Sphinx) -> Dict[str, Any]:
266264
app.add_config_value("ogp_custom_meta_tags", [], "html")
267265
app.add_config_value("ogp_enable_meta_description", True, "html")
268266

269-
# Social media card images
270-
app.connect("builder-inited", setup_social_card_matplotlib_objects)
271-
272267
# Main Sphinx OpenGraph linking
273268
app.connect("html-page-context", html_page_context)
274269

-740 Bytes
Loading

0 commit comments

Comments
 (0)