When running django documentation to preview my changes locally, I spent a fair amount of time thinking something was missing because it looks [like this], but then I asked (Django documentation — Django 5.0.6 documentation) other contributors and they said this is the usual local theme.
I was wondering why this is the case as it added a bit of confusion and it’s usually better to be able to preview things as they’ll finally be rendered in production.
Hoping I can add an explanation about this in the “documentation contribution” guidelines or in the README.md or else, try and make the local theme the same as the official one.
That’s a great question, and I agree that this mismatch is confusing.
I’m not sure I have the whole answer to your question (and there might be multiple “why”-s here), but I think I can shed some light on some aspects at least.
The yellow/green style (which you get when building the docs locally, or - as you pointed out - on ReadTheDocs) is Django’s old official theme. This is how the website used to look like, until it was overhauled about 10 years ago with a new design, which we still have today.
I was on the team that led the implementation of that “new” design, and I have a vague memory that the topic of the local docs theme was mentioned, but that it was decided that the “old” theme would stay.
My recollection is that it had something to do with licensing. I might be wrong here, but the old theme has the same license as Django (being included in the repository alongside the code), whereas the new theme does not have a public license (the DSF owns the rights I think).
Because this has to do with licensing, it might be tricky to change things, but maybe the color palette could be changed at least? Surely that falls within the license requirements (he says, being completely ignorant of licensing laws).
In any case, if you do end up making a pull request to the README, please feel free to tag me if you have questions or want a review (I have the same username on github or in the Django #contributor-discussion channel).
I wanted to raise this again and see if we can find a solution. The CSS mismatch between the production docs site vs. local/preview builds complicates working on the docs. It’s not just color schemes: there are (visual) semantic differences between the two styles. Example below.
If there’s a licensing issue with the DSF owning the docs site styles, I’d think that could be solved somehow. (Do we know anyone at the DSF? ) Maybe we could vendor the DSF’s CSS into Django’s docs with the DSF’s license intact, like we do for other vendored code (such as docs/_theme/djangodocs/static/fontawesome).
Here’s an example: we want to versionchanged:: two things related to the same function. There’s a bug in my reST source—can you spot it from the local docs build? (I didn’t.)
I ran into this particular issue in my own recent documentation work. But I’m guessing it’s not the only significant difference between the old and new docs CSS.
[Related aside: The bundled CSS on docs.djangoproject.com is missing a /*! license or copyright comment for DSF’s CSS, making it seem like it’s covered by FontAwesome’s MIT license statement from earlier in the bundle.]
Looking into it a bit, I think the issues may be more technical and content than licensing-related:
The djangoproject style source is scss, so needs to be compiled to css. We might not want to depend on an scss compiler for Django docs builds. (Or it might be OK? We already have other docs build requirements.)
The docs-specific styles are mixed in with other djangoproject.com site styles, and it might be difficult to separate them. (See _style.scss. This includes things we’d want, like shared layout and base styles, plus things we don’t need, like fundraising and hero modules. But maybe that extra CSS is OK for now to get styles matching, and we could work on cleaning it up later?)
Fwiw, the djangoproject.com source is under a BSD license, so I think we could certainly vendor parts of it into Django with appropriate license attribution. (There might be some concerns about the trademarked logos that the CSS places in the header, but we could maybe avoid those. Also, IANAL.)
The main difficulty turned out to be adapting (and reducing) the djangoproject.com templates for use directly with Sphinx. There will be a bit of effort to monitor future upstream template changes, but looking at the history very few changes would have affected the parts I copied anyway. (So it might be OK to just ignore upstream template updates until something breaks.)
For updating the CSS and other static assets, I added a docs Makefile recipe that automates fetching them from the djangoproject.com repo. This is run only on demand—not as part of ordinary docs builds—and the results are meant to be committed to the django repo.
Let me know what you think or if you spot any problems.
I’ve completed the missing parts of the PR to update Django’s docs theme and believe it’s ready for review. (And I found a few other bugs along the way, reported separately.)
Somewhat related, how would we feel about changing the ReadTheDocs config to use Sphinx’s “dirhtml” builder? That would make the URLs in PR preview builds closer to what you’d find on docs.djangoproject.com (no .html extensions).
Following up here as Mike asked in the PR, now that the 6.1beta is out.
We (Fellows) have two concerns about ingesting the djangoproject.com CSS into Django, and then I (Natalia) have a proposal to look at the opposite direction.
1. Licensing/provenance. The current website CSS styling was contributed as an in-kind donation, and that donation does not cover/include shipping the CSS inside Django’s source tree/released artifacts. This is the same hesitation @bmispelon raised earlier in the thread, and I don’t think we can wave it away.
2. Maintenance. A copy of the compiled CSS in django/django would drift from its source. Realistically we wouldn’t keep it in sync, and we’d recreate the exact staleness this ticket is about, just against a newer baseline.
3. A different direction (my strong preference). I’d rather drop our bespoke local theme entirely and adopt the Read the Docs theme, instead of ingesting the production CSS. Adopting sphinx-rtd-theme fixes exactly what the ticket is about (the current local theme has usability problems, is missing semantically-important styles, and has no dark mode), with zero licensing risk and zero sync burden, since it’s maintained by its own community.
Worth making explicit why this is safe
docs.djangoproject.com doesn't use the Sphinx HTML theme at all. It consumes the JSON builder output and applies the site's own templates and styles, so docs/_theme/djangodocs/ only affects local and RTD preview builds therefore production is unaffected by whatever we pick there. The custom directives emit their HTML from docs/_ext/djangodocs.py regardless of theme, so switching themes doesn't change the content the site ingests.
There’s a second benefit I care about: it removes the confusion. Right now local looks a little somehow like the website but not quite, and that near-match is what trips authors up (IMHO). Adopting something clearly different, and equal to a widely known theme, sets clear expectations: contributors know they’re previewing in a standard Sphinx theme, not a stand-in for docs.djangoproject.com. A maintained theme with clear admonition boxes would also have surfaced the versionchanged issue that Mike raised.
The one genuinely functional piece in our django theme is the ~46-line pure-CSS console-tabs stylesheet, which we can keep as a small supplemental stylesheet on top of the base theme.
@medmunds I really appreciate the work in PR #21416 but I’d love to redirect that toward adopting sphinx-rtd-theme (or another well known and well maintained theme), which gets us the same benefit on a foundation we can actually sustain.
Thanks for following up @nessita. I think I agree with your preference for adopting a well-maintained Sphinx theme rather than trying to maintain our own.
Incidentally, I just learned that downloadable copies of the docs from docs.djangoproject.com use the (old) theme that’s bundled with Django, so don’t match what you see on the docs site anyway.
Some specific responses, in reverse order…
I agree. And at risk of bikeshedding…
I would caution against sphinx-rtd-theme. (I say this as someone who has long had a todo item to replace it in my own projects.) Its CSS is complicated and fragile (based on the Wyrm and Bourbon sass libraries that haven’t been maintained for over a decade). Perhaps as a result, it has been prone to regressions.
The Furo theme seems quite popular and well maintained. (PyPA has adopted it for many of its tools.) It supports light/dark mode, can be customized with CSS properties, and is MIT licensed. (My only concern is there may be some accessibility issues with its admonition fontsize and contrast, but there are CSS properties to change those if necessary.)
True, but at least it is a newer baseline. And unlike the current theme, it has upstream source that’s actively maintained. With an eye toward accessibility. (And fwiw, my PR did try to automate the syncing process. But I take your point.)
So… this status is not reflected in the djangoproject.com repo, which currently seems to place the source for the styling under the same permissive BSD license as everything else (that isn’t vendored) in the repo. If the DSF doesn’t have the rights to relicense and permit redistribution of the style source, that should really get corrected.
Heh, looks like we had the same weekend project. In addition to Furo, I tried building with pydata-sphinx-theme. (There were a couple of things about Furo that bothered me after seeing it in action.)
Neither theme is perfect, but both are quite good and improvements over what we have now:
I also updated the console-tabs djangodocs Sphinx extension to improve compatibility with any theme and fix a handful of other problems (first commit in each PR). For the console-tabs labels, I’d suggest dropping the icons and going with plain text—here’s why.
These two look great! I like boths, though locally I had furo being stubborn in that if I switched to dark mode, clicking on any link would take me to the page with light mode on. So that was annoying.
PyData theme looks very polished, I like the search input in the navbar, and the dark/light switcher is fancy too. I’m fine with either, but I’m now convinced that we should adopt a mature theme like these instead of having our own.
I’ll close my PR in favor of yours, though I would like to see the set of cleanup changes be its own commit to make the review a bit easier. Also merging this would require some pre-requisite changes in the website, as I’m sure you are aware of since you have been investigating that already.
I find the expanded color palette and overuse of bold and italics with PyData distracting.
My biggest concern with PyData is the navigation. There are three places to navigate: left right, and top. Furo just has two. I find three overwhelming.
Left and right navigation is also what I think we are most likely to choose for djangoproject.com itself once we get around to implementing it (the website already has a site-wide top nav). I know @alexgmin has been pushing hard on a prototype for that. Assuming that roadmap, it would be convenient for the local docs build to have similar navigation.
The only accessibility concern with Furo I saw above sounded like a font-size tweak we can do, so I’m not aware of any serious problems. I also couldn’t reproduce Natalia’s reported bug with the dark mode switcher.
So the winner of my “quick draw” is Furo, but I didn’t spend nearly as much time with the details as you all did. Mike, what were the aspects that soured you on Furo?
To be clear, I don’t know of any serious accessibility bugs in Furo; my concern is the bus factor and the lack of an accessibility process, since we’d be relying on this theme for a long time.
That said, your point about navigation is a strong one. If we go with Furo, I’d want us to check the admonition font size and contrast concern Mike raised and address it as a follow-up.
@medmunds, I’m also curious about what bothered you about Furo.
As I mentioned in July, my initial instinct was Furo, based on its popularity throughout the Python ecosystem. I only started looking for alternatives after spending a bunch of time in Django’s docs built with Furo and running into some nof its limitations. And after finding pydata-sphinx-theme (PST) and spending time with it alongside Furo, I started to feel PST was:
better organized for a large documentation set like Django’s. I think the three-way navigation split is actually quite helpful for Django’s docs and works well with its Díataxis structure. (I have some longer thoughts about organization and navigation, which I’ll put in a separate reply)
more readable to my eyes. This is of course subjective, but I felt PST had better contrast, spacing, and rhythm. Also, PST’s code formatting manages to fit more lines of code in the same space (objectively) while somehow feeling more readable than Furo (subjectively). That’s helpful for viewing longer (blacken-docs’ed) examples without scrolling. (There are some outdatedside-by-side screenshots in GitHub.)
better positioned to minimize customizations and maintenance on Django’s part. (And to minimize docs theme feature requests in Django’s tracker.)
Documentation tends to evolve to work with a particular theme (and vice versa). Django’s docs are currently designed for the djangoproject.com theme. Full stop. (They were originally designed for Django’s custom djangodocs theme, but djangodocs has gone largely unmaintained since djangoproject.com forked and then replaced it on the public docs site. Which is why we’re having this discussion.)
I still believe that the best choice would be using a single Sphinx theme for both the website and standalone docs builds, for all the reasons I raised back in May. But with the unclear licensing status of that part of the djangoproject.com source code[1], the next best choice is selecting a compatible, well-maintained, third-party theme for standalone builds.
“Compatible” and “well-maintained” are doing some heavy lifting there. We want to outsource theme maintenance for the standalone docs. Every time we have to adapt the theme for our use—or adjust our docs to fit the theme—it’s adding maintenance burden on Django’s side. We need to consider not just the initial implementation, but also (somehow) the likelihood of future change requests and Django bug reports against the standalone docs build.
Here’s how I’ve been trying to evaluate that…
Everything in @nessita’s comparison chart. (I had similar notes from July, but not so well organized.) I also looked at:
Dark mode: both support it
High-contrast/forced-colors support: PST works well; Furo has several bugs
Maturity and stability: Furo comes out ahead, and even has an explicit stability policy; PST hasn’t reached 1.0 yet
Support for a variety of screen sizes: both do reasonably well, but Furo’s “on this page” nav is only reachable by scrolling back to the top at medium widths (which makes it nearly useless for jumping around within a page)
How much theme customization is needed to get it to work well with Django’s docs, and what do those changes look like?
Does the theme work well as is? Or do we feel a need to adjust colors or font sizes or icons?
Does the theme support at least the same persistent navigation points as the docs website? (“on this page” ToC, next/prev page, links to main ToC and indexes)
Where customization is desired, is it even possible? Can we use documented extension points that are likely to stay stable (CSS properties, Sphinx config options, etc.)? Or do we have to dig into the theme’s guts (undocumented and potentially fragile CSS selectors, templates marked internal-use-only, etc.)?
What kinds of Django docs changes are needed to make our docs work well with the theme?
Does the theme prohibit any standard Sphinx constructs?
Are there any new, implicit rules for our docs source to avoid breaking the standalone builds (in ways that might not be detected by checks)?
Where docs changes are needed for the theme, do they feel like overall improvements to the docs (that will also benefit djangoproject.com users), or compromises just to make the theme work?
On all of those, I felt PST came out ahead. Just to pick a couple of examples (since this post is already quite long):
Furo does not support local ToCs. We use one in the Settings reference, so will need to remove it or customize Furo as a workaround. (Speaks to Q3.)
Both themes have important navigation hidden by RTD’s preview widgets. I added workarounds (whether to keep them is a separate discussion). The PST version of this is straightforward using defined Bootstrap classes; the Furo version had to use multiple, undocumented selectors and is considerably more complicated. (Speaks to Q2.)
Bottom line, I prefer PST. But the good news is we’ve managed to clean up Django’s Sphinx usage recently so it should be a bit easier to change themes in the future, if we change our minds. (Neither of the PRs is particularly long.)
I’m hoping the Website Working Group takes licensing and reusability into account as part of any redesign proposals. ↩︎
I was composing an argument for why PST’s split header/sidebar navigation is actually good for Django, and think I may have just convinced myself that neither theme is a great option. And that we really need a plan to share a single theme between docs.djangoproject.com and standalone docs builds.
Navigation and sidebars
First, I think PST’s top header is actually quite nice for surfacing our high-level Díataxis groupings (Tutorials, Using, How-to, Reference) as an overall organizing principle for navigating the docs:
But looking at both themes again, it really is useful to have the full site table of contents in one collapsible tree—not just the contents for the current section. Furo’s left sidebar is better than PST’s for Django’s docs. (Both themes agree the right sidebar navigates within the current page.)
So what I really want is PST’s focus on accessibility and broad support for Sphinx, but with Furo’s navigation structure. And… turns out that exists. sphinx-book-theme is based on PST but removes the top nav and replaces it with a Furo-like full-site ToC on the left:
So why not just go with sphinx-book-theme? The project is “in maintenance mode” due to lack of resources.
What problem are we trying to solve?
OK, none of the third-party themes is perfect. Nothing is. Let’s pick one that’s good enough, and it will certainly be better than what we have now. Right?
That brings me back to this (emphasis added):
I’ll go a step further: it would be convenient for the local docs build to have exactly the same navigation structure as the docs website. And the same theme and styling. Because it will still be true that:
The reality is, even if these third-party themes are better than the old djangodocs theme (they are), we still have two different themes for one set of docs. We’ll keep running into confusion that the themes look different. There will still be bugs where content is missing or behaves differently in the standalone builds (and it takes a long time for anyone to notice). We’re addressing some of the usability problems with djangodocs, but we’re not really solving the original issue in this thread.
One theme to rule them all…
Let me turn the question around: can we imagine using any of these third-party Sphinx themes for docs.djangoproject.com? (With some minor customizations, like borrowing the website’s green accent colors and heading/body fonts? And maybe one major customization: making pydata-sphinx-theme use our preferred nav?)
If so, that’s a great path forward: adopt the new theme for Django standalone docs, make plans to use it for docs.djangoproject.com as part of the redesign, and it becomes our one single theme to maintain for both. (And starting with a popular, well-maintained theme should mean a lot less work on our side.)
Or if we can’t imagine basing the docs site on a third-party theme (even with customizations), then I think we should try to come up with a plan for a new djangodocs theme that could be shared between the website and standalone builds. That may not be legally possible with the current site, but it could certainly be a goal for a redesign. (And while that’s in process we could adopt Furo as a temporary fix for the old djangodocs limitations in the standalone builds, knowing it has some accessibility issues.)
So I’ve updated my votes in my earlier comment: I’m -0 on Furo, merely +0 on PST, but +1 on a path to a shared Django docs theme.
I created this by borrowing the font stack and primary accent colors from the website (with documented pydata-sphinx-theme CSS properties). And by borrowing a single template from sphinx-book-theme to get the full site nav in the left sidebar (so it turned out not to be “major” customization).
It would of course need a lot of refinement, but I think demonstrates a shared theme could become workable.