Skip to content

Commit 3897f9c

Browse files
authored
Merge pull request #221 from ByteInternet/json_sitemap
Add json sitemap generator
2 parents 8d8bddb + 6ded664 commit 3897f9c

File tree

2 files changed

+79
-1
lines changed

2 files changed

+79
-1
lines changed

docs/conf.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,13 @@
8787

8888
if os.getenv("DOCS_BASE_URL"):
8989
html_baseurl = os.getenv("DOCS_BASE_URL")
90-
extensions.append("sphinx_sitemap") # Only generate sitemap when we have a base url
90+
# Only generate sitemap when we have a base url
91+
extensions.extend(
92+
[
93+
"sphinx_sitemap",
94+
"hypernode.sphinx.extensions.json_sitemap",
95+
]
96+
)
9197

9298
# Add any paths that contain custom static files (such as style sheets) here,
9399
# relative to this directory. They are copied after the builtin static files,
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import json
2+
import queue
3+
from multiprocessing import Manager
4+
from pathlib import Path
5+
from typing import TYPE_CHECKING
6+
7+
from sphinx.util.logging import getLogger
8+
9+
logger = getLogger(__name__)
10+
11+
if TYPE_CHECKING:
12+
from sphinx.application import Sphinx
13+
14+
"""
15+
This extension was inspired by sphinx-sitemap, which is a generator
16+
for the sitemap.xml file.
17+
"""
18+
19+
20+
def register_page(app: "Sphinx", pagename: str, templatename, context, doctree):
21+
env = app.builder.env
22+
base_url = app.builder.config.html_baseurl
23+
file_suffix = app.builder.config.html_file_suffix or ".html"
24+
25+
if pagename == "404":
26+
return
27+
28+
link = base_url + pagename + file_suffix
29+
page_title = context.get("title")
30+
if page_title:
31+
env.app.json_sitemap_links.put({"url": link, "title": page_title}) # type: ignore[attr-defined]
32+
33+
34+
def write_sitemap(app: "Sphinx", exception):
35+
links = []
36+
while True:
37+
try:
38+
links.append(app.env.app.json_sitemap_links.get_nowait()) # type: ignore[attr-defined]
39+
except queue.Empty:
40+
break
41+
42+
encoded = json.dumps(links)
43+
filename = app.config.json_sitemap_filename
44+
with open(Path(app.outdir) / filename, "w", encoding="utf-8") as f:
45+
f.write(encoded)
46+
47+
logger.info(
48+
f"json-sitemap: {filename} has been generated",
49+
type="json-sitemap",
50+
subtype="information",
51+
)
52+
53+
54+
def init_page_queue(app: "Sphinx"):
55+
builder = getattr(app, "builder", None)
56+
if builder is None:
57+
return
58+
builder.env.is_directory_builder = type(builder).__name__ == "DirectoryHTMLBuilder"
59+
builder.env.app.json_sitemap_links = Manager().Queue()
60+
61+
62+
def setup(app: "Sphinx"):
63+
app.add_config_value("json_sitemap_filename", default="sitemap.json", rebuild="")
64+
app.connect("builder-inited", init_page_queue)
65+
app.connect("html-page-context", register_page)
66+
app.connect("build-finished", write_sitemap)
67+
68+
return {
69+
"version": "1.0",
70+
"parallel_read_safe": True,
71+
"parallel_write_safe": True,
72+
}

0 commit comments

Comments
 (0)