Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generate a single sidebar HTML file and insert it into each page in an iframe #762

Open
gilbertbw opened this issue Jun 27, 2022 · 4 comments

Comments

@gilbertbw
Copy link

As requested by @choldgraf here #364 (comment) I have pulled this comment #364 (comment) out into its own issue and clarified the proposal.


We are looking to use sphinx-book-theme to document our product, moving from a .chm file produced using Help and Manual. sphinx-book-theme is based off of pydata-sphinx-theme.

We have two issues with inserting the sidebar into every page:

  1. It takes a long time, increasing the build time of our help from 2 minutes with alabaster, to 10 minutes with sphinx-book-theme
  2. It increases the build size massively. In our project each page ends up around 0.25 MB. This is with around 1500 help topics. The whole help ends up around 380 MB, compared to around 3 MB for the .chm file this is replacing.

I have been discussing this on the sphinx-book-theme repo here executablebooks/sphinx-book-theme#561

Current Workaround

These issues seem to be reported by many users, currently the recommendation, here, is to reduce the number of pages in the sidebar. This is not a good solution for us, as want the UX of being able to browse through the tree before moving page.

Proposal

Looking into this, I have come up with the following proposal (first discussed here executablebooks/sphinx-book-theme#561 (comment)):

Support outputting the sidebar once, into its own file, then including the sidebar with an <iframe/> in each page.

To still show the relevant subsection of the tree on each page, without javascript:

  1. update generate_nav_tree
    def generate_nav_html(kind, startdepth=None, show_nav_level=1, **kwargs):
    to optionally write unique classes for each page <li> in the tree.
  2. add a new toctree function to write out the <style>...</style> to show the current page.
  3. Maybe add helpers to add the <iframe>? Not sure if the implementer of the theme should be responsible for this?
  4. Maybe add documentation about using this alternative method for the sidebar? I am not sure you would want to make this the default?

I want to discuss how these changed would be received, before I open a PR.

Example

With a tree like this, where the class is on the <li>

  • Top 1 class="t1"
    • Top 1 Child 1 class="t1c1"
    • Top 1 Child 2 class="t1c2"
  • Top 2 class="t2"
    • Top 2 Child 1 class="t2c1"
    • Top 2 Child 2 class="t2c2"
    • Top 2 Child 3 class="t2c3"
      • Top 2 Child 3 Child 1 class="t2c3c1"
      • Top 2 Child 3 Child 2 class="t2c3c2"
      • Top 2 Child 3 Child 3 class="t2c3c3"
  • Top 3 class="t3"
    • Top 3 Child 1 class="t3c1"

on the page Top 1 add

<style>
#site-navigation .t1>a { color: rgba(var(--pst-color-link),1); }
#site-navigation .t1>ul { display:block; }
</style>

or on Top 2 Child 3 Child 2 add

<style>
#site-navigation .t2>a { color: rgba(var(--pst-color-link),1); }
#site-navigation .t2>ul { display:block; }

#site-navigation .t2c3>a { color: rgba(var(--pst-color-link),1); }
#site-navigation .t2c3>ul { display:block; }

#site-navigation .t2c3c3>a { color: rgba(var(--pst-color-link),1); }
</style>

e.t.c.

@choldgraf
Copy link
Collaborator

I think a challenge that you're going to run into here is that the relative links will change for each page (Sphinx makes all of its cross-reference links relative to the current document). For example, here's an example of a link in the header:

<a class="reference internal nav-link" href="../demo/index.html">
  Demo site
 </a>

So to define a single HTML structure you'd need to either hard-code absolute paths in the links (which I don't think is possible in Sphinx), or you'd need to ensure that your documentation is all in a single folder so that relative paths are the same everywhere.

@choldgraf choldgraf changed the title Abstract out sidebar Generate a single sidebar HTML file and insert it into each page in an iframe Jun 27, 2022
@gilbertbw
Copy link
Author

Good point! We would be happy to flatten the output into one folder. I'm not familiar enough with sphinx to know whether that can/should be done by the theme, or if we will need a pre-processing step e.g. in an extension.

Alternatively, for our use case, we could possibly set an absolute path as the <base> in the sidebar html, substituted in as a full path as part of our software installation.

Playing around a bit, it looks like a block like <base href="./" target="_top"/> in the sidebar.html seems to make the links relative to it, rather than relative to the page that includes it with an <iframe>.

@choldgraf
Copy link
Collaborator

My feeling is that re-working this theme to embed an <html> block via an iframe would be too much customization for this theme specifically, as this is a pretty particular use-case. What I'd recommend doing is writing your own sidebar-primary.html template via creating your own section template here:

https://github.com/pydata/pydata-sphinx-theme/blob/main/src/pydata_sphinx_theme/theme/pydata_sphinx_theme/sections/sidebar-primary.html

That could then replace the pydata sphinx theme sidebar in its entirety and you could add whatever HTML mechanism you'd like. Then in your build conf.py file, you could add the code to generate the HTML you'd like to insert into the sidebar.

That way you could have full flexibility over the sidebar.

@12rambau
Copy link
Collaborator

@gilbertbw did you had the time to check this solution ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants