Skip to content

Commit

Permalink
Addons: integrate with new beta addons flyout (#1526)
Browse files Browse the repository at this point in the history
* Addons: integrate with new beta addons flyout

Initial experimentation to use the `CustomEvent` triggered by the addons called
`readthedocsdataready` event (from
readthedocs/addons#64) to build the Read the Docs
flyout being integrated into the theme keeping the original look & feel.

* Related: readthedocs/addons#64
* Closes #1523

* `READTHEDOCS` variable has to be passed to the `html_context`

This is because we are not executing the Read the Docs magic that modifies the
`conf.py` file on the fly :/

* Update code to match the latest changes

* Use `.join` to avoid rendering the Array with `,`

* Update code to use the v1 API structure response

* Don't auto-remove the original flyout

This can be disabled per-project by using the settings UI from the dashboard.

* Join the values to avoid strange `,`s

* Support translations

Use the current pattern to translate string generated for the flyout.

* Remove HTML tags for testing

* Show "Search" section on flyout

* Render footer

* Add some styling

* TODO comments to work on

* add `div.injected`

* Apply suggestions from code review

Co-authored-by: Anthony <[email protected]>

* Translate privacy policy

* Add `.rtd-current-item` class to selected version/language

* Refactor code to show sections only if there is content

* Epub instead of EPUB for backward compatibility

* Show the modal when clicking on the "Search docs" from navbar

* Remove privacy policy link from flyout

* Add UTM analytics

* Move CSS style into SASS file

* Move the `script` tag into its own file

* Rename JS file to mark it as a Sphinx template

* Build css/js files

Run `npm ci` and `npm run build` using NodeJS 14.20.1.

* Add the JS template in the package

---------

Co-authored-by: Anthony <[email protected]>
  • Loading branch information
humitos and agjohnson authored Jul 15, 2024
1 parent 28c377f commit 357e76d
Show file tree
Hide file tree
Showing 8 changed files with 144 additions and 36 deletions.
1 change: 1 addition & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ recursive-include sphinx_rtd_theme *.css
recursive-include sphinx_rtd_theme *.eot
recursive-include sphinx_rtd_theme *.html
recursive-include sphinx_rtd_theme *.js
recursive-include sphinx_rtd_theme *.js_t
recursive-include sphinx_rtd_theme *.svg
recursive-include sphinx_rtd_theme *.ttf
recursive-include sphinx_rtd_theme *.woff
Expand Down
4 changes: 4 additions & 0 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@
range(1, 100)
))

if 'READTHEDOCS' in os.environ:
html_context['READTHEDOCS'] = True
html_context['READTHEDOCS_PROJECT'] = os.environ.get("READTHEDOCS_PROJECT")

html_logo = "demo/static/logo-wordmark-light.svg"
html_show_sourcelink = True
html_favicon = "demo/static/favicon.ico"
Expand Down
7 changes: 7 additions & 0 deletions sphinx_rtd_theme/layout.html
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
<html class="writer-html5" lang="{{ lang_attr }}"{% if sphinx_version_info >= (7, 2) %} data-content_root="{{ content_root }}"{% endif %}>
<head>
<meta charset="utf-8" />
{%- if READTHEDOCS and not embedded %}
<meta name="readthedocs-addons-api-version" content="1">
{%- endif %}
{{- metatags }}
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
{%- block htmltitle %}
Expand Down Expand Up @@ -64,6 +67,10 @@
{%- endfor %}
<script src="{{ pathto('_static/js/theme.js', 1) }}"></script>

{%- if READTHEDOCS %}
<script src="{{ pathto('_static/js/versions.js', 1) }}"></script>
{%- endif %}

