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

Switch documentation theme to Furo #1746

Closed
simonw opened this issue May 20, 2022 · 21 comments
Closed

Switch documentation theme to Furo #1746

simonw opened this issue May 20, 2022 · 21 comments

Comments

@simonw
Copy link
Owner

simonw commented May 20, 2022

https://github.com/pradyunsg/furo

I just did this for shot-scraper and I really like it: https://shot-scraper.datasette.io/en/latest/

@simonw
Copy link
Owner Author

simonw commented May 20, 2022

A couple of changes I want to make. First, I don't really like the way Furo keeps the in-page titles in a separate menu on the right rather than expanding them on the left.

I like this:

CleanShot 2022-05-20 at 11 43 33@2x

Furo wants to do this instead:

image

I also still want to include those inline tables of contents on the two pages that have them:

@simonw
Copy link
Owner Author

simonw commented May 20, 2022

I found a workaround for the no-longer-nested left hand navigation: drop this into _templates/sidebar/navigation.html:

<div class="sidebar-tree">
  {{ toctree(
    collapse=True,
    titles_only=False,
    maxdepth=3,
    includehidden=True,
) }}
</div>

@simonw
Copy link
Owner Author

simonw commented May 20, 2022

And for those local table of contents, do this:

.. contents::
   :local:
   :class: this-will-duplicate-information-and-it-is-still-useful-here

@simonw
Copy link
Owner Author

simonw commented May 20, 2022

One other problem: in dark mode the Datasette logo looks bad:

image

This helps a bit:

.sidebar-logo-container {
  background-color: white;
  padding: 5px;
  opacity: 0.6;
}

image

@simonw
Copy link
Owner Author

simonw commented May 20, 2022

Need to address other customizations I've made in https://github.com/simonw/datasette/blob/0.62a0/docs/_templates/layout.html - such as Plausible analytics and some custom JavaScript.

{%- extends "!layout.html" %}
{% block htmltitle %}
{{ super() }}
<script defer data-domain="docs.datasette.io" src="https://plausible.io/js/plausible.js"></script>
{% endblock %}
{% block sidebartitle %}
<a href="https://datasette.io/">
<img src="{{ pathto('_static/' + logo, 1) }}" class="logo" alt="{{ _('Logo') }}"/>
</a>
{% if theme_display_version %}
{%- set nav_version = version %}
{% if READTHEDOCS and current_version %}
{%- set nav_version = current_version %}
{% endif %}
{% if nav_version %}
<div class="version">
{{ nav_version }}
</div>
{% endif %}
{% endif %}
{% include "searchbox.html" %}
{% endblock %}
{% block footer %}
{{ super() }}
<script>
jQuery(function ($) {
// Show banner linking to /stable/ if this is a /latest/ page
if (!/\/latest\//.test(location.pathname)) {
return;
}
var stableUrl = location.pathname.replace("/latest/", "/stable/");
// Check it's not a 404
fetch(stableUrl, { method: "HEAD" }).then((response) => {
if (response.status == 200) {
var warning = $(
`<div class="admonition warning">
<p class="first admonition-title">Note</p>
<p class="last">
This documentation covers the <strong>development version</strong> of Datasette.</p>
<p>See <a href="${stableUrl}">this page</a> for the current stable release.
</p>
</div>`
);
warning.find("a").attr("href", stableUrl);
var body = $("div.body");
if (!body.length) {
body = $("div.document");
}
body.prepend(warning);
}
});
});
</script>
{% endblock %}

@simonw
Copy link
Owner Author

simonw commented May 20, 2022

I have some custom CSS in this file:

a.external {
overflow-wrap: anywhere;
}
div .wy-side-nav-search > div.version {
color: rgba(0,0,0,0.75);
}

I tested and the overflow-wrap: anywhere is still needed for this fix:

The .wy-side-nav-search bit is no longer needed with the new theme.

@simonw
Copy link
Owner Author

simonw commented May 20, 2022

Putting this in the css/custom.css file seems to work for fixing that logo problem:

body[data-theme="dark"] .sidebar-logo-container {
    background-color: white;
    padding: 5px;
    opacity: 0.6;
}

@simonw
Copy link
Owner Author

simonw commented May 20, 2022

I want the Datasette logo in the sidebar to link to https://datasette.io/

Looks like I can do that by dropping in my own sidebar/brand.html template based on this:

https://github.com/pradyunsg/furo/blob/0c2acbbd23f8146dd0ae50a2ba57258c1f63ea9f/src/furo/theme/furo/sidebar/brand.html

@simonw
Copy link
Owner Author

simonw commented May 20, 2022

