Merge pull request #420 from ZoiteChat/docs-theme-update

update theme to match new site
This commit is contained in:
deepend-tildeclub
2026-10-12 17:11:27 -07:00
committed by GitHub
9 changed files with 881 additions and 2289 deletions
+46 -5
View File
@@ -33,10 +33,51 @@ Example:
that is not visually indented
```
## Read the Docs theme skin
## HTML theme
The HTML output keeps the existing `basicstrap` Sphinx theme, then applies the
ZoiteChat main-site skin from `_static/css/zoitechat-docs.css`.
The `zoitechat` theme inherits Sphinx's built-in `basic` theme. It uses the
same compact layout, blue navigation, and system fonts as zoitechat.org.
Appearance starts in System mode on each page. Light and Dark are available
for the current page; no cookies or browser storage are used.
Brand navigation links are set in `conf.py` through `html_context`, and the
header logo uses `_static/zoitechat-logo.svg`.
The theme's templates are in `_theme/zoitechat/`. Its readable CSS and
JavaScript are in `_static/css/zoitechat-docs.css` and
`_static/js/zoitechat-docs.js`. No minification, JavaScript package manager,
external fonts, or CDN assets are required.
Navigation URLs, including `zoite_atlas_url`, are configured through
`html_context` in `conf.py`. The logo
is `_static/zoitechat-logo.svg`. Standard Sphinx search, indexes, source
links, anchors, translations, and previous/next links remain available.
The HTML output also works as locally installed documentation; project-site
links only access the network when clicked.
Build from the repository root:
```sh
sphinx-build -b html docs docs/_build/html
```
Use a clean output directory when switching themes, so stale Basicstrap
assets from an earlier build are not included in a package.
## Debian packaging
The active theme does not use the bundled Basicstrap, Bootstrap, jQuery,
jQuery Cookie, Font Awesome, or icon fonts. Its font stack includes DejaVu
Sans and DejaVu Sans Mono; no font files are bundled by the theme.
Packagers may exclude `docs/_theme/basicstrap/` from the source package.
The default theme continues to build without that directory. No pre-minified
third-party assets need to be added or rebuilt for this theme.
Build with the distribution's `python3-sphinx`. After installing the HTML
into the package staging directory, use `dh_sphinxdoc` (or `dh --with
sphinxdoc`) to replace Sphinx's standard JavaScript files with system
symlinks. Include `${sphinxdoc:Depends}` in the package dependencies and
`${sphinxdoc:Built-Using}` where required for generated assets. The custom
`zoitechat-docs.js` remains a small, readable project source file.
A built-in theme is still selectable with `-D html_theme=classic` if a
packager needs a different layout. The old RST content has existing build
diagnostics; changing the theme does not suppress or alter them.
+655 -2281
View File
File diff suppressed because it is too large Load Diff
+44
View File
@@ -0,0 +1,44 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
(() => {
'use strict';
const initialise = () => {
const picker = document.getElementById('theme-picker');
const preference = window.matchMedia('(prefers-color-scheme: dark)');
if (picker instanceof HTMLSelectElement) {
const applyTheme = () => {
const dark = picker.value === 'dark'
|| (picker.value === 'system' && preference.matches);
document.documentElement.dataset.theme = dark ? 'dark' : 'light';
document.querySelectorAll('meta[name="theme-color"]').forEach((meta) => {
meta.setAttribute('content', dark ? '#111416' : '#ffffff');
});
};
// Follow the OS on every visit, including browser back/forward navigation.
const resetTheme = () => {
picker.value = 'system';
applyTheme();
};
picker.addEventListener('change', applyTheme);
preference.addEventListener('change', applyTheme);
window.addEventListener('pageshow', resetTheme);
resetTheme();
}
const navigation = document.getElementById('docs-navigation');
const compact = window.matchMedia('(max-width: 760px)');
if (navigation instanceof HTMLDetailsElement) {
const fitNavigation = () => { navigation.open = !compact.matches; };
compact.addEventListener('change', fitNavigation);
fitNavigation();
}
};
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', initialise, { once: true });
} else {
initialise();
}
})();
+5
View File
@@ -0,0 +1,5 @@
{# SPDX-License-Identifier: GPL-2.0-or-later #}
<nav class="global-toc" aria-label="{{ _('Documentation contents') }}">
<h2>{{ _('Contents') }}</h2>
{{ toctree(maxdepth=2, collapse=true, includehidden=true, titles_only=true) }}
</nav>
+102
View File
@@ -0,0 +1,102 @@
{# SPDX-License-Identifier: GPL-2.0-or-later #}
{% extends "basic/layout.html" %}
{% set docs_root = root_doc|default(master_doc) %}
{% block extrahead %}
{{ super() }}
<meta name="theme-color" content="#ffffff" media="(prefers-color-scheme: light)">
<meta name="theme-color" content="#111416" media="(prefers-color-scheme: dark)">
{% endblock %}
{% block body_tag %}<body id="top">{% endblock %}
{% block header %}
<a class="skip-link" href="#main-content">{{ _('Skip to content') }}</a>
<header class="site-header">
<div class="topbar">
<a class="brand" href="{{ pathto(docs_root)|e }}">
<img src="{{ logo_url|default(pathto('_static/zoitechat-logo.svg', 1), true)|e }}" alt="" width="38" height="42">
<strong>{{ project|e }}</strong>
</a>
<label class="appearance" for="theme-picker">
<span>{{ _('Appearance') }}</span>
<select id="theme-picker" aria-label="{{ _('Documentation appearance') }}">
<option value="system" selected>{{ _('System') }}</option>
<option value="light">{{ _('Light') }}</option>
<option value="dark">{{ _('Dark') }}</option>
</select>
</label>
</div>
<nav class="site-nav" aria-label="{{ _('Primary navigation') }}">
<a href="{{ zoite_site_url|e }}">{{ _('Home') }}</a>
<a href="{{ zoite_download_url|e }}">{{ _('Downloads') }}</a>
<a href="{{ zoite_addons_url|e }}">{{ _('Addons') }}</a>
<a class="selected" href="{{ pathto(docs_root)|e }}" aria-current="location">{{ _('Documentation') }}</a>
<a href="{{ zoite_atlas_url|e }}">{{ _('Atlas') }}</a>
{% if hasdoc('genindex') %}<a href="{{ pathto('genindex')|e }}">{{ _('Index') }}</a>{% endif %}
<details class="support-menu">
<summary>{{ _('IRC support') }}</summary>
<div class="support-links">
<a href="{{ zoite_irc_url|e }}">{{ _('Zoite IRC') }}<small>#zoitechat · {{ _('Official support') }}</small></a>
<a href="{{ libera_irc_url|e }}">{{ _('Libera.Chat') }}<small>#zoitechat</small></a>
</div>
</details>
</nav>
<div class="docs-location">
<nav aria-label="{{ _('Breadcrumbs') }}">
<a href="{{ pathto(docs_root)|e }}">{{ _('Documentation') }}</a>
{% for parent in parents %}
<span aria-hidden="true">/</span> <a href="{{ parent.link|e }}">{{ parent.title }}</a>
{% endfor %}
{% if pagename != docs_root %}<span aria-hidden="true">/</span> <span>{{ title|striptags|e }}</span>{% endif %}
</nav>
<span class="docs-version">{{ release|e }}</span>
</div>
</header>
{% endblock %}
{% block relbar1 %}{% endblock %}
{% block relbar2 %}{% endblock %}
{% block content %}
<div class="docs-layout{% if not render_sidebar %} no-sidebar{% endif %}">
{% if render_sidebar %}
<aside class="docs-sidebar" aria-label="{{ _('Documentation navigation') }}">
<details class="docs-navigation" id="docs-navigation" open>
<summary>{{ _('Documentation') }}</summary>
<div class="sidebar-content">
{% for sidebartemplate in sidebars %}
{% include sidebartemplate %}
{% endfor %}
</div>
</details>
</aside>
{% endif %}
<main class="docs-content" id="main-content" tabindex="-1">
{% block body %}{% endblock %}
{% if prev or next %}
<nav class="page-relations" aria-label="{{ _('Related pages') }}">
<div>
{% if prev %}<small>{{ _('Previous') }}</small><a href="{{ prev.link|e }}" rel="prev">{{ prev.title }}</a>{% endif %}
</div>
<div>
{% if next %}<small>{{ _('Next') }}</small><a href="{{ next.link|e }}" rel="next">{{ next.title }}</a>{% endif %}
</div>
</nav>
{% endif %}
</main>
</div>
{% endblock %}
{% block footer %}
<footer class="site-footer">
<span>{{ project|e }} {{ _('documentation') }} · {{ release|e }}</span>
<nav aria-label="{{ _('Footer navigation') }}">
<a href="{{ pathto(docs_root)|e }}">{{ _('Contents') }}</a>
<a href="{{ zoite_atlas_url|e }}">{{ _('Atlas') }}</a>
{% if hasdoc('search') %}<a href="{{ pathto('search')|e }}">{{ _('Search') }}</a>{% endif %}
{% if hasdoc('genindex') %}<a href="{{ pathto('genindex')|e }}">{{ _('Index') }}</a>{% endif %}
<a href="#top">{{ _('Back to top') }}</a>
</nav>
</footer>
{% endblock %}
+7
View File
@@ -0,0 +1,7 @@
{# SPDX-License-Identifier: GPL-2.0-or-later #}
{% if display_toc %}
<nav class="local-toc" aria-label="{{ _('On this page') }}">
<h2>{{ _('On this page') }}</h2>
{{ toc }}
</nav>
{% endif %}
+10
View File
@@ -0,0 +1,10 @@
{# SPDX-License-Identifier: GPL-2.0-or-later #}
{% if pagename != "search" %}
<form class="docs-search" action="{{ pathto('search')|e }}" method="get" role="search">
<label for="docs-search-input">{{ _('Search documentation') }}</label>
<div class="search-inputs">
<input id="docs-search-input" type="search" name="q" placeholder="{{ _('Search documentation') }}" autocomplete="off" spellcheck="false">
<button type="submit">{{ _('Search') }}</button>
</div>
</form>
{% endif %}
+7
View File
@@ -0,0 +1,7 @@
[theme]
inherit = basic
stylesheet = basic.css
pygments_style = sphinx
sidebars = searchbox.html, globaltoc.html, localtoc.html, sourcelink.html
[options]
+5 -3
View File
@@ -99,7 +99,7 @@ trim_footnote_reference_space = True
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
html_theme = 'basicstrap'
html_theme = 'zoitechat'
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
@@ -127,13 +127,14 @@ html_context = {
'zoite_site_url': 'https://zoitechat.org/',
'zoite_download_url': 'https://zoitechat.org/download.php',
'zoite_addons_url': 'https://zoitechat.org/addons.php',
'zoite_atlas_url': 'https://atlas.zoitechat.org/',
'zoite_irc_url': 'https://zoite.net/webchat/?join=%23zoitechat',
'libera_irc_url': 'https://web.libera.chat/#zoitechat',
}
# The name of an image file (relative to this directory) to place at the top
# of the sidebar.
html_logo = 'zoitechat-logo.svg'
html_logo = '_static/zoitechat-logo.svg'
# The name of an image file (within the static path) to use as favicon of the
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
@@ -145,8 +146,9 @@ html_favicon = '_static/favicon.ico'
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
# Main-site visual skin for Read the Docs/Sphinx HTML output.
# Local, readable assets shared by hosted and offline HTML documentation.
html_css_files = ['css/zoitechat-docs.css']
html_js_files = ['js/zoitechat-docs.js']
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format.