Skip to content

Commit a2d9acc

Browse files
authored
Add support for meta description (#72)
1 parent 93148a6 commit a2d9acc

File tree

12 files changed

+138
-20
lines changed

12 files changed

+138
-20
lines changed

.github/workflows/workflow.yml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,17 @@ on:
44
branches:
55
- main
66
push:
7-
branches:
8-
- main
97
create:
108
tags:
119
- '*'
1210
jobs:
1311
check:
1412
runs-on: ubuntu-latest
13+
14+
# We want to run on external PRs, but not on our own internal PRs as they'll be run
15+
# by the push to the branch.
16+
if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository
17+
1518
steps:
1619
- uses: actions/checkout@v3
1720
- uses: actions/setup-python@v4

README.md

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
# sphinxext-opengraph
2-
![Build](https://github.com/wpilibsuite/sphinxext-opengraph/workflows/Test%20and%20Deploy/badge.svg)
3-
[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
42

5-
Sphinx extension to generate OpenGraph metadata (https://ogp.me/)
3+
[![Build](https://github.com/wpilibsuite/sphinxext-opengraph/workflows/Test%20and%20Deploy/badge.svg)](https://github.com/wpilibsuite/sphinxext-opengraph/actions)
4+
[![Code style: Black](https://img.shields.io/badge/code%20style-Black-000000.svg)](https://github.com/psf/black)
5+
6+
Sphinx extension to generate [Open Graph metadata](https://ogp.me/).
67

78
## Installation
89

9-
`python -m pip install sphinxext-opengraph`
10+
```sh
11+
python -m pip install sphinxext-opengraph
12+
```
1013

1114
## Usage
1215
Just add `sphinxext.opengraph` to your extensions list in your `conf.py`
@@ -17,9 +20,9 @@ extensions = [
1720
]
1821
```
1922
## Options
20-
These values are placed in the conf.py of your sphinx project.
23+
These values are placed in the `conf.py` of your Sphinx project.
2124

22-
Users hosting documentation on Read The Docs *do not* need to set any of the following unless custom configuration is wanted. The extension will automatically retrieve your site url.
25+
Users hosting documentation on Read The Docs *do not* need to set any of the following unless custom configuration is wanted. The extension will automatically retrieve your site URL.
2326

2427
* `ogp_site_url`
2528
* This config option is very important, set it to the URL the site is being hosted on.
@@ -32,12 +35,14 @@ Users hosting documentation on Read The Docs *do not* need to set any of the fol
3235
* `ogp_image_alt`
3336
* 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.
3437
* `ogp_use_first_image`
35-
* 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.
38+
* 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.
3639
* `ogp_type`
37-
* 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.
40+
* This sets the ogp type attribute, for more information on the types available please take a look at [https://ogp.me/#types](https://ogp.me/#types). By default it is set to `website`, which should be fine for most use cases.
3841
* `ogp_custom_meta_tags`
3942
* This is not required. List of custom html snippets to insert.
40-
43+
* `ogp_enable_meta_description`
44+
* This is not required. When `True`, generates `<meta name="description" content="...">` from the page.
45+
4146
## Example Config
4247

4348
### Simple Config
@@ -59,20 +64,23 @@ ogp_custom_meta_tags = [
5964
'<meta property="og:ignore_canonical" content="true" />',
6065
]
6166

67+
ogp_enable_meta_description = True
6268
```
6369

6470
## Per Page Overrides
65-
[Field lists](https://www.sphinx-doc.org/en/master/usage/restructuredtext/field-lists.html) are used to allow you to override certain settings on each page and set unsupported arbitrary OpenGraph tags.
71+
[Field lists](https://www.sphinx-doc.org/en/master/usage/restructuredtext/field-lists.html) are used to allow you to override certain settings on each page and set unsupported arbitrary Open Graph tags.
6672

6773
Make sure you place the fields at the very start of the document such that Sphinx will pick them up and also won't build them into the html.
6874

6975
### Overrides
70-
These are some overrides that can be used, you can actually override any tag and field lists will always take priority.
76+
These are some overrides that can be used on individual pages, you can actually override any tag and field lists will always take priority.
7177

7278
* `:og_description_length:`
73-
* Configure the amount of characters to grab for the description of the page. If the value isn't a number it will fall back to `ogp_description_length`. Note the slightly different syntax because this isn't directly an OpenGraph tag.
79+
* Configure the amount of characters to grab for the description of the page. If the value isn't a number it will fall back to `ogp_description_length`. Note the slightly different syntax because this isn't directly an Open Graph tag.
7480
* `:og:description:`
7581
* Lets you override the description of the page.
82+
* `:description:` or `.. meta::\n :description:`
83+
* Sets the `<meta name="description" content="...">` description.
7684
* `:og:title:`
7785
* Lets you override the title of the page.
7886
* `:og:type:`
@@ -95,7 +103,7 @@ Page contents
95103
```
96104

97105
### Arbitrary Tags[^1]
98-
Additionally, you can use field lists to add any arbitrary OpenGraph tag not supported by the extension. The syntax for arbitrary tags is the same with `:og:tag: content`. For Example:
106+
Additionally, you can use field lists to add any arbitrary Open Graph tag not supported by the extension. The syntax for arbitrary tags is the same with `:og:tag: content`. For example:
99107

100108
```rst
101109
:og:video: http://example.org/video.mp4

docs/source/conf.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@
4444
# This pattern also affects html_static_path and html_extra_path.
4545
exclude_patterns = []
4646

47-
4847
# -- Options for HTML output -------------------------------------------------
4948

5049
# The theme to use for HTML and HTML Help pages. See the documentation for

sphinxext/opengraph/__init__.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from sphinx.application import Sphinx
77

88
from .descriptionparser import get_description
9+
from .metaparser import get_meta_description
910
from .titleparser import get_title
1011

1112
import os
@@ -28,10 +29,10 @@
2829
}
2930

3031

31-
def make_tag(property: str, content: str) -> str:
32+
def make_tag(property: str, content: str, type_: str = "property") -> str:
3233
# Parse quotation, so they won't break html tags if smart quotes are disabled
3334
content = content.replace('"', "&quot;")
34-
return f'<meta property="{property}" content="{content}" />'
35+
return f'<meta {type_}="{property}" content="{content}" />'
3536

3637

3738
def get_tags(
@@ -45,6 +46,7 @@ def get_tags(
4546
if fields is None:
4647
fields = {}
4748
tags = {}
49+
meta_tags = {} # For non-og meta tags
4850

4951
# Set length of description
5052
try:
@@ -105,6 +107,11 @@ def get_tags(
105107
if description:
106108
tags["og:description"] = description
107109

110+
if config["ogp_enable_meta_description"] and not get_meta_description(
111+
context["metatags"]
112+
):
113+
meta_tags["description"] = description
114+
108115
# image tag
109116
# Get basic values from config
110117
if "og:image" in fields:
@@ -160,7 +167,9 @@ def get_tags(
160167

161168
return (
162169
"\n".join(
163-
[make_tag(p, c) for p, c in tags.items()] + config["ogp_custom_meta_tags"]
170+
[make_tag(p, c) for p, c in tags.items()]
171+
+ [make_tag(p, c, "name") for p, c in meta_tags.items()]
172+
+ config["ogp_custom_meta_tags"]
164173
)
165174
+ "\n"
166175
)
@@ -186,6 +195,7 @@ def setup(app: Sphinx) -> Dict[str, Any]:
186195
app.add_config_value("ogp_type", "website", "html")
187196
app.add_config_value("ogp_site_name", None, "html")
188197
app.add_config_value("ogp_custom_meta_tags", [], "html")
198+
app.add_config_value("ogp_enable_meta_description", True, "html")
189199

190200
app.connect("html-page-context", html_page_context)
191201

sphinxext/opengraph/metaparser.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
from html.parser import HTMLParser
2+
3+
4+
class HTMLTextParser(HTMLParser):
5+
"""
6+
Parse HTML into text
7+
"""
8+
9+
def __init__(self):
10+
super().__init__()
11+
self.meta_description = None
12+
13+
def handle_starttag(self, tag, attrs) -> None:
14+
# For example:
15+
# attrs = [("content", "My manual description"), ("name", "description")]
16+
if ("name", "description") in attrs:
17+
self.meta_description = True
18+
for name, value in attrs:
19+
if name == "content":
20+
self.meta_description = value
21+
break
22+
23+
24+
def get_meta_description(meta_tags: str) -> bool:
25+
htp = HTMLTextParser()
26+
htp.feed(meta_tags)
27+
htp.close()
28+
29+
return htp.meta_description
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
extensions = ["sphinxext.opengraph"]
2+
3+
master_doc = "index"
4+
exclude_patterns = ["_build"]
5+
6+
html_theme = "basic"
7+
8+
ogp_site_url = "http://example.org/en/latest/"
9+
10+
ogp_enable_meta_description = True
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
.. meta::
2+
:description: My manual description
3+
4+
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse at lorem ornare, fringilla massa nec, venenatis mi. Donec erat sapien, tincidunt nec rhoncus nec, scelerisque id diam. Orci varius natoque penatibus et magnis dis parturient mauris.
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
extensions = ["sphinxext.opengraph"]
2+
3+
master_doc = "index"
4+
exclude_patterns = ["_build"]
5+
6+
html_theme = "basic"
7+
8+
ogp_site_url = "http://example.org/en/latest/"
9+
10+
ogp_enable_meta_description = True
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
:og:description: My manual og:description
2+
3+
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse at lorem ornare, fringilla massa nec, venenatis mi. Donec erat sapien, tincidunt nec rhoncus nec, scelerisque id diam. Orci varius natoque penatibus et magnis dis parturient mauris.
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
extensions = ["sphinxext.opengraph"]
2+
3+
master_doc = "index"
4+
exclude_patterns = ["_build"]
5+
6+
html_theme = "basic"
7+
8+
ogp_site_url = "http://example.org/en/latest/"
9+
10+
enable_meta_description = True

0 commit comments

Comments
 (0)