Skip to content

Commit

Permalink
Refactor social card generation
Browse files Browse the repository at this point in the history
  • Loading branch information
choldgraf committed Dec 23, 2022
1 parent c6a7f39 commit 269d082
Show file tree
Hide file tree
Showing 11 changed files with 230 additions and 117 deletions.
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -286,4 +286,7 @@ $RECYCLE.BIN/
# Windows shortcuts
*.lnk

# End of https://www.toptal.com/developers/gitignore/api/windows,linux,python,pycharm,visualstudiocode
# End of https://www.toptal.com/developers/gitignore/api/windows,linux,python,pycharm,visualstudiocode

# Assets that are built by sphinx
docs/tmp
2 changes: 0 additions & 2 deletions dev-requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,3 @@ wheel==0.37.1
pytest==7.1.3
beautifulsoup4==4.11.1
setuptools==65.4.1
furo
myst-parser
1 change: 1 addition & 0 deletions docs/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
myst-parser==0.18.1
furo==2022.9.29
sphinx==5.2.3
sphinx-design
./
76 changes: 76 additions & 0 deletions docs/script/generate_social_card_previews.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
"""
A helper script to test out what social previews look like.
I should remove this when I'm happy with the result.
"""
# %load_ext autoreload
# %autoreload 2

from pathlib import Path
from textwrap import dedent
from sphinxext.opengraph.socialcards import render_social_card, MAX_CHAR_PAGE_TITLE, MAX_CHAR_DESCRIPTION
import random

here = Path(__file__).parent

# Dummy lorem text
lorem = """
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
""".split() # noqa

kwargs_fig = dict(
image=here / "../source/_static/og-logo.png",
image_mini=here / "../../sphinxext/opengraph/_static/sphinx-logo-shadow.png",
)

print("Generating previews of social media cards...")
plt_objects = None
embed_text = []
for perm in range(20):
# Create dummy text description and pagetitle for this iteration
random.shuffle(lorem)
title = " ".join(lorem[:100])
title = title[: MAX_CHAR_PAGE_TITLE - 3] + "..."

random.shuffle(lorem)
desc = " ".join(lorem[:100])
desc = desc[: MAX_CHAR_DESCRIPTION - 3] + "..."

path_tmp = Path(here / "../tmp")
path_tmp.mkdir(exist_ok=True)
path_out = Path(path_tmp / f"num_{perm}.png")

plt_objects = render_social_card(
path=path_out,
site_title="Sphinx Social Card Demo",
page_title=title,
description=desc,
siteurl="sphinxext-opengraph.readthedocs.io",
plt_objects=plt_objects,
kwargs_fig=kwargs_fig
)

path_examples_page_folder = here / ".."
embed_text.append(
dedent(
f"""
````{{grid-item}}
```{{image}} ../{path_out.relative_to(path_examples_page_folder)}
```
````
"""
)
)

embed_text = "\n".join(embed_text)
embed_text = f"""
`````{{grid}} 2
:gutter: 5
{embed_text}
`````
"""

# Write markdown text that we can use to embed these images in the docs
(here / "../tmp/embed.txt").write_text(embed_text)

print("Done generating previews of social media cards...")
Binary file modified docs/source/_static/og-logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 7 additions & 1 deletion docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#
import os
import sys
from subprocess import run

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

Expand All @@ -33,6 +34,7 @@
# ones.
extensions = [
"myst_parser",
"sphinx_design",
"sphinxext.opengraph",
]

Expand Down Expand Up @@ -64,4 +66,8 @@
"site_url": "sphinxext-opengraph.readthedocs.io",
# "image": "TODO: add another image to test",
# "line_color": "#4078c0",
}
}

