Skip to content

Commit 66c7758

Browse files
committed
Add suppport for overrides
1 parent cdeb4ed commit 66c7758

File tree

1 file changed

+94
-18
lines changed

1 file changed

+94
-18
lines changed

sphinxext/opengraph/__init__.py

Lines changed: 94 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1+
from collections import OrderedDict
2+
from pathlib import Path
13
from typing import Any, Dict
24
from urllib.parse import urljoin
3-
from pathlib import Path
45

56
import docutils.nodes as nodes
67
from sphinx.application import Sphinx
@@ -24,13 +25,67 @@
2425
"tiff": "image/tiff",
2526
}
2627

28+
# A selection from https://www.iana.org/assignments/media-types/media-types.xhtml#video
29+
VIDEO_MIME_TYPES = {
30+
"3gpp": "video/3gpp",
31+
"3gp2": "video/3gp2",
32+
"3gpp2": "video/3gpp2",
33+
"av1": "video/AV1",
34+
"dv": "video/DV",
35+
"h263": "video/H263",
36+
"h264": "video/H264",
37+
"h265": "video/H265",
38+
"jpeg": "video/JPEG",
39+
"jpeg2000": "video/jpeg2000",
40+
"MPV": "video/MPV",
41+
"ogg": "video/ogg",
42+
"quicktime": "video/quicktime",
43+
"raw": "video/raw",
44+
"vc1": "video/vc1",
45+
"vc2": "video/vc2",
46+
"vp8": "video/VP8",
47+
"mp4": "video/mp4",
48+
"webm": "video/webm",
49+
"m4v": "video/mp4",
50+
}
51+
52+
# A selection from https://www.iana.org/assignments/media-types/media-types.xhtml#audio
53+
AUDIO_MIME_TYPES = {
54+
"wave": "audio/x-wav",
55+
"wav": "audio/x-wav",
56+
"webm": "audio/webm",
57+
"ogg": "audio/ogg",
58+
"3gpp": "audio/3gpp",
59+
"3gpp2": "audio/3gpp2",
60+
"3gp2": "audio/3gp2",
61+
"aac": "audio/aac",
62+
"ac3": "audio/ac3",
63+
"aptx": "audio/aptx",
64+
"dv": "audio/DV",
65+
"mpeg": "audio/mpeg",
66+
"opus": "audio/opus",
67+
"vorbis": "audio/vorbis",
68+
"m3u": "audio/x-mpegurl",
69+
"m3u8": "audio/x-mpegurl",
70+
"mid": "audio/midi",
71+
"midi": "audio/midi",
72+
"mp2": "audio/mpeg",
73+
"mp3": "audio/mpeg",
74+
"m4a": "audio/mp4",
75+
"aiff": "audio/x-aiff",
76+
}
77+
2778

2879
def make_tag(property: str, content: str) -> str:
2980
return f'<meta property="{property}" content="{content}" />\n '
3081

3182

3283
def get_tags(
33-
context: Dict[str, Any], doctree: nodes.document, config: Dict[str, Any]
84+
app: Sphinx,
85+
pagename: str,
86+
context: Dict[str, Any],
87+
doctree: nodes.document,
88+
config: Dict[str, Any],
3489
) -> str:
3590

3691
# Set length of description
@@ -39,35 +94,31 @@ def get_tags(
3994
except ValueError:
4095
desc_len = DEFAULT_DESCRIPTION_LENGTH
4196

97+
meta = OrderedDict()
98+
4299
# Get the title and parse any html in it
43100
title = get_title(context["title"], skip_html_tags=False)
44101
title_excluding_html = get_title(context["title"], skip_html_tags=True)
102+
meta["og:title"] = title
45103

46104
# Parse/walk doctree for metadata (tag/description)
47105
description = get_description(doctree, desc_len, [title, title_excluding_html])
48-
49-
tags = "\n "
50-
51-
# title tag
52-
tags += make_tag("og:title", title)
106+
meta["og:description"] = description
53107

54108
# type tag
55-
tags += make_tag("og:type", config["ogp_type"])
109+
meta["og:type"] = config["ogp_type"]
56110

57111
# url tag
58112
# Get the URL of the specific page
59113
page_url = urljoin(
60114
config["ogp_site_url"], context["pagename"] + context["file_suffix"]
61115
)
62-
tags += make_tag("og:url", page_url)
116+
meta["og:url"] = page_url
63117

64118
# site name tag
65119
site_name = config["ogp_site_name"]
66120
if site_name:
67-
tags += make_tag("og:site_name", site_name)
68-
69-
# description tag
70-
tags += make_tag("og:description", description)
121+
meta["og:site_name"] = site_name
71122

72123
# image tag
73124
# Get basic values from config
@@ -85,15 +136,40 @@ def get_tags(
85136
ogp_image_alt = first_image.get("alt", None)
86137

87138
if image_url:
88-
tags += make_tag("og:image", image_url)
139+
meta["og:image"] = image_url
89140

90141
# Add image alt text (either provided by config or from site_name)
91142
if isinstance(ogp_image_alt, str):
92-
tags += make_tag("og:image:alt", ogp_image_alt)
143+
meta["og:image:alt"] = ogp_image_alt
93144
elif ogp_image_alt is None and site_name:
94-
tags += make_tag("og:image:alt", site_name)
145+
meta["og:image:alt"] = site_name
95146
elif ogp_image_alt is None and title:
96-
tags += make_tag("og:image:alt", title)
147+
meta["og:image:alt"] = title
148+
149+
# apply overrides
150+
meta.update(context.get("meta", {}))
151+
152+
# fix relative overrides
153+
for prop in ["og:image", "og:audio", "og:video"]:
154+
value = meta.get("prop", "")
155+
if not (value.startswith("http://") or value.startswith("https://")):
156+
meta[prop] = app.env.relfn2path(value, pagename)
157+
158+
# add mime types
159+
def add_mime_type(prop: str, mime_types: dict):
160+
if prop not in meta:
161+
return
162+
value = meta[prop]
163+
ext = value.split(".")[-1].split("?")[0].split("#")[0].lower()
164+
if ext in mime_types:
165+
meta[prop + ":type"] = mime_types[ext]
166+
167+
add_mime_type("og:image", IMAGE_MIME_TYPES)
168+
add_mime_type("og:video", VIDEO_MIME_TYPES)
169+
add_mime_type("og:audio", AUDIO_MIME_TYPES)
170+
171+
# write tags
172+
tags = "".join([make_tag(k, v) for k, v in meta.items()])
97173

98174
# custom tags
99175
tags += "\n".join(config["ogp_custom_meta_tags"])
@@ -109,7 +185,7 @@ def html_page_context(
109185
doctree: nodes.document,
110186
) -> None:
111187
if doctree:
112-
context["metatags"] += get_tags(context, doctree, app.config)
188+
context["metatags"] += get_tags(app, pagename, context, doctree, app.config)
113189

114190

115191
def setup(app: Sphinx) -> Dict[str, Any]:

0 commit comments

Comments
 (0)