11Social media card images
22========================
33
4- This extension will automatically generate a PNG meant for sharing documentation links on social media platforms.
5- These cards display metadata about the page that you link to, and are meant to catch the attention of readers.
4+ This extension may create and reference a PNG file on the HTML pages, meant for sharing
5+ documentation links on social media platforms (both "feed-based" and "chat-based" social
6+ networks tend to use this). These cards display metadata about the page that you link
7+ to.
8+
9+ This extension will automatically setup such social media card images for each page of
10+ your documentation, using one of 3 possible setups:
11+
12+ - If you have set up an image manually using ``ogp_use_first_image `` or ``ogp_image ``,
13+ that image will be used as the social media card image.
14+ - Otherwise, you may define a callback function to generate a custom PNG image for each
15+ page (see below).
16+ - If neither of the above are set, and matplotlib is installed, a default social media card
17+ image will be generated for each page, using the page title and other metadata.
18+
19+ Custom image callback
20+ ---------------------
21+
22+ In conf.py, connect a custom function to the ``ogp_social_card_callback `` event:
23+
24+ .. code-block :: python
25+ :caption: conf.py
26+
27+ def setup (app ):
28+ app.connect(" generate-social-card" , my_custom_generate_card_function)
29+
30+
31+ Then implement the function as follows:
32+
33+ .. code-block :: python
34+
35+ from sphinxext.opengraph import SocialCardContents
36+
37+ def generate_card (
38+ app : Sphinx,
39+ contents : SocialCardContents,
40+ check_if_signature_exists : typing.Callable[[str ], None ],
41+ ) -> None | tuple[io.BytesIO, str ]:
42+ """ Generate a social media card image for the current page.
43+
44+ Parameters
45+ ----------
46+ app : Sphinx
47+ The Sphinx application object.
48+ contents : SocialCardContents
49+ An object containing metadata about the current page.
50+ Contains the following attributes:
51+ - site_name : str - the name of the site
52+ - site_url : str - the base URL of the site
53+ - page_title : str - the title of the page
54+ - description : str - the description of the page
55+ - html_logo : Path | None - the path to the logo image, if set
56+ - page_path : Path - the path to the current page file
57+ check_if_signature_exists : Callable[[str], None]
58+ A callable to check if a social card image has already been generated for
59+ the current page. This is useful to avoid regenerating an image that
60+ already exists.
61+ Returns
62+ -------
63+ None or tuple[io.BytesIO, str]
64+ If None is returned, the default image generation will be used.
65+ Otherwise, return a tuple containing:
66+ - An io.BytesIO object containing the image PNG bytes.
67+ - A string whose hash will be included in the image filename to ensure
68+ the image is updated when the content changes (because social media platforms
69+ often cache images aggressively).
70+ """
71+
72+ signature = f " { contents.page_title} - { contents.description} "
73+ check_if_signature_exists(signature)
74+
75+ # Generate image bytes here
76+ image_bytes = io.BytesIO(... )
77+ # ... generate image and write to image_bytes ...
78+ return image_bytes, signature
79+
80+ You may want to explore different libraries to generate images, such as Pillow, Matplotlib,
81+ html2image, or others.
82+
83+ Default social media card images (with matplotlib)
84+ --------------------------------------------------
85+
86+ Default image generation uses additional third-party libraries, so you need to install
87+ the extension with the **social_cards ** extra:
88+
89+ .. code-block :: console
90+
91+ pip install 'sphinxext-opengraph[social_cards]'
692
793 See `the opengraph.xyz website `__ for a way to preview what your social media cards look like.
894Here's an example of what the card for this page looks like:
@@ -12,40 +98,48 @@ Here's an example of what the card for this page looks like:
1298
1399__ https://www.opengraph.xyz/
14100
15- Disable card images
16- -------------------
101+ Default image generation also uses specific configuration options, which you can set in
102+ your `` conf.py `` file as a dictionnary assigned to the `` ogp_social_cards `` variable.
17103
18- To disable social media card images, use the following configuration :
104+ Here are the available options and their default values :
19105
20106.. code-block :: python
21107 :caption: conf.py
22108
23109 ogp_social_cards = {
24- " enable" : False
25- }
26-
27- Update the top-right image
28- --------------------------
29-
30- By default the top-right image will use the image specified by ``html_logo `` if it exists.
31- To update it, specify another path in the **image ** key like so:
110+ # If False, disable social card images
111+ " enable" : True ,
112+ # If set, use this URL as the site URL instead of the one inferred from the config
113+ " override_site_url" : None ,
114+
115+ # Color overides, in hex format or named colors
116+ " page_title_color" : " #2f363d" ,
117+ " description_color" : " #585e63" ,
118+ " site_title_color" : " #585e63" ,
119+ " site_url_color" : " #2f363d" ,
120+ " line_color" : " #5a626b" ,
121+ " background_color" : " white" ,
122+
123+ # Font override. If not set, use Roboto Flex (vendored in _static)
124+ " font" : None ,
125+
126+ # Image override, if not set, use html_logo
127+ # You may set it as a string path or a Path object
128+ # Note: neither this image not the image_mini may be an SVG file
129+ " image" : None ,
130+
131+ # Mini-image appears at the bottom-left of the card
132+ # If not set, use the Sphinx logo
133+ # You may set it as a string path or a Path object
134+ " image_mini" : " ..." ,
135+
136+ # Maximum length of the description text (in characters) before truncation
137+ " description_max_length" : 140 ,
32138
33- .. code-block :: python
34- :caption: conf.py
35-
36- ogp_social_cards = {
37- " image" : " path/to/image.png" ,
38139 }
39140
40- .. warning ::
41-
42- The image cannot be an SVG
43-
44- Matplotlib does not support easy plotting of SVG images,
45- so ensure that your image is a PNG or JPEG file, not SVG.
46-
47141 Customize the text font
48- -----------------------
142+ ^^^^^^^^^^^^^^^^^^^^^^^
49143
50144By default, the Roboto Flex font is used to render the card text.
51145
@@ -58,25 +152,30 @@ You can specify the other font name via ``font`` key:
58152 " font" : " Noto Sans CJK JP" ,
59153 }
60154
61- You might need to install an additional font package on your environment. Also, note that the font name needs to be
62- discoverable by Matplotlib FontManager.
63- See `Matplotlib documentation `__
64- for the information about FontManager.
155+ You can also use a font from a file by specifying the full path to the font file:
65156
66- __ https://matplotlib.org/stable/tutorials/text/text_props.html#default-font
157+ .. code-block :: python
158+ :caption: conf.py
67159
68- Customize the card
69- ------------------
160+ from matplotlib import font_manager
70161
71- There are several customization options to change the text and look of the social media preview card.
72- Below is a summary of these options.
162+ font_path = ' font-file.ttf ' # Your font path goes here
163+ font_manager.fontManager.addfont(font_path)
73164
74- - **site_url **: Set a custom site URL.
75- - **line_color **: Colour of the border line at the bottom of the card, in hex format.
165+ ogp_social_cards = {
166+ " font" : " font name" ,
167+ }
168+
169+ You might need to install an additional font package on your environment. Also, note
170+ that the font name needs to be discoverable by Matplotlib FontManager. See `Matplotlib
171+ documentation `__ for the information about FontManager.
172+
173+ __ https://matplotlib.org/stable/tutorials/text/text_props.html#default-font
76174
77175Example social cards
78- --------------------
176+ ^^^^^^^^^^^^^^^^^^^^
79177
80- Below are several social cards to give an idea for how this extension behaves with different length and size of text.
178+ Below are several social cards to give an idea for how this extension behaves with
179+ different length and size of text.
81180
82181.. include :: ./tmp/embed.txt
0 commit comments