Customizing Sphinx visuals was somewhat upsetting to me at first, since the process is not really straightforward and the documentation is scarce. It could be a little bit user-friendlier. However, as soon as you get grip at basics, it gets pretty smooth and simple. You may have already tried copying over the default theme only to discover, that there is nothing particularly useful in there for an inquisitive scholar, since only one of the standard Sphinx themes is in fact editable and complete, the rest of them simply inherit its properties to add some minor alterations. This theme is called Basic and it’s a minimal sandbox template, the only theme that could be helpful for getting to the very bottom of Sphinx customization. Later you’d be able to inherit it and create a template, consisting only of alterations, but for a start it’s OK to copy the Basic in its entirety.
Hopefully, you’ve already created a folder for your Sphinx project and initiated it by issuing:
Or you may have an already existing Sphinx project, you want to theme — it’s up to you. In your project folder create a _themes directory and then rename and copy the theme folder there. Basic theme, perhaps, should be located in site_packages folder of your active Python install. On my Mac it’s: /Library/Python/2.7/site-packages/Sphinx-1.2b1-py2.7.egg/sphinx/themes/basic/, but Python on Mac OS X is just weird. If you’re using Linux or Windows, you should look it up yourself.
Next step would be to change conf.py of your project, accordingly. First, we should make sure, that the following line is uncommented and in fact correct:
html_theme_path = ['_themes']
Don’t forget to check the value of the html_theme parameter above:
html_theme = 'renamed_basic'
Example I: Spoiler
.. admonition:: Request :class: splr Request example and parameters.
If implemented correctly, this script should turn the splr admonition into a collapsible drawer. I’ve been actively using this, when documenting HTTP APIs, since it’s very helpful to hide request and response by default. Note, that you could also use this method for special CSS effects. Imagine, if aside from usual note, warning and tip you could have yellow, blue and purple boxes for whatever reason you can think of? Well, it couldn’t be any simpler. Admonitions are good default containers for some parts of your text, that should differ in design or function from the rest of the page.
Example II: Interactive TOC in Sidebar
You may have noticed, that Sphinx often adds TOC to sidebar automatically, if it’s not explicitly placed in the page itself. While this is certainly a very useful feature, sometimes things get out of control. I didn’t use the worst case in the picture on the right, but it could get up to innumerable 1st level sections, each of them could have a number of subsections and so on. Sometimes it is a clear sign, that the page should be reorganized into multiple standalone pages, united by a category, but it’s not always possible or needed. It’s perfectly alright to have a long and deep TOC in some cases and Default Sphinx theme is terrible in that regard.
You could use an updated version of the algorithm from the previous example to collapse some parts of the TOC by default. Note, how this script works with ul and li tags of the TOC tree list. Some stuff is applied recursively on the highest level of the list, some — on the subsequent levels. Especially it is well observed in different styles applied to different levels of the list, so that you could tell whether it is 1st, 2nd or even 3rd level title. Here is the full script:
Perhaps, it won’t look very well, but it is a very simplified version to illustrate the concept. If you get the idea, you may alter or add .css methods to achieve more plausible visuals. You could also work on lower title levels, but you will have to figure it all out yourself. In this version algorithm works only with three headings levels from <h1> to <h2>.
That’s it. I’ve compiled these examples as a full-featured theme project on GitHub. I’m going to polish it to some extent and perhaps, implement more interactive stuff over time. Feel free to contribute to this little project. If you come upon any issue with the examples above, or the theoretical rambling in the beginning — let me know. Sure, I’ve tested both scripts, but you never know. Also, you’re free to use any of these examples as a building block in your work with no attribution, since they’re rather generic and simple.