I'd also like to bring back this stable / latest / version indicator:

CleanShot 2022-05-20 at 12 30 49@2x

@simonw
Copy link
Owner Author

simonw commented May 20, 2022

Actually maybe I don't? I just noticed that on other pages on https://docs.datasette.io/en/stable/installation.html the only way to get back to that useful table of context / index page at https://docs.datasette.io/en/stable/index.html is by clicking the tiny house icon. Can I do better or should I have the logo do that?

@simonw
Copy link
Owner Author

simonw commented May 20, 2022

Here's a TIL from when I first customized the layout.html template: https://til.simonwillison.net/readthedocs/custom-sphinx-templates

Note that Furo doesn't use layout.html so I need to completely change how I did that.

@simonw
Copy link
Owner Author

simonw commented May 20, 2022

I can't get that thing that displays the version working.

https://github.com/readthedocs/sphinx_rtd_theme/blob/9264091087620d421b0804c00937b00980ac3916/sphinx_rtd_theme/layout.html#L154 is wheresphinx_rtd_theme implements it - {%- if theme_display_version %} - but I can't find where that variable is first set, from searching both that theme and Sphinx itself!

@simonw
Copy link
Owner Author

simonw commented May 20, 2022

Weird, I cannot figure out this theme_display_version thing - I even tried this:

cd /tmp
mkdir s
cd s
python3 -m venv venv
source venv/bin/activate
pip install sphinx_rtd_theme
cd venv
rg theme_display_version

And got just that one reference:

lib/python3.10/site-packages/sphinx_rtd_theme/layout.html
154:          {%- if theme_display_version %}

@simonw
Copy link
Owner Author

simonw commented May 20, 2022

Oh but rg display_version is a lot more interesting:

