xref: /aosp_15_r20/external/pigweed/seed/0130.rst (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1.. _seed-0130:
2
3=========================
40130: Update Sphinx theme
5=========================
6.. seed::
7   :number: 130
8   :name: Update Sphinx theme
9   :status: Accepted
10   :proposal_date: 2024-08-28
11   :cl: 232591
12   :authors: Kayce Basques
13   :facilitator: Anthony DiGirolamo
14
15.. _seed-0130-summary:
16
17-------
18Summary
19-------
20.. _pydata-sphinx-theme: https://pydata-sphinx-theme.readthedocs.io/en/stable/
21
22Our current ``pigweed.dev`` theme (``furo``) has served us well over the
23last few years but we are starting to outgrow it. This SEED proposes adopting
24`pydata-sphinx-theme`_ (``pydata`` for short) as the new theme for
25``pigweed.dev``.
26
27The primary purpose of this seed is to document the thought process behind
28choosing one theme over another. Switching themes is a fairly reversible
29decision; switching from the current theme to ``pydata`` was 2-4 days of
30work for example.
31
32.. _seed-0130-motivation:
33
34----------
35Motivation
36----------
37.. inclusive-language: disable
38.. _Sphinx: https://www.sphinx-doc.org/en/master/
39.. _theme API: https://www.sphinx-doc.org/en/master/usage/theming.html
40.. inclusive-language: enable
41.. _PyPI: https://pypi.org/search/?q=&o=&c=Framework+%3A%3A+Sphinx+%3A%3A+Theme
42
43``pigweed.dev`` is powered by `Sphinx`_. Sphinx does not enforce a single
44UI. Rather, it provides a `theme API`_ and lets the Sphinx community
45develop and share customized UIs. There are now hundreds of themes we can
46choose from on `PyPI`_. Our choice of theme has a big effect on the usability
47and maintenance workload of ``pigweed.dev``.
48
49.. _seed-0130-motivation-usability:
50
51Usability
52=========
53The user interface of ``pigweed.dev`` needs to be easy to use and intuitive
54so that people can find the information they need as quickly and efficiently
55as possible. The main criteria are UI elements and layout.
56
57.. _seed-0130-motivation-ui:
58
59User interface elements
60-----------------------
61If the theme does not provide critical UI elements like search modals or
62breadcrumbs, then we must implement and maintain these UI elements
63ourselves.
64
65.. _seed-0130-motivation-layout:
66
67Layout
68------
69By "layout" we mean the positioning of key UI elements like the search box,
70the top-level nav, the page nav, breadcrumbs, etc. We should align the
71layout of ``pigweed.dev`` with the layouts of docs sites that are widely
72regarded as being easy to use.
73
74.. _seed-0130-motivation-maintenance:
75
76Maintenance workload
77====================
78Some themes are a lot more work to maintain than others. Time
79spent hacking on our theme is time *not* spent writing docs, creating code
80samples, or improving upstream Pigweed. The two main criteria are
81internationalization and community.
82
83.. _seed-0130-motivation-internationalization:
84
85Internationalization
86--------------------
87.. _UI string localization: https://lingoport.com/i18n-term/ui-strings/
88
89Soon we may want to start delivering ``pigweed.dev`` content in different
90languages. Our theme needs to support basic internationalization features
91like `UI string localization`_ so that we can begin figuring out an
92internationalization pipeline that works for us.
93
94.. _seed-0130-motivation-community:
95
96Community
97---------
98If a theme is used by lots of big projects, then there's a better chance
99that the theme will keep improving over time. I.e. it's more likely that
100bugs will get fixed quickly and new features will be continuously added.
101Likewise, as we inevitably fix bugs and implement new features ourselves,
102it would be great to be able to let other projects benefit from our work.
103
104.. _seed-0130-proposal:
105
106--------
107Proposal
108--------
109.. _change #226172: https://pwrev.dev/226172
110
111Adopt ``pydata`` as the new ``pigweed.dev`` theme by merging
112`change #226172`_.
113
114.. _seed-0130-problem:
115
116---------------------
117Problem investigation
118---------------------
119
120.. _seed-0130-problem-ui:
121
122UI elements
123===========
124The most important UI element missing from the current ``pigweed.dev`` theme
125is a search modal. By "search modal" we mean the ability to see search results
126immediately after typing something into the search box. ``pigweed.dev`` has
127this feature now but we had to implement it ourselves:
128
129.. figure:: https://storage.googleapis.com/pigweed-media/seeds/theme/current_search_modal.png
130
131   The current search modal on ``pigweed.dev``
132
133Implementing a search modal from scratch is a lot of work to maintain:
134
135* The current search box (i.e. the input that you click to open the search
136  modal) is hidden on narrow viewports. I.e. when you visit
137  ``pigweed.dev`` on a smartphone you can't access the search box unless you
138  open the site nav menu. This will require significant theme customization
139  to fix.
140* Search modal UIs can have tricky bugs. See :bug:`349475063`.
141
142.. note::
143
144   Search is a critical part of the ``pigweed.dev`` user experience. Our website
145   analytics data shows that ``/search.html`` is our second-most-visited page,
146   meaning that people use in-site search a lot.
147
148.. _a5038af: https://cs.opensource.google/pigweed/pigweed/+/a5038affded6feab2522a7dcc781c21c4f16cc1e
149
150A breadcrumbs component is another key UI element missing from the current
151theme. We implemented our own custom breadcrumbs element in `a5038af`_.
152Admittedly, this was not much work to create, but we really shouldn't need
153to implement core navigational elements like this ourselves.
154
155.. _seed-0130-problem-layout:
156
157Layout
158======
159.. _MDN: https://developer.mozilla.org/
160.. _Stripe: https://docs.stripe.com/
161
162The current ``pigweed.dev`` layout differs noticeably from two documentation
163sites that are widely renowned for being helpful and easy to use: `MDN`_ and
164`Stripe`_.
165
166.. admonition:: How to choose what websites to index against?
167
168   There is no annual survey of "best documentation websites" that we can rely
169   on. Maybe we should make that survey! Until then, we have to make an educated
170   guess. When discussions about great documentation sites come up, Stripe and
171   MDN are frequently mentioned. Other docs sites are sometimes mentioned, but not
172   as consistently as Stripe and MDN.
173
174   Another factor is scope. Stripe has ~20 products. MDN documents the entire
175   web platform. These sites have spent a lot of time figuring out how to
176   keep thousands of docs pages usable and discoverable. As Pigweed's
177   offerings continue to grow in size and variety, ``pigweed.dev`` will
178   face similar challenges. In other words, Stripe and MDN have already thought
179   through the scaling challenges that we'll face in the coming years.
180
181   One of our critical assumptions (which could be wrong!) is that the layouts
182   of MDN and Stripe *contribute* to their reputations of being helpful and
183   easy-to-use. It's possible that people only consider the *content* of these
184   sites to be high-quality, not necessarily the layouts (and UIs more
185   generally).
186
187To unpack the layout problem we need to look at color-coded diagrams of where
188Stripe, MDN, and Pigweed place key UI elements:
189
190.. _typical Stripe doc: https://storage.googleapis.com/pigweed-media/seeds/theme/stripe2.png
191
192.. _typical MDN doc: https://storage.googleapis.com/pigweed-media/seeds/theme/mdn2.png
193
194.. _typical Pigweed doc: https://storage.googleapis.com/pigweed-media/seeds/theme/pigweed.png
195
196.. figure:: https://storage.googleapis.com/pigweed-media/seeds/theme/stripe-layout.png
197
198   Layout of a `typical Stripe doc`_
199
200.. figure:: https://storage.googleapis.com/pigweed-media/seeds/theme/mdn-layout.png
201
202   Layout of a `typical MDN doc`_
203
204.. figure:: https://storage.googleapis.com/pigweed-media/seeds/theme/pigweed_layout_2.png
205
206   Layout of a `typical Pigweed doc`_
207
208Both Stripe and MDN have the same key UI elements. The location of some
209key UI elements like the search box varies a little, but not much.
210
211.. _previous research on searchboxes: https://web.archive.org/web/20240823151546/https://technicalwriting.dev/ux/searchboxes.html
212
213Pigweed's layout, on the other hand, differs significantly from the layouts
214of Stripe and MDN:
215
216* The concepts of "top-level nav" and "section nav" don't exist on
217  ``pigweed.dev``. Instead, there's only a global nav that's basically a
218  combination of top-level nav and section nav. This is discussed more in
219  :ref:`seed-0130-problem-globalnav`.
220* The search box is positioned far to the left, below the logo, whereas
221  Stripe and MDN put the search box in the header. My `previous research on
222  searchboxes`_ suggests that most docs sites put the search box in the header.
223  ``pigweed.dev`` is therefore probably not meeting readers expectations of
224  where to find the search box.
225* The logo element is much taller.
226
227.. _seed-0130-problem-globalnav:
228
229Global nav
230----------
231``pigweed.dev`` does not have a concept of a top-level nav and section nav
232like what you see on Stripe and MDN. Instead, it combines the top-level nav
233and section nav into a global nav.
234
235Over time, this global nav gradually builds up and becomes an overwhelmingly
236long list of links:
237
238.. figure:: https://storage.googleapis.com/pigweed-media/seeds/theme/old_global_nav_2.png
239
240   Global nav circa Q1 2024
241
242That screenshot is from Q1 2024. The current global nav (next screenshot) is a
243little more tidy, but will probably grow and become messy again.
244
245Accessing some links requires navigating through 5 or more layers of nesting:
246
247.. figure:: https://storage.googleapis.com/pigweed-media/seeds/theme/global_nav_2.png
248
249   The ``pw_assert`` docs are an example of 5 levels of nesting in the
250   current global nav
251
252.. _seed-0130-problem-internationalization:
253
254Internationalization
255====================
256.. _documentation: https://pradyunsg.me/furo/quickstart/
257.. _template: https://github.com/pradyunsg/furo/blob/696ceb13f060dc505053f91ac4d46f0915c261be/src/furo/theme/furo/page.html
258
259The `documentation`_ for our current theme does not mention any support
260for internationalization. The core ``page.html`` `template`_ does not have
261any logic suggesting that `UI string localization`_ is supported.
262
263.. _seed-0130-problem-community:
264
265Community
266=========
267.. _Pulse: https://github.com/pradyunsg/furo/pulse/monthly
268
269Our current theme's repository is not very active. Summary of
2701-month activity from the repo's `Pulse`_ page:
271
272  Excluding merges, 3 authors have pushed 7 commits to main and 10 commits
273  to all branches. On main, 5 files have changed and there have been 24
274  additions and 14 deletions.
275
276The repo has had 49 contributors in total.
277
278.. _1.383M downloads: https://pypistats.org/packages/furo
279
280PyPI Stats says that the theme got `1.383M downloads`_ last month.
281
282.. _seed-0130-design:
283
284---------------
285Detailed design
286---------------
287
288.. _seed-0130-design-ui:
289
290User interface elements
291=======================
292``pydata`` provides a built-in search modal:
293
294.. figure:: https://storage.googleapis.com/pigweed-media/seeds/pydata-sphinx-theme/search_modal.png
295
296.. _Change #226172: https://pwrev.dev/226172
297
298``pydata`` does **not** currently provide an inline search experience.
299I.e. after typing text in the search modal, you do not immediately see
300search results. You have to press :kbd:`Enter` to view the search
301results page. `Change #226172`_ introduces custom logic
302in ``//docs/_static/js/pigweed.js`` and ``//docs/_static/css/pigweed.css``
303to enable an inline search experience. We will attempt to contribute this
304inline search feature to the upstream ``pydata`` repo. The existing custom
305search features at ``//pw_docgen/py/pw_docgen/sphinx/inlinesearch`` will be
306deleted as part of `change #226172`_.
307
308.. _seed-0130-design-layout:
309
310Layout
311======
312The layout of the ``pydata`` theme is much closer to the MDN and Stripe
313layouts than the current Pigweed theme:
314
315.. _typical Pigweed doc when using pydata: https://storage.googleapis.com/pigweed-media/seeds/theme/pigweed_pydata.png
316
317.. figure:: https://storage.googleapis.com/pigweed-media/seeds/theme/pydata-layout.png
318
319   Layout of a `typical Pigweed doc when using pydata`_
320
321Here are the Stripe and MDN layouts again for comparison:
322
323.. figure:: https://storage.googleapis.com/pigweed-media/seeds/theme/stripe-layout.png
324
325   Layout of a `typical Stripe doc`_
326
327.. figure:: https://storage.googleapis.com/pigweed-media/seeds/theme/mdn-layout.png
328
329   Layout of a `typical MDN doc`_
330
331.. _seed-0130-design-globalnav:
332
333Global nav
334----------
335By adopting ``pydata`` we will get rid of the global nav and switch to a
336top-level nav and section nav, very similar to the layouts of MDN and Stripe.
337First-level links in the current global nav move to the top-level nav in
338the header:
339
340.. figure:: https://storage.googleapis.com/pigweed-media/seeds/theme/nav_changes.png
341
342   The box on the left is the old global nav. The box on the right is the new
343   top-level nav. The first-level links in the global nav become the links in
344   the new top-level nav. (The ordering and names of the links have changed
345   slightly.)
346
347After clicking a top-level link like ``Modules`` the section nav shows
348all the links related to that section:
349
350.. figure:: https://storage.googleapis.com/pigweed-media/seeds/theme/modules.png
351
352   After clicking the ``Modules`` link in the header, the list of modules
353   appear as first-level links in the section nav
354
355In other words, second-level links in the global nav (next screenshot) get
356promoted to top-level links in the new section nav:
357
358.. figure:: https://storage.googleapis.com/pigweed-media/seeds/theme/modules_old.png
359
360   Second-level links like ``Module Structure``, ``pw_alignment``, etc. become
361   first-level links in the new section nav
362
363Therefore, top-down navigation is still possible in the new theme.
364There's just a little more friction. This new friction will probably be the
365most noticeable change for long-time ``pigweed.dev`` readers.
366
367The main reason to try the top-level nav and section nav approach is that
368we will probably need to get rid of the global nav soon anyways:
369
370.. _Every Page Is Page One: https://everypageispageone.com/the-book/
371
372* :ref:`Problem investigation: Global nav <seed-0130-problem-globalnav>`
373  demonstrated how our global nav has already become overwhelming and
374  deeply nested.
375* Global navs are not common on big docs sites. E.g. Stripe, MDN, Firebase,
376  Android, and AWS do not use global navs. `Every Page Is Page One`_
377  explains why most sites give up on global navs after exceeding a certain
378  size:
379
380    Sites like Amazon and Wikipedia make little use of top-down navigation... Both
381    sites are far too big to cover effectively, and most of what they contain is not
382    of immediate interest to the person viewing the page. Instead, they link to
383    things related to the current situation of the reader, the current subject of
384    interest, and immediately related subjects. In other words, the navigation that
385    these pages provide is local.
386
387.. get some data on global nav usage
388
389.. _seed-0130-design-internationalization:
390
391Internationalization
392====================
393.. _Internationalization: https://pydata-sphinx-theme.readthedocs.io/en/stable/user_guide/i18n.html
394
395``pydata`` supports `UI string localization`_ and has documentation detailing
396the theme's `Internationalization`_ support. This is sufficient for unblocking
397our work to start figuring out an internationalization strategy.
398
399.. _seed-0130-design-community:
400
401Community
402=========
403The ``pydata`` repo has been more active than the current theme over the last
404month. From `Pulse <https://github.com/pydata/pydata-sphinx-theme/pulse>`__:
405
406  Excluding merges, 8 authors have pushed 8 commits to main and 18 commits to
407  all branches. On main, 20 files have changed and there have been 148
408  additions and 132 deletions.
409
410Here is the current theme's pulse data again for comparison:
411
412  Excluding merges, 3 authors have pushed 7 commits to main and 10 commits
413  to all branches. On main, 5 files have changed and there have been 24
414  additions and 14 deletions.
415
416``pydata`` has had 126 contributors in total whereas the current theme has
417had 49.
418
419.. _1.316M downloads: https://pypistats.org/packages/pydata-sphinx-theme
420
421PyPI Stats says that ``pydata`` got `1.316M downloads`_ last month, slightly
422less than the current theme (1.383M downloads) but definitely in the same
423ballpark.
424
425.. _gallery: https://pydata-sphinx-theme.readthedocs.io/en/stable/examples/gallery.html
426
427`Gallery`_ shows that ``pydata`` is used by many extremely popular and
428important projects:
429
430* Jupyter
431* Matplotlib
432* NumPy
433* Pandas
434* SciPy
435
436.. _seed-0130-alternatives:
437
438------------
439Alternatives
440------------
441
442.. _seed-0130-alternatives-create:
443
444Create our own Sphinx theme
445===========================
446Creating our own Sphinx theme that aligns with a Google design
447system like Material Design could be worthwhile one day but would be
448months of work. We would have to fix all the problems described in
449:ref:`seed-0130-problem` ourselves and build up our own theme community.
450We should first find 5-10 other Google projects using Sphinx that will
451adopt the theme and maybe share the workload with us.
452
453.. _seed-0130-alternatives-adopt:
454
455Adopt a different Sphinx theme
456==============================
457We did a fairly comprehensive review of other Sphinx themes, but
458it's worth mentioning again that switching Sphinx themes is not
459usually that much work. I.e. if we find another theme that's even
460better suited than ``pydata``, then it should only be a few days
461of work to switch to the new theme.
462
463.. inclusive-language: disable
464.. _official theme documentation: https://www.sphinx-doc.org/en/master/usage/theming.html
465.. inclusive-language: enable
466.. _sphinx-themes: https://sphinx-themes.org/
467.. _Framework\:\:Sphinx\:\:Theme: https://pypi.org/search/?q=&o=&c=Framework+%3A%3A+Sphinx+%3A%3A+Theme
468.. _PyPI Stats: https://pypistats.org/
469
470Notes about the methodology for finding other themes:
471
472* The `official theme documentation`_ mentions `sphinx-themes`_ as a place for
473  discovering new themes.
474* The `Framework::Sphinx::Theme`_ tag on PyPI provides a comprehensive
475  list of themes, but you can only sort by "relevance" and last update.
476* `PyPI Stats`_ provides statistics on monthly downloads.
477* When a theme is hosted on GitHub, the Insights page on the theme's
478  repository provides more granular information about how active or
479  inactive the repository is.
480
481Summary of other notable themes:
482
483.. _python-docs-theme: https://github.com/python/python-docs-theme
484.. _sphinx-rtd-theme: https://github.com/readthedocs/sphinx_rtd_theme
485.. _sphinx-book-theme: https://github.com/executablebooks/sphinx-book-theme
486.. _piccolo-theme: https://github.com/piccolo-orm/piccolo_theme
487.. _sphinx-material: https://github.com/bashtage/sphinx-material
488.. _shibuya: https://github.com/lepture/shibuya
489
490.. csv-table::
491   :header: "Name", "Monthly Downloads", "UI elements", "Layout", "i18n"
492
493   "`python-docs-theme`_", "80K", "❌", "✅", "✅"
494   "`sphinx-rtd-theme`_", "6.6M", "❌", "❌", "✅"
495   "`sphinx-book-theme`_", "560K", "❌", "❌", "❌"
496   "`piccolo-theme`_", "11K", "❌", "❌", "❌"
497   "`sphinx-material`_", "33K", "❌", "❌", "❌"
498   "`shibuya`_", "7K", "❌", "❌", "❌"
499
500`shibuya <https://shibuya.lepture.com/>`__ has a pleasant UI. If
501its community grows and support for breadcrumbs and internationalization
502is added then we might want to consider switching to that one
503in the future.
504
505.. _seed-0130-alternatives-fork:
506
507Fork the current theme
508======================
509Forking the current theme would give us the freedom to customize
510the theme to meet our needs, but we would have to fix all the problems
511described in :ref:`seed-0130-problem` ourselves. We would also have to
512build up our own theme community.
513
514.. _seed-0130-alternatives-ssg:
515
516Use a different static site generator
517=====================================
518Sphinx at large is working well for Pigweed. We have simply outgrown our
519current theme. Migrating to a different static site generator would be
520weeks or months of work for highly uncertain ROI. Docs site migrations
521are often extremely disruptive to both authors and readers.
522
523.. _seed-0130-alternatives-continue:
524
525Continue with the current theme
526===============================
527The maintainers of the current theme might be receptive to the
528features we need, but we would have to wait weeks or months for
529them to implement the changes or implement them ourselves. ``pydata``
530already provides everything we need now.
531
532.. _seed-0130-questions:
533
534--------------
535Open questions
536--------------
537
538.. _seed-0130-questions-community:
539
540Community
541=========
542It's unknown whether ``pydata`` will accept our inline search feature.
543If they don't, we'll have to continue maintaining that custom logic.
544In general, we don't know how receptive the ``pydata`` maintainers will
545be to our feature requests, bug reports, etc.
546
547.. _seed-0130-questions-themes:
548
549Themes
550======
551We did not meticulously study every Sphinx theme in existence. It's
552possible (but unlikely) that there's an even better theme for us
553out there somewhere.
554