Skip to content

Commit f8fa940

Browse files
Use first image (after refactor) (#26)
* Use first image (after refactor) Co-authored-by: tcmetzger <[email protected]> * black * fix first_image no uri edge case * Use iana instead of wikipedia for mime types * black * Address comments * black Co-authored-by: tcmetzger <[email protected]>
1 parent 482f1ad commit f8fa940

File tree

7 files changed

+78
-10
lines changed

7 files changed

+78
-10
lines changed

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ Just add `sphinxext.opengraph` to your extensions list in your `conf.py`
1313

1414
```python
1515
extensions = [
16-
sphinxext.opengraph,
16+
"sphinxext.opengraph",
1717
]
1818
```
1919
## Options
@@ -29,6 +29,8 @@ These values are placed in the conf.py of your sphinx project.
2929
* This is not required. Link to image to show.
3030
* `ogp_image_alt`
3131
* This is not required. Alt text for image. Defaults to using `ogp_site_name` or the document's title as alt text, if available. Set to `False` if you want to turn off alt text completely.
32+
* `ogp_use_first_image`
33+
* This is not required. Set to True to use each page's first image, if available. If set to True but no image is found, Sphinx will use `ogp_image` instead.
3234
* `ogp_type`
3335
* This sets the ogp type attribute, for more information on the types available please take a look at https://ogp.me/#types. By default it is set to `website`, which should be fine for most use cases.
3436
* `ogp_custom_meta_tags`

sphinxext/opengraph/__init__.py

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from typing import Any, Dict
22
from urllib.parse import urljoin
3+
from pathlib import Path
34

45
import docutils.nodes as nodes
56
from sphinx.application import Sphinx
@@ -9,6 +10,20 @@
910

1011
DEFAULT_DESCRIPTION_LENGTH = 200
1112

13+
# A selection from https://www.iana.org/assignments/media-types/media-types.xhtml#image
14+
IMAGE_MIME_TYPES = {
15+
"gif": "image/gif",
16+
"apng": "image/apng",
17+
"webp": "image/webp",
18+
"jpeg": "image/jpeg",
19+
"jpg": "image/jpeg",
20+
"png": "image/png",
21+
"bmp": "image/bmp",
22+
"heic": "image/heic",
23+
"heif": "image/heif",
24+
"tiff": "image/tiff",
25+
}
26+
1227

1328
def make_tag(property: str, content: str) -> str:
1429
return f'<meta property="{property}" content="{content}" />\n '
@@ -55,19 +70,30 @@ def get_tags(
5570
tags += make_tag("og:description", description)
5671

5772
# image tag
58-
# Get the image from the config
73+
# Get basic values from config
5974
image_url = config["ogp_image"]
75+
ogp_use_first_image = config["ogp_use_first_image"]
76+
ogp_image_alt = config["ogp_image_alt"]
77+
78+
if ogp_use_first_image:
79+
first_image = doctree.next_node(nodes.image)
80+
if (
81+
first_image
82+
and Path(first_image.get("uri", "")).suffix[1:].lower() in IMAGE_MIME_TYPES
83+
):
84+
image_url = first_image["uri"]
85+
ogp_image_alt = first_image.get("alt", None)
86+
6087
if image_url:
6188
tags += make_tag("og:image", image_url)
6289

63-
# Add image alt text (either provided by config or from site_name)
64-
ogp_image_alt = config["ogp_image_alt"]
65-
if isinstance(ogp_image_alt, str):
66-
tags += make_tag("og:image:alt", ogp_image_alt)
67-
elif ogp_image_alt and site_name:
68-
tags += make_tag("og:image:alt", site_name)
69-
elif ogp_image_alt and title:
70-
tags += make_tag("og:image:alt", title)
90+
# Add image alt text (either provided by config or from site_name)
91+
if isinstance(ogp_image_alt, str):
92+
tags += make_tag("og:image:alt", ogp_image_alt)
93+
elif ogp_image_alt and site_name:
94+
tags += make_tag("og:image:alt", site_name)
95+
elif ogp_image_alt and title:
96+
tags += make_tag("og:image:alt", title)
7197

7298
# custom tags
7399
tags += "\n".join(config["ogp_custom_meta_tags"])
@@ -91,6 +117,7 @@ def setup(app: Sphinx) -> Dict[str, Any]:
91117
app.add_config_value("ogp_description_length", DEFAULT_DESCRIPTION_LENGTH, "html")
92118
app.add_config_value("ogp_image", None, "html")
93119
app.add_config_value("ogp_image_alt", True, "html")
120+
app.add_config_value("ogp_use_first_image", False, "html")
94121
app.add_config_value("ogp_type", "website", "html")
95122
app.add_config_value("ogp_site_name", None, "html")
96123
app.add_config_value("ogp_custom_meta_tags", [], "html")
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
extensions = ["sphinxext.opengraph"]
2+
3+
master_doc = "index"
4+
exclude_patterns = ["_build"]
5+
6+
html_theme = "basic"
7+
8+
ogp_site_name = "Example's Docs!"
9+
ogp_site_url = "http://example.org/"
10+
ogp_image = "http://example.org/image33.png"
11+
ogp_image_alt = "TEST"
12+
ogp_use_first_image = True
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Title Only

tests/roots/test-first-image/conf.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
extensions = ["sphinxext.opengraph"]
2+
3+
master_doc = "index"
4+
exclude_patterns = ["_build"]
5+
6+
html_theme = "basic"
7+
8+
ogp_site_name = "Example's Docs!"
9+
ogp_site_url = "http://example.org/"
10+
ogp_image = "http://example.org/image33.png"
11+
ogp_image_alt = "TEST"
12+
ogp_use_first_image = True
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
.. image:: http://example.org/image2.png
2+
:alt: Test image alt text

tests/test_options.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,18 @@ def test_site_name(og_meta_tags):
5454
assert get_tag_content(og_meta_tags, "site_name") == "Example's Docs!"
5555

5656

57+
@pytest.mark.sphinx("html", testroot="first-image")
58+
def test_first_image(og_meta_tags):
59+
assert get_tag_content(og_meta_tags, "image") == "http://example.org/image2.png"
60+
assert get_tag_content(og_meta_tags, "image:alt") == "Test image alt text"
61+
62+
63+
@pytest.mark.sphinx("html", testroot="first-image-no-image")
64+
def test_first_image_no_image(og_meta_tags):
65+
assert get_tag_content(og_meta_tags, "image") == "http://example.org/image33.png"
66+
assert get_tag_content(og_meta_tags, "image:alt") == "TEST"
67+
68+
5769
@pytest.mark.sphinx("html", testroot="skip-admonitions")
5870
def test_skip_admonitions(og_meta_tags):
5971
assert get_tag_content(og_meta_tags, "description") == "This is text."

0 commit comments

Comments
 (0)