lib/python3.10/site-packages/sphinx/builders/html/__init__.py:from sphinx import __display_version__, package_dir
lib/python3.10/site-packages/sphinx/builders/html/__init__.py:            'sphinx_version': __display_version__,
lib/python3.10/site-packages/sphinx/application.py:        logger.info(bold(__('Running Sphinx v%s') % sphinx.__display_version__))
lib/python3.10/site-packages/sphinx/application.py:        if self.config.needs_sphinx and self.config.needs_sphinx > sphinx.__display_version__:
lib/python3.10/site-packages/sphinx/application.py:        if version > sphinx.__display_version__[:3]:
lib/python3.10/site-packages/sphinx/cmd/build.py:from sphinx import __display_version__, package_dir
lib/python3.10/site-packages/sphinx/cmd/build.py:                        version='%%(prog)s %s' % __display_version__)
lib/python3.10/site-packages/sphinx/cmd/make_mode.py:        print(bold("Sphinx v%s" % sphinx.__display_version__))
lib/python3.10/site-packages/sphinx/__init__.py:__display_version__ = __version__  # used for command line version
lib/python3.10/site-packages/sphinx/__init__.py:    __display_version__ = __version__
lib/python3.10/site-packages/sphinx/__init__.py:            __display_version__ += '/' + ret.stdout.strip()
lib/python3.10/site-packages/sphinx/ext/githubpages.py:    return {'version': sphinx.__display_version__, 'parallel_read_safe': True}
lib/python3.10/site-packages/sphinx/ext/intersphinx.py:        'version': sphinx.__display_version__,
lib/python3.10/site-packages/sphinx/cmd/quickstart.py:from sphinx import __display_version__, package_dir
lib/python3.10/site-packages/sphinx/cmd/quickstart.py:    print(bold(__('Welcome to the Sphinx %s quickstart utility.')) % __display_version__)
lib/python3.10/site-packages/sphinx/cmd/quickstart.py:                        version='%%(prog)s %s' % __display_version__)
lib/python3.10/site-packages/sphinx/ext/viewcode.py:        'version': sphinx.__display_version__,
lib/python3.10/site-packages/sphinx/util/__init__.py:                  (sphinx.__display_version__,
lib/python3.10/site-packages/sphinx/ext/ifconfig.py:    return {'version': sphinx.__display_version__, 'parallel_read_safe': True}
lib/python3.10/site-packages/sphinx/ext/todo.py:        'version': sphinx.__display_version__,
lib/python3.10/site-packages/sphinx/ext/doctest.py:    return {'version': sphinx.__display_version__, 'parallel_read_safe': True}
lib/python3.10/site-packages/sphinx/ext/autosummary/__init__.py:    return {'version': sphinx.__display_version__, 'parallel_read_safe': True}
lib/python3.10/site-packages/sphinx/ext/napoleon/__init__.py:from sphinx import __display_version__ as __version__
lib/python3.10/site-packages/sphinx/ext/autosummary/generate.py:from sphinx import __display_version__, package_dir
lib/python3.10/site-packages/sphinx/ext/autosummary/generate.py:                        version='%%(prog)s %s' % __display_version__)
lib/python3.10/site-packages/sphinx/ext/inheritance_diagram.py:    return {'version': sphinx.__display_version__, 'parallel_read_safe': True}
lib/python3.10/site-packages/sphinx/ext/imgmath.py:    return {'version': sphinx.__display_version__, 'parallel_read_safe': True}
lib/python3.10/site-packages/sphinx/ext/linkcode.py:    return {'version': sphinx.__display_version__, 'parallel_read_safe': True}
lib/python3.10/site-packages/sphinx/ext/coverage.py:    return {'version': sphinx.__display_version__, 'parallel_read_safe': True}
lib/python3.10/site-packages/sphinx/writers/texinfo.py:from sphinx import __display_version__, addnodes
lib/python3.10/site-packages/sphinx/writers/texinfo.py:@*Generated by Sphinx """ + __display_version__ + """.@*
lib/python3.10/site-packages/sphinx/ext/graphviz.py:    return {'version': sphinx.__display_version__, 'parallel_read_safe': True}
lib/python3.10/site-packages/sphinx/ext/mathjax.py:    return {'version': sphinx.__display_version__, 'parallel_read_safe': True}
lib/python3.10/site-packages/sphinx/ext/extlinks.py:    return {'version': sphinx.__display_version__, 'parallel_read_safe': True}
lib/python3.10/site-packages/sphinx/ext/apidoc.py:from sphinx import __display_version__, package_dir
lib/python3.10/site-packages/sphinx/ext/apidoc.py:                        version='%%(prog)s %s' % __display_version__)
lib/python3.10/site-packages/sphinx/ext/autodoc/type_comment.py:    return {'version': sphinx.__display_version__, 'parallel_read_safe': True}
lib/python3.10/site-packages/sphinx/ext/autodoc/__init__.py:    return {'version': sphinx.__display_version__, 'parallel_read_safe': True}
lib/python3.10/site-packages/pip/_internal/models/target_python.py:        display_version = None
lib/python3.10/site-packages/pip/_internal/models/target_python.py:            display_version = '.'.join(
lib/python3.10/site-packages/pip/_internal/models/target_python.py:            ('version_info', display_version),
lib/python3.10/site-packages/sphinx_rtd_theme/theme.conf:display_version = True
lib/python3.10/site-packages/sphinx_rtd_theme/layout.html:          {%- if theme_display_version %}

@simonw
Copy link
Owner Author

simonw commented May 20, 2022

This seems to work for brand.html:

<div class="sidebar-brand centered">
  {% block brand_content %}
  <div class="sidebar-logo-container">
    <a href="https://datasette.io/"><img class="sidebar-logo" src="{{ logo_url }}" alt="Datasette"></a>
  </div>
  {%- set nav_version = version %}
  {% if READTHEDOCS and current_version %}
    {%- set nav_version = current_version %}
  {% endif %}
  {% if nav_version %}
    <div class="version">
      {{ nav_version }}
    </div>
  {% endif %}
  {% endblock brand_content %}
</div>

@simonw
Copy link
Owner Author

simonw commented May 20, 2022

I'm going to move my custom JavaScript from layout.html into js/custom.js, similar to how the custom CSS works.

@simonw
Copy link
Owner Author

simonw commented May 20, 2022

One last question: how to include the Plausible analytics?

Furo doesn't have any specific tools for this:

@simonw
Copy link
Owner Author

simonw commented May 20, 2022

I think the trick will be to extend the base.html template from Furo using the same trick I used in https://til.simonwillison.net/readthedocs/custom-sphinx-templates

https://github.com/pradyunsg/furo/blob/2022.04.07/src/furo/theme/furo/base.html - the site_meta block looks good.

simonw added a commit that referenced this issue May 20, 2022
@simonw
Copy link
Owner Author

simonw commented May 20, 2022

Now live at https://docs.datasette.io/en/latest/ - the JavaScript that adds the banner about that not being the stable version doesn't seem to work though.

Before:

image

After:

image

@simonw
Copy link
Owner Author

simonw commented May 20, 2022

Relevant JavaScript:

var body = $("div.body");
if (!body.length) {
body = $("div.document");
}
body.prepend(warning);

@simonw
Copy link
Owner Author

simonw commented May 20, 2022

That fixed it:

image

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

No branches or pull requests

1 participant