Bootstrap-based Sphinx theme from the PyData community
npx @tessl/cli install tessl/pypi-pydata-sphinx-theme@0.16.0A comprehensive Bootstrap-based Sphinx documentation theme specifically designed for the PyData community ecosystem. The theme provides a clean, three-column layout with extensive customization options including light/dark theme switching, analytics integration, flexible navigation components, and comprehensive branding features. It's built with modern web technologies while maintaining compatibility with Sphinx documentation workflows and is designed for maximum reusability across scientific Python documentation projects.
pip install pydata-sphinx-themeimport pydata_sphinx_theme
from pydata_sphinx_theme import __version__The theme is typically configured through Sphinx's configuration system rather than direct imports:
# In conf.py
html_theme = "pydata_sphinx_theme"For programmatic access to theme information:
import pydata_sphinx_theme
print(f"Theme version: {pydata_sphinx_theme.__version__}")# conf.py - Basic Sphinx configuration
html_theme = "pydata_sphinx_theme"
# Optional: Theme customization
html_theme_options = {
"logo": {
"image_light": "logo-light.png",
"image_dark": "logo-dark.png",
"text": "My Project"
},
"icon_links": [
{
"name": "GitHub",
"url": "https://github.com/user/repo",
"icon": "fa-brands fa-square-github",
"type": "fontawesome",
}
],
"use_edit_page_button": True,
"show_toc_level": 2,
"navbar_align": "left",
}
# Context variables for edit buttons and version switching
html_context = {
"github_user": "user",
"github_repo": "repo",
"github_version": "main",
"doc_path": "docs/",
}The theme follows Sphinx's extension architecture pattern:
Core functionality for registering the theme with Sphinx and managing configuration options, including theme options validation, deprecated key handling, and analytics integration.
def setup(app: Sphinx) -> Dict[str, str]:
"""Setup the Sphinx application."""
def update_config(app):
"""Update config with new default values and handle deprecated keys."""Template processing functionality that manages Jinja2 template rendering, asset injection, and HTML context preparation for each page during the build process.
def update_and_remove_templates(
app: Sphinx, pagename: str, templatename: str, context, doctree
) -> None:
"""Update template names and assets for page build."""
def _fix_canonical_url(
app: Sphinx, pagename: str, templatename: str, context: dict, doctree
) -> None:
"""Fix the canonical URL when using the dirhtml builder."""Helper functions for theme configuration management, template processing, sidebar customization, and Sphinx integration utilities.
def get_theme_options_dict(app: Sphinx) -> Dict[str, Any]:
"""Return theme options for the application w/ a fallback if they don't exist."""
def config_provided_by_user(app: Sphinx, key: str) -> bool:
"""Check if the user has manually provided the config."""
def set_secondary_sidebar_items(
app: Sphinx, pagename: str, templatename: str, context, doctree
) -> None:
"""Set the secondary sidebar items to render for the given pagename."""Functionality for generating "edit this page" links that work with GitHub, GitLab, and Bitbucket repositories, supporting custom URL templates and multiple version control platforms.
def setup_edit_url(
app: Sphinx, pagename: str, templatename: str, context, doctree
) -> None:
"""Add a function that jinja can access for returning the edit URL of a page."""Logo handling system that supports light/dark theme variants, custom logo positioning, and automatic asset copying to the build output directory.
def setup_logo_path(
app: Sphinx, pagename: str, templatename: str, context: dict, doctree: Node
) -> None:
"""Set up relative paths to logos in HTML templates."""
def copy_logo_images(app: Sphinx, exception=None) -> None:
"""Copy logo image to the _static directory."""Pygments integration that provides dynamic light/dark theme switching for code syntax highlighting, with automatic fallbacks and custom style generation.
def get_pygments_stylesheet(light_style: str, dark_style: str) -> str:
"""Generate the theme-specific pygments.css."""
def overwrite_pygments_css(app: Sphinx, exception=None):
"""Overwrite pygments.css to allow dynamic light/dark switching."""Transform system for automatically shortening and styling GitHub and GitLab repository links in documentation, making them more readable and visually consistent.
class ShortenLinkTransform(SphinxPostTransform):
"""Transform to shorten GitHub/GitLab links."""
def run(self, **kwargs):
"""Run the Transform object."""
def parse_url(self, uri: ParseResult) -> str:
"""Parse the content of the url with respect to the selected platform."""Advanced TOC processing with support for inline math rendering, ancestor page determination, and custom toctree function injection for enhanced navigation.
def add_inline_math(node: Node) -> str:
"""Render a node with HTML tags that activate MathJax processing."""
def add_toctree_functions(
app: Sphinx, pagename: str, templatename: str, context, doctree
) -> None:
"""Add toctree-related functions to template context."""Bootstrap-specific HTML translator that modifies Sphinx's default HTML output to be compatible with Bootstrap 5 styling, including table formatting and accessibility improvements.
class BootstrapHTML5TranslatorMixin:
"""Mixin HTML Translator for a Bootstrap-ified Sphinx layout."""
def starttag(self, *args, **kwargs):
"""Perform small modifications to tags."""
def visit_table(self, node):
"""Custom visit table method."""
def depart_table(self, node):
"""Custom depart_table method to close the scrollable div."""
def setup_translators(app: Sphinx):
"""Add bootstrap HTML functionality if we are using an HTML translator."""# Version constant
__version__: str # Current theme version (e.g., "0.16.1")
# From typing imports
from typing import Dict, Any, List, Optional, Union, Callable, Iterable, ClassVar
from pathlib import Path
from urllib.parse import ParseResult
# Sphinx types
from sphinx.application import Sphinx
from sphinx.builders.dirhtml import DirectoryHTMLBuilder
from docutils.nodes import Node
# Theme-specific types
ThemeOptions = Dict[str, Any]
TemplateList = Union[List[str], str]
IconLinkConfig = Dict[str, str] # Contains url, icon, name, type keys
LogoConfig = Dict[str, str] # Contains image_light, image_dark, text, link keys
# Additional types from the codebase
AnalyticsConfig = Dict[str, Union[str, Dict[str, str]]] # Contains google_analytics_id, plausible_analytics_domain, etc.
SwitcherConfig = Dict[str, Union[str, bool]] # Contains json_url, version_match, check_switcher
LinkInfo = Dict[str, Union[str, bool]] # Contains is_current, href, title, is_external