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