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

Better ReadTheDocs integration #3104

Closed
4 tasks done
2bndy5 opened this issue Oct 12, 2021 · 10 comments
Closed
4 tasks done

Better ReadTheDocs integration #3104

2bndy5 opened this issue Oct 12, 2021 · 10 comments

Comments

@2bndy5
Copy link
Contributor

2bndy5 commented Oct 12, 2021

Contribution guidelines

I want to suggest an idea and checked that ...

  • ... to my best knowledge, my idea wouldn't break something for other users
  • ... the documentation does not mention anything about my idea
  • ... there are no open or closed issues that are related to my idea

Description

There's 1 feature that hosting from readthedocs.org has over gh-pages: Different built versions of docs based on tagged commits or separate branches. When you browse any docs hosted by RTFD, you will see a added selector menu that looks like
image
or in the official readthedocs sphinx theme
image

When expanded, the menu looks like
image


I've worked out how to do this on a theme based on this repo, but I think it would be better to have this feature upstream. Please excuse my assumptions based on the repo structure.

src/partials/integrations/readthedocs.html

Most of this was copied from the html template used in the readthedocs sphinx theme

{% if READTHEDOCS %}
{# This integration is specially styled to cohesively appear in the nav menu. #}
  <div class="md-nav__rtd-versions" data-toggle="rst-current-version" aria-label="{{ _('Versions') }}">
    <span class="md-nav__rtd-current-version" data-toggle="rst-current-version">
      <span class="md-nav__rtd-fa-book"> Read The Docs</span>
      v: {{ current_version }}
      <span class="md-nav__rtd-fa-caret"></span>
    </span>
  </div>
  <div class="md-nav__rtd-other-versions">
    <dl>
      <dt>{{ _('Versions') }}</dt>
      {% for slug, url in versions %}
        <dd><a href="{{ url }}">{{ slug }}</a></dd>
      {% endfor %}
    </dl>
    {% if downloads|length > 0 %}
    <dl>
      <dt>{{ _('Downloads') }}</dt>
      {% for type, url in downloads %}
        <dd><a href="{{ url }}">{{ type }}</a></dd>
      {% endfor %}
    </dl>
    {% endif %}
    <dl>
      {# Translators: The phrase "Read the Docs" is not translated #}
      <dt>{{ _('On Read the Docs') }}</dt>
        <dd>
          <a href="//{{ PRODUCTION_DOMAIN }}/projects/{{ slug }}">{{ _('Project Home') }}</a>
        </dd>
        <dd>
          <a href="//{{ PRODUCTION_DOMAIN }}/projects/{{ slug }}/builds">{{ _('Builds') }}</a>
        </dd>
    </dl>
  </div>
{% endif %}
--- src/partials/nav.html
+++ src/partials/nav.html
@@ -53,58 +53,59 @@
   <!-- Repository information -->
   {% if config.repo_url %}
     <div class="md-nav__source">
       {% include "partials/source.html" %}
     </div>
   {% endif %}
+  {% include "partials/integrations/readthedocs.html" %}
src/assets/stylesheets/main/extensions/readthedocs/_readthedocs.scss
:root {
  --md-rtd-book-icon: svg-load("fontawesome/solid/book.svg");
  --md-rtd-caret-down-icon: svg-load("fontawesome/solid/caret-down.svg");
  --md-rtd-caret-left-icon: svg-load("fontawesome/solid/caret-left.svg");
}

.md-nav__rtd-versions {
  padding: 12px;
  display: block;
  text-align: right;
  background-color: #272525;
  cursor: pointer;
  color: #fefefe;

  .md-nav__rtd-current-version {
    color: #27ae60;

    .md-nav__rtd-fa-book {
      float: left;
      color: #fefefe;

      &::before{
        display: inline-block;
        width: 0.7rem;
        height: 0.7rem;
        background-color: currentColor;
        mask-image: var(--md-rtd-book-icon);
        mask-repeat: no-repeat;
        content: "";
      }
    }

    .md-nav__rtd-fa-caret {
      color: #fefefe;

      &::before {
        display: inline-block;
        width: 0.5rem;
        height: 0.7rem;
        background-color: currentColor;
        mask-image: var(--md-rtd-caret-left-icon);
        mask-repeat: no-repeat;
        content: "";
      }

      &.expanded {
        color: #fefefe;

        &::before {
          display: inline-block;
          width: 0.5rem;
          height: 0.7rem;
          background-color: currentColor;
          mask-image: var(--md-rtd-caret-down-icon);
          mask-repeat: no-repeat;
          content: "";
        }
      }
    }
  }
}

.md-nav__rtd-other-versions {
  text-align: left;
  display: none;
  background-color: #1f1d1d;
  overflow-y: auto;

  &.expanded {
    display: block;
  }

  a {
    border: 0;
  }

  dl {
    margin: 0 0.3rem;
  }
  dt {
    color: grey;
    padding: .25rem 0;
  }
  dd {
    display: inline-block;
    margin: .25rem;
  }
}
--- src/assets/stylesheets/main.scss
+++ src/assets/stylesheets/main.scss
@@ -73,75 +73,76 @@
 @import "main/extensions/pymdownx/tasklist";
 
+@import "main/extensions/readthedocs/readthedocs";
src/assets/javascripts/integrations/readthedocs/index.ts
/* insert License here */

function toggleReadTheDocsContextDetails(): void {
    var caret = document.getElementsByClassName("md-nav__rtd-fa-caret");
    var contextDetails = document.getElementsByClassName("md-nav__rtd-other-versions");
    caret[0].classList.toggle("expanded");
    contextDetails[0].classList.toggle("expanded");
}

export function setupReadTheDocsVersionSelector(): void {
    var currentVersion = document.getElementsByClassName("md-nav__rtd-versions");
    if (currentVersion.length > 0) {
        currentVersion[0].addEventListener("click", toggleReadTheDocsContextDetails, false);
    }
}
--- src/assets/javascripts/integrations/index.ts
+++ src/assets/javascripts/integrations/index.ts
@@ -23,26 +23,27 @@
 export * from "./clipboard"
 export * from "./instant"
 export * from "./search"
 export * from "./version"
+export * from "./readthedocs"
--- src/assets/javascripts/bundle.ts
+++ src/assets/javascripts/bundle.ts
@@ --114,117 +114,119 @@
 /* Set up version selector */
 if (config.version?.provider === "mike")
   setupVersionSelector()

+/* setup ReadTheDocs version selector */
+setupReadTheDocsVersionSelector();
+

Use Cases

Literally anyone using readthedocs.org to host their documentation would benefit from this.

I often refer beta testers to a separate set of docs build from a dev branch.

I would like to raise the question, what would happen if the user disables the nav menu? Normally themes that don't have this feature supported have a floating equivalent menu in the lower right corner. However, this alternative menu placement doesn't seem to work with mkdocs themes.

Screenshots / Mockups

I decided to place the added menu atop all nav menu items. The following mockup results are done from the sphinx-immaterial theme (which is based on the latest release of this repo). These screenshots can be observed live from my project hosted at https://circuitpython-nrf24l01.readthedocs.io/en/rf24-network/

image
expanded this looks like
image

Compared to the native feature from screenshots at the top of this post, you'll notice that I left out the search input box (for obvious reasons). The "Downloads" section would show up if the project had additional formats of documentation (such as PDF or EPUB).

@squidfunk
Copy link
Owner

squidfunk commented Oct 12, 2021

Thanks for reporting and sharing your solution! However, I'm not interested in maintaining this functionality, because I'm not a user of RTD. Material for MkDocs recommends using GitHub or GitLab Pages. The modifications you made are trivial to add, as no functionality needs to be changed, only added, so I'd regard this as a perfect case for customization 😊

I would like to raise the question, what would happen if the user disables the nav menu? Normally themes that don't have this feature supported have a floating equivalent menu in the lower right corner. However, this alternative menu placement doesn't seem to work with mkdocs themes.

The navigation sidebar can be hidden, so it might not be the best location for the dropdown.

@2bndy5
Copy link
Contributor Author

2bndy5 commented Oct 12, 2021

I'd regard this as a perfect case for customization

Thanks for hearing me out. I'm not usually a mkdocs user, but I figured I'd run this idea by you before commiting it downstream to a sphinx derivative of this theme called sphinx-immaterial (not be confused with the "hacked" derivative sphinx-material). You can close this if you like.

@squidfunk
Copy link
Owner

I see. I'm aware of both projects. Thanks for taking it upstream, albeit my decision is not to integrate it. However, it's great that you shared your solution because anybody who wants to improve the integration has now something to work with.

@mpilgrem
Copy link

mpilgrem commented Sep 1, 2022

@2bndy5, many thanks for your detailed description above about how to customize Material for MkDocs. The Haskell Tool Stack ('Stack') project uses Read the Docs (RTD) with MkDocs, and I had been trying to move to the Material for MkDocs theme (which looks excellent) for new versions, and the only sticking point was the absence of support for the RTD flyout.

I've read https://squidfunk.github.io/mkdocs-material/customization/#extending-the-theme and I thought I had copied what you propose faithfully in the mkdocs-test branch of the Stack repository: https://github.com/commercialhaskell/stack/tree/mkdocs-test. Read the Docs builds and renders that as https://docs.haskellstack.org/en/mkdocs-test/ ... but I still do not have an RTD flyout. I've CTRL-F5-ed and so it is not a browser caching problem.

I've looked at the source HTML for the rendered page, and I can't see anything in it to suggest that partials/integrations/readthedocs.html is actually getting injected. It is as if the theme.custom_dir is being entirely ignored.

The overrides are in folder /overrrides and my /mkdocs.yml file has this stanza:

theme:
  name: material
  custom_dir: overrides
  palette:
    primary: 'deep purple'
    accent: 'deep purple'
  icon:
    logo: material/language-haskell

My doc/requirements.txt file has this:

mkdocs==1.3.1
mkdocs-material

So, I am at a loss as to what I am doing wrong. If you could spare a moment to look at what I have done, I would be very grateful.

I did wonder if main\extensions\readthedocs\_readthedocs.scss was meant to have the intital "_", but removing it from the file name seemed to have no effect.

@2bndy5
Copy link
Contributor Author

2bndy5 commented Sep 1, 2022

I have added the RTD integration into sphinx-immaterial (an offshoot of this theme for sphinx - not mkdocs). IIRC, the above proposal is based on the fact that RTD installs its own sphinx extension which injects assets like JS, CSS, & HTML. Since mkdocs cannot use this readthedocs-sphinx-ext (which seems to have been updated since I posted this), I just created imitations of the CSS & JS from that extension into the theme assets and introduced the necessary HTML template.

Looking at your mkdocs-test output in RTD, the browser's dev console shows an error which may indicate the lack of jquery in this theme (I'm not a JS expert). Personally, I don't think RTD should be assuming that all themes use jquery, and I'm glad this theme doesn't.

Have you looked at how mkdocs' readthedocs theme integrates the flyout menu? I would start with their version.html template The CSS from this post should still work though. However, their JS also uses jquery.


I'm sorry I couldn't be of more help, but I'm committed to maintaining sphinx-immaterial theme. I don't like mkdocs' inadequate ability to document an API (seems best suited for a REST API), and I've tried the various mkdocs plugins that claim to augment mkdocs for that purpose... And, the version flyout for RTD is leagues better than this theme's version dropdown integration.

@mpilgrem
Copy link

mpilgrem commented Sep 2, 2022

@2bndy5 thanks for taking the time to consider my request - that is much appreciated. I am on a steep learning curve, but I will follow up your pointers.

@chester-leung
Copy link

chester-leung commented Dec 13, 2022

@mpilgrem were you able to make any progress on this? I am running into a similar issue where the flyout does not work properly on RTD.

@mpilgrem
Copy link

mpilgrem commented Dec 13, 2022

@chester-leung, yes, I was. The site is here: https://docs.haskellstack.org/en/stable/ and its mkdocs.yml and other configuration at: https://github.com/commercialhaskell/stack. From memory, the solution was as explained in this part of that mkdocs.yml:

extra_javascript:
- js/searchhack.js
# Read the Docs requires JQuery for its JavaScript code to inject the flyout
# menu. Material for MkDocs does not come with JQuery.
- 'https://code.jquery.com/jquery-3.6.1.min.js'

EDIT: I also had problems with the fly out format. So, I had this in the mkdocs.yml:

extra_css:
- css/extra.css

and this in css/extra.css:

.hidden-warning {
    display: none
}

/* The Read the Docs flyout is formatted with a font-size that is 90% of the
body's. Material for MkDocs has a body font-size that is 0.5rem. This body
font-size will result in the flyout having a font-size of 0.7rem, consistent
with the font-size of other elements in the theme.
*/
body {
    font-size: 0.777778rem;
}

@chester-leung
Copy link

@mpilgrem this worked for me as well. Thank you so much!

@humitos
Copy link

humitos commented Sep 8, 2023

Hi 👋🏼 . For anyone still interested in a better Read the Docs integration with Material for MkDocs, I wanted to let them know that we (I work at Read the Docs) have been working on this for some time now and we have a beta available ready for those who want to opt-in and try it out 🚀 . Read more about it at https://blog.readthedocs.com/addons-flyout-menu-beta/

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

5 participants