{#- OPENSEARCH #}
{%- if use_opensearch %}
<link rel="search" type="application/opensearchdescription+xml"
Expand Down
2 changes: 1 addition & 1 deletion sphinx_rtd_theme/static/css/badge_only.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion sphinx_rtd_theme/static/css/theme.css

Large diffs are not rendered by default.

125 changes: 125 additions & 0 deletions sphinx_rtd_theme/static/js/versions.js_t
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
function renderLanguages(config) {
if (!config.projects.translations.length) {
return "";
}

const languagesHTML = `
<dl>
<dt>{{ _('Languages') }}</dt>
${ config.projects.translations.map(
(translation) => `
<dd ${ translation.slug == config.projects.current.slug ? 'class="rtd-current-item"' : '' }>
<a href="${ translation.urls.documentation }">${ translation.language.code }</a>
</dd>
`).join("\n")}
</dl>
`;
return languagesHTML;
}

function renderVersions(config) {
if (!config.versions.active.length) {
return "";
}
const versionsHTML = `
<dl>
<dt>{{ _('Versions') }}</dt>
${ config.versions.active.map(
(version) => `
<dd ${ version.slug === config.versions.current.slug ? 'class="rtd-current-item"' : '' }>
<a href="${ version.urls.documentation }">${ version.slug }</a>
</dd>
`).join("\n")}
</dl>
`;
return versionsHTML;
}

function renderDownloads(config) {
if (!Object.keys(config.versions.current.downloads).length) {
return "";
}
const downloadsNameDisplay = {
pdf: "PDF",
epub: "Epub",
htmlzip: "HTML",
};

const downloadsHTML = `
<dl>
<dt>{{ _('Downloads') }}</dt>
${ Object.entries(config.versions.current.downloads).map(
([name, url]) => `
<dd>
<a href="${ url }">${ downloadsNameDisplay[name] }</a>
</dd>
`).join("\n")}
</dl>
`;
return downloadsHTML;
}

document.addEventListener("readthedocs-addons-data-ready", function(event) {
const config = event.detail.data();

const flyout = `
<div class="rst-versions" data-toggle="rst-versions" role="note">
<span class="rst-current-version" data-toggle="rst-current-version">
<span class="fa fa-book"> Read the Docs</span>
v: ${ config.versions.current.slug }
<span class="fa fa-caret-down"></span>
</span>
<div class="rst-other-versions">
<div class="injected">
${ renderLanguages(config) }
${ renderVersions(config) }
${ renderDownloads(config) }
<dl>
<dt>{{ _('On Read the Docs') }}</dt>
<dd>
<a href="${ config.projects.current.urls.home }">{{ _('Project Home') }}</a>
</dd>
<dd>
<a href="${ config.projects.current.urls.builds }">{{ _('Builds') }}</a>
</dd>
<dd>
<a href="${ config.projects.current.urls.downloads }">{{ _('Downloads') }}</a>
</dd>
</dl>
<dl>
<dt>{{ _('Search') }}</dt>
<dd>
<form id="flyout-search-form">
<input
class="wy-form"
type="text"
name="q"
aria-label="{{ _('Search docs') }}"
placeholder="{{ _('Search docs') }}"
/>
</form>
</dd>
</dl>
<hr />
<small>
<span>Hosted by <a href="https://about.readthedocs.org/?utm_source={{ READTHEDOCS_PROJECT }}&utm_content=flyout">Read the Docs</a></span>
</small>
</div>
</div>
`;

// Inject the generated flyout into the body HTML element.
document.body.insertAdjacentHTML("beforeend", flyout);

// Trigger the Read the Docs Addons Search modal when clicking on the "Search docs" input from inside the flyout.
document.querySelector("#flyout-search-form").addEventListener("focusin", () => {
const event = new CustomEvent("readthedocs-search-show");
document.dispatchEvent(event);
});

// Trigger the Read the Docs Addons Search modal when clicking on "Search docs" input from the topnav.
document.querySelector("[role='search'] input").addEventListener("focusin", () => {
const event = new CustomEvent("readthedocs-search-show");
document.dispatchEvent(event);
});
});
34 changes: 0 additions & 34 deletions sphinx_rtd_theme/versions.html
Original file line number Diff line number Diff line change
@@ -1,34 +0,0 @@
{% if READTHEDOCS %}
{# Add rst-badge after rst-versions for small badge style. #}
<div class="rst-versions" data-toggle="rst-versions" role="note" aria-label="{{ _('Versions') }}">
<span class="rst-current-version" data-toggle="rst-current-version">
<span class="fa fa-book"> Read the Docs</span>
v: {{ current_version }}
<span class="fa fa-caret-down"></span>
</span>
<div class="rst-other-versions">
<dl>
<dt>{{ _('Versions') }}</dt>
{% for slug, url in versions %}
<dd><a href="{{ url }}">{{ slug }}</a></dd>
{% endfor %}
</dl>
<dl>
<dt>{{ _('Downloads') }}</dt>
{% for type, url in downloads %}
<dd><a href="{{ url }}">{{ type }}</a></dd>
{% endfor %}
</dl>
<dl>
{# Translators: The phrase "Read the Docs" is not translated #}
<dt>{{ _('On Read the Docs') }}</dt>
<dd>
<a href="//{{ PRODUCTION_DOMAIN }}/projects/{{ slug }}/?fromdocs={{ slug }}">{{ _('Project Home') }}</a>
</dd>
<dd>
<a href="//{{ PRODUCTION_DOMAIN }}/builds/{{ slug }}/?fromdocs={{ slug }}">{{ _('Builds') }}</a>
</dd>
</dl>
</div>
</div>
{% endif %}
5 changes: 5 additions & 0 deletions src/sass/_theme_badge.sass
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@
display: inline-block
padding: $base-line-height / 4
color: $section-background-color
.rtd-current-item
font-weight: bold
&.rst-badge
width: auto
bottom: 20px
Expand Down Expand Up @@ -92,3 +94,6 @@
display: none
&.shift
display: block

#flyout-search-form
padding: 6px

0 comments on commit 357e76d

Please sign in to comment.