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 %}