diff options
| author | Mike Edmunds <medmunds@gmail.com> | 2026-06-08 14:43:44 -0700 |
|---|---|---|
| committer | nessita <124304+nessita@users.noreply.github.com> | 2026-06-09 21:56:35 -0300 |
| commit | 9b1db9cb2c38c75b8fb0fc64ba5f73a6012e5b2d (patch) | |
| tree | 7b8976389754f69cee4c0ecea8542f61fa43672b | |
| parent | 867c7c0451f2e67e715da5b55b5bf6696747fdc3 (diff) | |
Fixed #37150 -- Made djangodocs Sphinx extension work with any html builder.
Changed djangodocs extension to register DjangoHTMLTranslator for any
html-format builder (in the builder-inited hook), rather than a limited
list of builders at startup. That fixes missing content in dirhtml and
standard html builds (including ReadTheDocs PR previews):
- Missing console tabs
- Empty divs for versionadded and versionchanged directives
Removed JS code that depended on jQuery, which hasn't worked since
Sphinx 6.0 dropped jQuery in 2023:
- Unnecessary console tabs click handling. (Console tab behavior is
implemented purely in CSS.)
- Client-side hyperlinking of Django template tags and filters in code
examples. (This is also not supported on docs.djangoproject.com.)
Removed custom DjangoStandaloneHTMLBuilder and "djangohtml" builder
type. Its sole purpose was to generate the "templatebuiltins.js" file
used for the (non-functional) client-side template filter/tag linking.
Changed docs "make html" target from "djangohtml" to standard "html".
| -rw-r--r-- | docs/Makefile | 2 | ||||
| -rw-r--r-- | docs/_ext/djangodocs.py | 54 | ||||
| -rw-r--r-- | docs/_theme/djangodocs/layout.html | 54 |
3 files changed, 12 insertions, 98 deletions
diff --git a/docs/Makefile b/docs/Makefile index 41ed522daf..736cab6d7f 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -58,7 +58,7 @@ clean: -rm -rf $(BUILDDIR)/* html: - $(SPHINXBUILD) -b djangohtml $(ALLSPHINXOPTS) $(BUILDDIR)/html + $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." diff --git a/docs/_ext/djangodocs.py b/docs/_ext/djangodocs.py index a979a8e30a..a82cb5df96 100644 --- a/docs/_ext/djangodocs.py +++ b/docs/_ext/djangodocs.py @@ -2,8 +2,6 @@ Sphinx plugins for Django documentation. """ -import json -import os import re from docutils import nodes @@ -11,12 +9,10 @@ from docutils.parsers.rst import Directive from docutils.statemachine import ViewList from sphinx import addnodes from sphinx import version_info as sphinx_version -from sphinx.builders.html import StandaloneHTMLBuilder from sphinx.directives.code import CodeBlock from sphinx.domains.std import Cmdoption from sphinx.errors import ExtensionError from sphinx.util import logging -from sphinx.util.console import bold from sphinx.writers.html import HTMLTranslator logger = logging.getLogger(__name__) @@ -55,9 +51,7 @@ def setup(app): app.add_config_value("django_next_version", "0.0", True) app.add_directive("versionadded", VersionDirective) app.add_directive("versionchanged", VersionDirective) - app.add_builder(DjangoStandaloneHTMLBuilder) - app.set_translator("djangohtml", DjangoHTMLTranslator) - app.set_translator("json", DjangoHTMLTranslator) + app.connect("builder-inited", set_django_html_translator) app.add_node( ConsoleNode, html=(visit_console_html, None), @@ -72,6 +66,11 @@ def setup(app): return {"parallel_read_safe": True} +def set_django_html_translator(app): + if app.builder.format == "html": + app.set_translator(app.builder.name, DjangoHTMLTranslator, override=True) + + class VersionDirective(Directive): has_content = True required_arguments = 1 @@ -189,36 +188,6 @@ def parse_django_admin_node(env, sig, signode): return command -class DjangoStandaloneHTMLBuilder(StandaloneHTMLBuilder): - """ - Subclass to add some extra things we need. - """ - - name = "djangohtml" - - def finish(self): - super().finish() - logger.info(bold("writing templatebuiltins.js...")) - xrefs = self.env.domaindata["std"]["objects"] - templatebuiltins = { - "ttags": [ - n - for ((t, n), (k, a)) in xrefs.items() - if t == "templatetag" and k == "ref/templates/builtins" - ], - "tfilters": [ - n - for ((t, n), (k, a)) in xrefs.items() - if t == "templatefilter" and k == "ref/templates/builtins" - ], - } - outfilename = os.path.join(self.outdir, "templatebuiltins.js") - with open(outfilename, "w") as fp: - fp.write("var django_template_builtins = ") - json.dump(templatebuiltins, fp) - fp.write(";\n") - - class ConsoleNode(nodes.literal_block): """ Custom node to override the visit/depart event handlers at registration @@ -248,7 +217,7 @@ def depart_console_dummy(self, node): def visit_console_html(self, node): """Generate HTML for the console directive.""" - if self.builder.name in ("djangohtml", "json") and node["win_console_text"]: + if self.builder.format == "html" and node["win_console_text"]: # Put a mark on the document object signaling the fact the directive # has been used on it. self.document._console_directive_used_flag = True @@ -363,9 +332,9 @@ class ConsoleDirective(CodeBlock): self.arguments = ["console"] lit_blk_obj = super().run()[0] - # Only do work when the djangohtml HTML Sphinx builder is being used, + # Only do work when an HTML-format Sphinx builder is being used, # invoke the default behavior for the rest. - if env.app.builder.name not in ("djangohtml", "json"): + if env.app.builder.format != "html": return [lit_blk_obj] lit_blk_obj["uid"] = str(env.new_serialno("console")) @@ -385,9 +354,8 @@ class ConsoleDirective(CodeBlock): def html_page_context_hook(app, pagename, templatename, context, doctree): # Put a bool on the context used to render the template. It's used to - # control inclusion of console-tabs.css and activation of the JavaScript. - # This way it's include only from HTML files rendered from reST files where - # the ConsoleDirective is used. + # control inclusion of console-tabs.css. This way it's included only from + # HTML files rendered from reST files where the ConsoleDirective is used. context["include_console_assets"] = getattr( doctree, "_console_directive_used_flag", False ) diff --git a/docs/_theme/djangodocs/layout.html b/docs/_theme/djangodocs/layout.html index 487c2b4922..6d07375d07 100644 --- a/docs/_theme/djangodocs/layout.html +++ b/docs/_theme/djangodocs/layout.html @@ -17,60 +17,6 @@ {%- endmacro %} {% block extrahead %} -{# When building htmlhelp (CHM format) disable jQuery inclusion, #} -{# as it causes problems in compiled CHM files. #} -{% if builder != "htmlhelp" %} -{{ super() }} -<script src="{{ pathto('templatebuiltins.js', 1) }}"></script> -<script> -(function($) { - if (!django_template_builtins) { - // templatebuiltins.js missing, do nothing. - return; - } - $(document).ready(function() { - // Hyperlink Django template tags and filters - var base = "{{ pathto('ref/templates/builtins') }}"; - if (base == "#") { - // Special case for builtins.html itself - base = ""; - } - // Tags are keywords, class '.k' - $("div.highlight\\-html\\+django span.k").each(function(i, elem) { - var tagname = $(elem).text(); - if ($.inArray(tagname, django_template_builtins.ttags) != -1) { - var fragment = tagname.replace(/_/, '-'); - $(elem).html("<a href='" + base + "#" + fragment + "'>" + tagname + "</a>"); - } - }); - // Filters are functions, class '.nf' - $("div.highlight\\-html\\+django span.nf").each(function(i, elem) { - var filtername = $(elem).text(); - if ($.inArray(filtername, django_template_builtins.tfilters) != -1) { - var fragment = filtername.replace(/_/, '-'); - $(elem).html("<a href='" + base + "#" + fragment + "'>" + filtername + "</a>"); - } - }); - }); -})(jQuery); -{%- if include_console_assets -%} -(function($) { - $(document).ready(function() { - $(".c-tab-unix").on("click", function() { - $("section.c-content-unix").show(); - $("section.c-content-win").hide(); - $(".c-tab-unix").prop("checked", true); - }); - $(".c-tab-win").on("click", function() { - $("section.c-content-win").show(); - $("section.c-content-unix").hide(); - $(".c-tab-win").prop("checked", true); - }); - }); -})(jQuery); -{%- endif -%} -</script> -{% endif %} {%- if include_console_assets -%} <link rel="stylesheet" href="{{ pathto('_static/console-tabs.css', 1) }}"> {%- endif -%} |
