From a2919ec0817c808f4c97e3325986666523c25b8f Mon Sep 17 00:00:00 2001
From: Adam Turner <9087854+aa-turner@users.noreply.github.com>
Date: Sun, 13 Apr 2025 10:37:08 +0100
Subject: [PATCH 1/2] Use `string.Template` to render `indexsidebar.html`
---
build_docs.py | 40 ++++++++++++++++++++++---------------
templates/indexsidebar.html | 22 +++++---------------
2 files changed, 29 insertions(+), 33 deletions(-)
diff --git a/build_docs.py b/build_docs.py
index e40259c..836e5ca 100755
--- a/build_docs.py
+++ b/build_docs.py
@@ -143,16 +143,6 @@ def current_dev(self) -> Version:
"""Find the current CPython version in development."""
return max(self, key=Version.as_tuple)
- def setup_indexsidebar(self, current: Version, dest_path: Path) -> None:
- """Build indexsidebar.html for Sphinx."""
- template_path = HERE / "templates" / "indexsidebar.html"
- template = jinja2.Template(template_path.read_text(encoding="UTF-8"))
- rendered_template = template.render(
- current_version=current,
- versions=list(reversed(self)),
- )
- dest_path.write_text(rendered_template, encoding="UTF-8")
-
@dataclasses.dataclass(frozen=True, kw_only=True, slots=True)
class Version:
@@ -529,9 +519,9 @@ class DocBuilder:
"""Builder for a CPython version and a language."""
version: Version
- versions: Versions
language: Language
cpython_repo: Repository
+ indexsidebar_content: bytes
switchers_content: bytes
build_root: Path
www_root: Path
@@ -667,10 +657,8 @@ def build(self) -> None:
text = text.replace(" -A switchers=1", "")
(self.checkout / "Doc" / "Makefile").write_text(text, encoding="utf-8")
- self.versions.setup_indexsidebar(
- self.version,
- self.checkout / "Doc" / "tools" / "templates" / "indexsidebar.html",
- )
+ indexsidebar_path = self.checkout / "Doc/tools/templates/indexsidebar.html"
+ indexsidebar_path.write_bytes(self.indexsidebar_content)
run_with_logging([
"make",
"-C",
@@ -1099,6 +1087,7 @@ def build_docs(args: argparse.Namespace) -> int:
force_build = args.force
del args.force
+ isb_content, eol_isb_content = render_indexsidebar(versions)
switchers_content = render_switchers(versions, languages)
build_succeeded = set()
@@ -1118,12 +1107,14 @@ def build_docs(args: argparse.Namespace) -> int:
scope = sentry_sdk.get_isolation_scope()
scope.set_tag("version", version.name)
scope.set_tag("language", language.tag)
- cpython_repo.update()
+ cpython_repo.update()
+ v_isb_content = isb_content if version.status != "EOL" else eol_isb_content
builder = DocBuilder(
version,
versions,
language,
cpython_repo,
+ v_isb_content,
switchers_content,
**vars(args),
)
@@ -1179,6 +1170,23 @@ def parse_languages_from_config() -> Languages:
return Languages.from_json(config["defaults"], config["languages"])
+def render_indexsidebar(versions: Versions) -> tuple[bytes, bytes]:
+ """Pre-render indexsidebar.html for Sphinx."""
+ docs_by_version = f"""\
+
{{% trans %}}Docs by version{{% endtrans %}}
+
+"""
+
+ template_path = HERE / "templates" / "indexsidebar.html"
+ template = Template(template_path.read_text(encoding="UTF-8"))
+ rendered_template = template.substitute(DOCS_BY_VERSION=docs_by_version).encode()
+ eol_template = template.substitute(DOCS_BY_VERSION="").encode()
+ return rendered_template, eol_template
+
+
def render_switchers(versions: Versions, languages: Languages) -> bytes:
language_pairs = sorted((l.tag, l.switcher_label) for l in languages if l.in_prod) # NoQA: E741
version_pairs = [(v.name, v.picker_label) for v in reversed(versions)]
diff --git a/templates/indexsidebar.html b/templates/indexsidebar.html
index 3a56219..d5a0cc8 100644
--- a/templates/indexsidebar.html
+++ b/templates/indexsidebar.html
@@ -1,30 +1,18 @@
{#
-Beware, this file is rendered twice via Jinja2:
-- First by build_docs.py, given 'current_version' and 'versions'.
-- A 2nd time by Sphinx.
+Beware, this file is rendered twice:
+- First by build_docs.py using string.Template, given '$DOCS_BY_VERSION'.
+- Second time by Sphinx, using Jinja.
#}
-{% raw %}
{% trans %}Download{% endtrans %}
{% trans %}Download these documents{% endtrans %}
-{% endraw %}
-{% if current_version.status != "EOL" %}
-{% raw %}{% trans %}Docs by version{% endtrans %}
{% endraw %}
-
-{% endif %}
-{% raw %}
+$DOCS_BY_VERSION
{% trans %}Other resources{% endtrans %}
-{% endraw %}
From 21508d65af6d1c705f814cafa39ee0eb687c9dbb Mon Sep 17 00:00:00 2001
From: Adam Turner <9087854+aa-turner@users.noreply.github.com>
Date: Sun, 13 Apr 2025 10:57:34 +0100
Subject: [PATCH 2/2] Use a static docs_by_version file
---
build_docs.py | 42 ++++++++++++++++-----------------
templates/_docs_by_version.html | 11 +++++++++
templates/indexsidebar.html | 13 +++++-----
3 files changed, 37 insertions(+), 29 deletions(-)
create mode 100644 templates/_docs_by_version.html
diff --git a/build_docs.py b/build_docs.py
index 836e5ca..9b498fe 100755
--- a/build_docs.py
+++ b/build_docs.py
@@ -521,7 +521,7 @@ class DocBuilder:
version: Version
language: Language
cpython_repo: Repository
- indexsidebar_content: bytes
+ docs_by_version_content: bytes
switchers_content: bytes
build_root: Path
www_root: Path
@@ -657,8 +657,7 @@ def build(self) -> None:
text = text.replace(" -A switchers=1", "")
(self.checkout / "Doc" / "Makefile").write_text(text, encoding="utf-8")
- indexsidebar_path = self.checkout / "Doc/tools/templates/indexsidebar.html"
- indexsidebar_path.write_bytes(self.indexsidebar_content)
+ self.setup_indexsidebar()
run_with_logging([
"make",
"-C",
@@ -701,6 +700,18 @@ def build_venv(self) -> None:
run([venv_path / "bin" / "python", "-m", "pip", "freeze", "--all"])
self.venv = venv_path
+ def setup_indexsidebar(self) -> None:
+ """Copy indexsidebar.html for Sphinx."""
+ tmpl_src = HERE / "templates"
+ tmpl_dst = self.checkout / "Doc" / "tools" / "templates"
+ dbv_path = tmpl_dst / "_docs_by_version.html"
+
+ shutil.copy(tmpl_src / "indexsidebar.html", tmpl_dst / "indexsidebar.html")
+ if self.version.status != "EOL":
+ dbv_path.write_bytes(self.docs_by_version_content)
+ else:
+ shutil.copy(tmpl_src / "_docs_by_version.html", dbv_path)
+
def copy_build_to_webroot(self, http: urllib3.PoolManager) -> None:
"""Copy a given build to the appropriate webroot with appropriate rights."""
logging.info("Publishing start.")
@@ -1087,7 +1098,7 @@ def build_docs(args: argparse.Namespace) -> int:
force_build = args.force
del args.force
- isb_content, eol_isb_content = render_indexsidebar(versions)
+ docs_by_version_content = render_docs_by_version(versions).encode()
switchers_content = render_switchers(versions, languages)
build_succeeded = set()
@@ -1108,13 +1119,11 @@ def build_docs(args: argparse.Namespace) -> int:
scope.set_tag("version", version.name)
scope.set_tag("language", language.tag)
cpython_repo.update()
- v_isb_content = isb_content if version.status != "EOL" else eol_isb_content
builder = DocBuilder(
version,
- versions,
language,
cpython_repo,
- v_isb_content,
+ docs_by_version_content,
switchers_content,
**vars(args),
)
@@ -1170,21 +1179,10 @@ def parse_languages_from_config() -> Languages:
return Languages.from_json(config["defaults"], config["languages"])
-def render_indexsidebar(versions: Versions) -> tuple[bytes, bytes]:
- """Pre-render indexsidebar.html for Sphinx."""
- docs_by_version = f"""\
-{{% trans %}}Docs by version{{% endtrans %}}
-
-"""
-
- template_path = HERE / "templates" / "indexsidebar.html"
- template = Template(template_path.read_text(encoding="UTF-8"))
- rendered_template = template.substitute(DOCS_BY_VERSION=docs_by_version).encode()
- eol_template = template.substitute(DOCS_BY_VERSION="").encode()
- return rendered_template, eol_template
+def render_docs_by_version(versions: Versions) -> str:
+ """Generate content for _docs_by_version.html."""
+ links = [f'{v.title}' for v in reversed(versions)]
+ return "\n".join(links)
def render_switchers(versions: Versions, languages: Languages) -> bytes:
diff --git a/templates/_docs_by_version.html b/templates/_docs_by_version.html
new file mode 100644
index 0000000..1a84cfb
--- /dev/null
+++ b/templates/_docs_by_version.html
@@ -0,0 +1,11 @@
+{#
+This file is only used in indexsidebar.html, where it is included in the docs
+by version list. For non-end-of-life branches, build_docs.py overwrites this
+list with the full list of versions.
+
+Keep the following two files synchronised:
+* cpython/Doc/tools/templates/_docs_by_version.html
+* docsbuild-scripts/templates/_docs_by_version.html
+#}
+{% trans %}Stable{% endtrans %}
+{% trans %}In development{% endtrans %}
diff --git a/templates/indexsidebar.html b/templates/indexsidebar.html
index d5a0cc8..eea29e2 100644
--- a/templates/indexsidebar.html
+++ b/templates/indexsidebar.html
@@ -1,12 +1,11 @@
-{#
-Beware, this file is rendered twice:
-- First by build_docs.py using string.Template, given '$DOCS_BY_VERSION'.
-- Second time by Sphinx, using Jinja.
-#}
-
{% trans %}Download{% endtrans %}
{% trans %}Download these documents{% endtrans %}
-$DOCS_BY_VERSION
+{% trans %}Docs by version{% endtrans %}
+
{% trans %}Other resources{% endtrans %}
{# XXX: many of these should probably be merged in the main docs #}