.. _seed-0130: ========================= 0130: Update Sphinx theme ========================= .. seed:: :number: 130 :name: Update Sphinx theme :status: Accepted :proposal_date: 2024-08-28 :cl: 232591 :authors: Kayce Basques :facilitator: Anthony DiGirolamo .. _seed-0130-summary: ------- Summary ------- .. _pydata-sphinx-theme: https://pydata-sphinx-theme.readthedocs.io/en/stable/ Our current ``pigweed.dev`` theme (``furo``) has served us well over the last few years but we are starting to outgrow it. This SEED proposes adopting `pydata-sphinx-theme`_ (``pydata`` for short) as the new theme for ``pigweed.dev``. The primary purpose of this seed is to document the thought process behind choosing one theme over another. Switching themes is a fairly reversible decision; switching from the current theme to ``pydata`` was 2-4 days of work for example. .. _seed-0130-motivation: ---------- Motivation ---------- .. inclusive-language: disable .. _Sphinx: https://www.sphinx-doc.org/en/master/ .. _theme API: https://www.sphinx-doc.org/en/master/usage/theming.html .. inclusive-language: enable .. _PyPI: https://pypi.org/search/?q=&o=&c=Framework+%3A%3A+Sphinx+%3A%3A+Theme ``pigweed.dev`` is powered by `Sphinx`_. Sphinx does not enforce a single UI. Rather, it provides a `theme API`_ and lets the Sphinx community develop and share customized UIs. There are now hundreds of themes we can choose from on `PyPI`_. Our choice of theme has a big effect on the usability and maintenance workload of ``pigweed.dev``. .. _seed-0130-motivation-usability: Usability ========= The user interface of ``pigweed.dev`` needs to be easy to use and intuitive so that people can find the information they need as quickly and efficiently as possible. The main criteria are UI elements and layout. .. _seed-0130-motivation-ui: User interface elements ----------------------- If the theme does not provide critical UI elements like search modals or breadcrumbs, then we must implement and maintain these UI elements ourselves. .. _seed-0130-motivation-layout: Layout ------ By "layout" we mean the positioning of key UI elements like the search box, the top-level nav, the page nav, breadcrumbs, etc. We should align the layout of ``pigweed.dev`` with the layouts of docs sites that are widely regarded as being easy to use. .. _seed-0130-motivation-maintenance: Maintenance workload ==================== Some themes are a lot more work to maintain than others. Time spent hacking on our theme is time *not* spent writing docs, creating code samples, or improving upstream Pigweed. The two main criteria are internationalization and community. .. _seed-0130-motivation-internationalization: Internationalization -------------------- .. _UI string localization: https://lingoport.com/i18n-term/ui-strings/ Soon we may want to start delivering ``pigweed.dev`` content in different languages. Our theme needs to support basic internationalization features like `UI string localization`_ so that we can begin figuring out an internationalization pipeline that works for us. .. _seed-0130-motivation-community: Community --------- If a theme is used by lots of big projects, then there's a better chance that the theme will keep improving over time. I.e. it's more likely that bugs will get fixed quickly and new features will be continuously added. Likewise, as we inevitably fix bugs and implement new features ourselves, it would be great to be able to let other projects benefit from our work. .. _seed-0130-proposal: -------- Proposal -------- .. _change #226172: https://pwrev.dev/226172 Adopt ``pydata`` as the new ``pigweed.dev`` theme by merging `change #226172`_. .. _seed-0130-problem: --------------------- Problem investigation --------------------- .. _seed-0130-problem-ui: UI elements =========== The most important UI element missing from the current ``pigweed.dev`` theme is a search modal. By "search modal" we mean the ability to see search results immediately after typing something into the search box. ``pigweed.dev`` has this feature now but we had to implement it ourselves: .. figure:: https://storage.googleapis.com/pigweed-media/seeds/theme/current_search_modal.png The current search modal on ``pigweed.dev`` Implementing a search modal from scratch is a lot of work to maintain: * The current search box (i.e. the input that you click to open the search modal) is hidden on narrow viewports. I.e. when you visit ``pigweed.dev`` on a smartphone you can't access the search box unless you open the site nav menu. This will require significant theme customization to fix. * Search modal UIs can have tricky bugs. See :bug:`349475063`. .. note:: Search is a critical part of the ``pigweed.dev`` user experience. Our website analytics data shows that ``/search.html`` is our second-most-visited page, meaning that people use in-site search a lot. .. _a5038af: https://cs.opensource.google/pigweed/pigweed/+/a5038affded6feab2522a7dcc781c21c4f16cc1e A breadcrumbs component is another key UI element missing from the current theme. We implemented our own custom breadcrumbs element in `a5038af`_. Admittedly, this was not much work to create, but we really shouldn't need to implement core navigational elements like this ourselves. .. _seed-0130-problem-layout: Layout ====== .. _MDN: https://developer.mozilla.org/ .. _Stripe: https://docs.stripe.com/ The current ``pigweed.dev`` layout differs noticeably from two documentation sites that are widely renowned for being helpful and easy to use: `MDN`_ and `Stripe`_. .. admonition:: How to choose what websites to index against? There is no annual survey of "best documentation websites" that we can rely on. Maybe we should make that survey! Until then, we have to make an educated guess. When discussions about great documentation sites come up, Stripe and MDN are frequently mentioned. Other docs sites are sometimes mentioned, but not as consistently as Stripe and MDN. Another factor is scope. Stripe has ~20 products. MDN documents the entire web platform. These sites have spent a lot of time figuring out how to keep thousands of docs pages usable and discoverable. As Pigweed's offerings continue to grow in size and variety, ``pigweed.dev`` will face similar challenges. In other words, Stripe and MDN have already thought through the scaling challenges that we'll face in the coming years. One of our critical assumptions (which could be wrong!) is that the layouts of MDN and Stripe *contribute* to their reputations of being helpful and easy-to-use. It's possible that people only consider the *content* of these sites to be high-quality, not necessarily the layouts (and UIs more generally). To unpack the layout problem we need to look at color-coded diagrams of where Stripe, MDN, and Pigweed place key UI elements: .. _typical Stripe doc: https://storage.googleapis.com/pigweed-media/seeds/theme/stripe2.png .. _typical MDN doc: https://storage.googleapis.com/pigweed-media/seeds/theme/mdn2.png .. _typical Pigweed doc: https://storage.googleapis.com/pigweed-media/seeds/theme/pigweed.png .. figure:: https://storage.googleapis.com/pigweed-media/seeds/theme/stripe-layout.png Layout of a `typical Stripe doc`_ .. figure:: https://storage.googleapis.com/pigweed-media/seeds/theme/mdn-layout.png Layout of a `typical MDN doc`_ .. figure:: https://storage.googleapis.com/pigweed-media/seeds/theme/pigweed_layout_2.png Layout of a `typical Pigweed doc`_ Both Stripe and MDN have the same key UI elements. The location of some key UI elements like the search box varies a little, but not much. .. _previous research on searchboxes: https://web.archive.org/web/20240823151546/https://technicalwriting.dev/ux/searchboxes.html Pigweed's layout, on the other hand, differs significantly from the layouts of Stripe and MDN: * The concepts of "top-level nav" and "section nav" don't exist on ``pigweed.dev``. Instead, there's only a global nav that's basically a combination of top-level nav and section nav. This is discussed more in :ref:`seed-0130-problem-globalnav`. * The search box is positioned far to the left, below the logo, whereas Stripe and MDN put the search box in the header. My `previous research on searchboxes`_ suggests that most docs sites put the search box in the header. ``pigweed.dev`` is therefore probably not meeting readers expectations of where to find the search box. * The logo element is much taller. .. _seed-0130-problem-globalnav: Global nav ---------- ``pigweed.dev`` does not have a concept of a top-level nav and section nav like what you see on Stripe and MDN. Instead, it combines the top-level nav and section nav into a global nav. Over time, this global nav gradually builds up and becomes an overwhelmingly long list of links: .. figure:: https://storage.googleapis.com/pigweed-media/seeds/theme/old_global_nav_2.png Global nav circa Q1 2024 That screenshot is from Q1 2024. The current global nav (next screenshot) is a little more tidy, but will probably grow and become messy again. Accessing some links requires navigating through 5 or more layers of nesting: .. figure:: https://storage.googleapis.com/pigweed-media/seeds/theme/global_nav_2.png The ``pw_assert`` docs are an example of 5 levels of nesting in the current global nav .. _seed-0130-problem-internationalization: Internationalization ==================== .. _documentation: https://pradyunsg.me/furo/quickstart/ .. _template: https://github.com/pradyunsg/furo/blob/696ceb13f060dc505053f91ac4d46f0915c261be/src/furo/theme/furo/page.html The `documentation`_ for our current theme does not mention any support for internationalization. The core ``page.html`` `template`_ does not have any logic suggesting that `UI string localization`_ is supported. .. _seed-0130-problem-community: Community ========= .. _Pulse: https://github.com/pradyunsg/furo/pulse/monthly Our current theme's repository is not very active. Summary of 1-month activity from the repo's `Pulse`_ page: Excluding merges, 3 authors have pushed 7 commits to main and 10 commits to all branches. On main, 5 files have changed and there have been 24 additions and 14 deletions. The repo has had 49 contributors in total. .. _1.383M downloads: https://pypistats.org/packages/furo PyPI Stats says that the theme got `1.383M downloads`_ last month. .. _seed-0130-design: --------------- Detailed design --------------- .. _seed-0130-design-ui: User interface elements ======================= ``pydata`` provides a built-in search modal: .. figure:: https://storage.googleapis.com/pigweed-media/seeds/pydata-sphinx-theme/search_modal.png .. _Change #226172: https://pwrev.dev/226172 ``pydata`` does **not** currently provide an inline search experience. I.e. after typing text in the search modal, you do not immediately see search results. You have to press :kbd:`Enter` to view the search results page. `Change #226172`_ introduces custom logic in ``//docs/_static/js/pigweed.js`` and ``//docs/_static/css/pigweed.css`` to enable an inline search experience. We will attempt to contribute this inline search feature to the upstream ``pydata`` repo. The existing custom search features at ``//pw_docgen/py/pw_docgen/sphinx/inlinesearch`` will be deleted as part of `change #226172`_. .. _seed-0130-design-layout: Layout ====== The layout of the ``pydata`` theme is much closer to the MDN and Stripe layouts than the current Pigweed theme: .. _typical Pigweed doc when using pydata: https://storage.googleapis.com/pigweed-media/seeds/theme/pigweed_pydata.png .. figure:: https://storage.googleapis.com/pigweed-media/seeds/theme/pydata-layout.png Layout of a `typical Pigweed doc when using pydata`_ Here are the Stripe and MDN layouts again for comparison: .. figure:: https://storage.googleapis.com/pigweed-media/seeds/theme/stripe-layout.png Layout of a `typical Stripe doc`_ .. figure:: https://storage.googleapis.com/pigweed-media/seeds/theme/mdn-layout.png Layout of a `typical MDN doc`_ .. _seed-0130-design-globalnav: Global nav ---------- By adopting ``pydata`` we will get rid of the global nav and switch to a top-level nav and section nav, very similar to the layouts of MDN and Stripe. First-level links in the current global nav move to the top-level nav in the header: .. figure:: https://storage.googleapis.com/pigweed-media/seeds/theme/nav_changes.png The box on the left is the old global nav. The box on the right is the new top-level nav. The first-level links in the global nav become the links in the new top-level nav. (The ordering and names of the links have changed slightly.) After clicking a top-level link like ``Modules`` the section nav shows all the links related to that section: .. figure:: https://storage.googleapis.com/pigweed-media/seeds/theme/modules.png After clicking the ``Modules`` link in the header, the list of modules appear as first-level links in the section nav In other words, second-level links in the global nav (next screenshot) get promoted to top-level links in the new section nav: .. figure:: https://storage.googleapis.com/pigweed-media/seeds/theme/modules_old.png Second-level links like ``Module Structure``, ``pw_alignment``, etc. become first-level links in the new section nav Therefore, top-down navigation is still possible in the new theme. There's just a little more friction. This new friction will probably be the most noticeable change for long-time ``pigweed.dev`` readers. The main reason to try the top-level nav and section nav approach is that we will probably need to get rid of the global nav soon anyways: .. _Every Page Is Page One: https://everypageispageone.com/the-book/ * :ref:`Problem investigation: Global nav ` demonstrated how our global nav has already become overwhelming and deeply nested. * Global navs are not common on big docs sites. E.g. Stripe, MDN, Firebase, Android, and AWS do not use global navs. `Every Page Is Page One`_ explains why most sites give up on global navs after exceeding a certain size: Sites like Amazon and Wikipedia make little use of top-down navigation... Both sites are far too big to cover effectively, and most of what they contain is not of immediate interest to the person viewing the page. Instead, they link to things related to the current situation of the reader, the current subject of interest, and immediately related subjects. In other words, the navigation that these pages provide is local. .. get some data on global nav usage .. _seed-0130-design-internationalization: Internationalization ==================== .. _Internationalization: https://pydata-sphinx-theme.readthedocs.io/en/stable/user_guide/i18n.html ``pydata`` supports `UI string localization`_ and has documentation detailing the theme's `Internationalization`_ support. This is sufficient for unblocking our work to start figuring out an internationalization strategy. .. _seed-0130-design-community: Community ========= The ``pydata`` repo has been more active than the current theme over the last month. From `Pulse `__: Excluding merges, 8 authors have pushed 8 commits to main and 18 commits to all branches. On main, 20 files have changed and there have been 148 additions and 132 deletions. Here is the current theme's pulse data again for comparison: Excluding merges, 3 authors have pushed 7 commits to main and 10 commits to all branches. On main, 5 files have changed and there have been 24 additions and 14 deletions. ``pydata`` has had 126 contributors in total whereas the current theme has had 49. .. _1.316M downloads: https://pypistats.org/packages/pydata-sphinx-theme PyPI Stats says that ``pydata`` got `1.316M downloads`_ last month, slightly less than the current theme (1.383M downloads) but definitely in the same ballpark. .. _gallery: https://pydata-sphinx-theme.readthedocs.io/en/stable/examples/gallery.html `Gallery`_ shows that ``pydata`` is used by many extremely popular and important projects: * Jupyter * Matplotlib * NumPy * Pandas * SciPy .. _seed-0130-alternatives: ------------ Alternatives ------------ .. _seed-0130-alternatives-create: Create our own Sphinx theme =========================== Creating our own Sphinx theme that aligns with a Google design system like Material Design could be worthwhile one day but would be months of work. We would have to fix all the problems described in :ref:`seed-0130-problem` ourselves and build up our own theme community. We should first find 5-10 other Google projects using Sphinx that will adopt the theme and maybe share the workload with us. .. _seed-0130-alternatives-adopt: Adopt a different Sphinx theme ============================== We did a fairly comprehensive review of other Sphinx themes, but it's worth mentioning again that switching Sphinx themes is not usually that much work. I.e. if we find another theme that's even better suited than ``pydata``, then it should only be a few days of work to switch to the new theme. .. inclusive-language: disable .. _official theme documentation: https://www.sphinx-doc.org/en/master/usage/theming.html .. inclusive-language: enable .. _sphinx-themes: https://sphinx-themes.org/ .. _Framework\:\:Sphinx\:\:Theme: https://pypi.org/search/?q=&o=&c=Framework+%3A%3A+Sphinx+%3A%3A+Theme .. _PyPI Stats: https://pypistats.org/ Notes about the methodology for finding other themes: * The `official theme documentation`_ mentions `sphinx-themes`_ as a place for discovering new themes. * The `Framework::Sphinx::Theme`_ tag on PyPI provides a comprehensive list of themes, but you can only sort by "relevance" and last update. * `PyPI Stats`_ provides statistics on monthly downloads. * When a theme is hosted on GitHub, the Insights page on the theme's repository provides more granular information about how active or inactive the repository is. Summary of other notable themes: .. _python-docs-theme: https://github.com/python/python-docs-theme .. _sphinx-rtd-theme: https://github.com/readthedocs/sphinx_rtd_theme .. _sphinx-book-theme: https://github.com/executablebooks/sphinx-book-theme .. _piccolo-theme: https://github.com/piccolo-orm/piccolo_theme .. _sphinx-material: https://github.com/bashtage/sphinx-material .. _shibuya: https://github.com/lepture/shibuya .. csv-table:: :header: "Name", "Monthly Downloads", "UI elements", "Layout", "i18n" "`python-docs-theme`_", "80K", "❌", "✅", "✅" "`sphinx-rtd-theme`_", "6.6M", "❌", "❌", "✅" "`sphinx-book-theme`_", "560K", "❌", "❌", "❌" "`piccolo-theme`_", "11K", "❌", "❌", "❌" "`sphinx-material`_", "33K", "❌", "❌", "❌" "`shibuya`_", "7K", "❌", "❌", "❌" `shibuya `__ has a pleasant UI. If its community grows and support for breadcrumbs and internationalization is added then we might want to consider switching to that one in the future. .. _seed-0130-alternatives-fork: Fork the current theme ====================== Forking the current theme would give us the freedom to customize the theme to meet our needs, but we would have to fix all the problems described in :ref:`seed-0130-problem` ourselves. We would also have to build up our own theme community. .. _seed-0130-alternatives-ssg: Use a different static site generator ===================================== Sphinx at large is working well for Pigweed. We have simply outgrown our current theme. Migrating to a different static site generator would be weeks or months of work for highly uncertain ROI. Docs site migrations are often extremely disruptive to both authors and readers. .. _seed-0130-alternatives-continue: Continue with the current theme =============================== The maintainers of the current theme might be receptive to the features we need, but we would have to wait weeks or months for them to implement the changes or implement them ourselves. ``pydata`` already provides everything we need now. .. _seed-0130-questions: -------------- Open questions -------------- .. _seed-0130-questions-community: Community ========= It's unknown whether ``pydata`` will accept our inline search feature. If they don't, we'll have to continue maintaining that custom logic. In general, we don't know how receptive the ``pydata`` maintainers will be to our feature requests, bug reports, etc. .. _seed-0130-questions-themes: Themes ====== We did not meticulously study every Sphinx theme in existence. It's possible (but unlikely) that there's an even better theme for us out there somewhere.