# Generate sample social media preview images
path_script = os.path.abspath("../script/generate_social_card_previews.py")
run(f"python {path_script}", shell=True)
15 changes: 10 additions & 5 deletions docs/source/socialcards.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,8 @@ These cards display metadata about the page that you link to, and are meant to c
See [the opengraph.xyz website](https://www.opengraph.xyz/) for a way to preview what your social media cards look like.
Here's an example of what the card for this page looks like:

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

Expand All @@ -33,4 +31,11 @@ Below is a summary of these options.
- **`site_url`**: Set a custom site URL.
- **`image`**: Over-ride the top-right image (by default, `html_logo` is used).
- **`line_color`**: Color of the border line at the bottom of the card, in hex format.
% TODO: add an over-ride for each part of the card.
% TODO: add an over-ride for each part of the card.

## Example social cards

Below are several social cards to give an idea for how this extension behaves with different length and size of text.

```{include} ../tmp/embed.txt
```
3 changes: 2 additions & 1 deletion noxfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@
@nox.session
def docs(session):
session.install("-e", ".")
session.install("-r", "dev-requirements.txt")
session.install("-r", "docs/requirements.txt")
if "live" in session.posargs:
session.install("ipython")
session.install("sphinx-autobuild")
session.run(*split("sphinx-autobuild -b html docs/source docs/build/html"))
else:
Expand Down
27 changes: 11 additions & 16 deletions sphinxext/opengraph/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from .descriptionparser import get_description
from .metaparser import get_meta_description
from .titleparser import get_title
from .socialcards import setup_social_card_matplotlib_objects, render_social_card
from .socialcards import create_social_card, DEFAULT_SOCIAL_CONFIG

import os

Expand Down Expand Up @@ -52,9 +52,6 @@ def get_tags(
tags = {}
meta_tags = {} # For non-og meta tags

# Social card preview configuration for later use
config_social = app.env.ogp_social_cards_config

# Set length of description
try:
desc_len = int(
Expand Down Expand Up @@ -138,7 +135,12 @@ def get_tags(
ogp_use_first_image = False
ogp_image_alt = fields.get("og:image:alt")
fields.pop("og:image", None)
elif app.env.ogp_social_cards_config["enable"] is True:
# This will only be False if the user explicitly sets it
elif app.config.ogp_social_cards.get("enable") is not False:
# Set up our configuration and update it with new information
config_social = DEFAULT_SOCIAL_CONFIG.copy()
config_social.update(app.config.ogp_social_cards)

# Description
description_max_length = config_social.get(
"description_max_length", DEFAULT_DESCRIPTION_LENGTH_SOCIAL_CARDS - 3
Expand All @@ -158,9 +160,10 @@ def get_tags(
elif isinstance(site_url, str):
url_text = site_url

# Render the card in a `_static` folder using the matplotlib objects
image_path = render_social_card(
# Plot an image with the given metadata to the output path
image_path = create_social_card(
app,
config_social,
site_name,
pagetitle,
description,
Expand All @@ -172,12 +175,7 @@ def get_tags(

# Link the image in our page metadata
url = app.config.ogp_site_url.strip("/")

# Add a hash to the image based on metadata to bust caches
# ref: https://developer.twitter.com/en/docs/twitter-for-websites/cards/guides/troubleshooting-cards#refreshing_images # noqa
hash = hashlib.sha1((site_name + pagetitle + description).encode()).hexdigest()
image_url = f"{url}/{image_path}?{hash}"

image_url = f"{url}/{image_path}"
else:
image_url = config["ogp_image"]
ogp_use_first_image = config["ogp_use_first_image"]
Expand Down Expand Up @@ -266,9 +264,6 @@ def setup(app: Sphinx) -> Dict[str, Any]:
app.add_config_value("ogp_custom_meta_tags", [], "html")
app.add_config_value("ogp_enable_meta_description", True, "html")

# Social media card images
app.connect("builder-inited", setup_social_card_matplotlib_objects)

# Main Sphinx OpenGraph linking
app.connect("html-page-context", html_page_context)

Expand Down
Binary file modified sphinxext/opengraph/_static/sphinx-logo-shadow.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 269d082

Please sign in to comment.