An awesome theme for the Sphinx documentation generator with enhanced features, custom code highlighting, and modern responsive design
Flexible logo system that supports separate light and dark mode logos with automatic asset copying, template context management, and comprehensive validation. This system enables responsive theming with proper logo display across different color schemes.
Utility function to safely access theme configuration across different Sphinx versions.
def get_theme_options(app: Sphinx) -> Any:
"""
Return theme options for the application.
Provides backward compatibility across Sphinx versions by checking
multiple possible locations for theme options.
Parameters:
- app (Sphinx): The Sphinx application instance
Returns:
Any: Theme options dictionary or empty dict if none found
"""Validates logo configuration and handles conflicting options.
def update_config(app: Sphinx) -> None:
"""
Update the configuration, handling the builder-inited event.
Validates logo configuration:
- Warns about conflicts between html_logo and theme logo options
- Ensures both light and dark logos are provided when using separate modes
- Provides clear guidance for proper logo configuration
Parameters:
- app (Sphinx): The Sphinx application instance
"""Updates template context with logo information for proper rendering.
def setup_logo_path(app: Sphinx, pagename: str, templatename: str,
context: dict[str, Any], doctree: Node) -> None:
"""
Update the logo path for the templates.
Processes logo paths and makes them available in template context:
- Converts file paths to basenames for template use
- Handles both local files and URLs
- Sets theme_logo_light and theme_logo_dark context variables
Parameters:
- app (Sphinx): The Sphinx application instance
- pagename (str): Current page name
- templatename (str): Template being rendered
- context (dict[str, Any]): Template context dictionary
- doctree (Node): Document tree node
"""Copies logo files to the output directory during the build process.
def copy_logos(app: Sphinx, exc: Exception | None) -> None:
"""
Copy the light and dark logos to the output directory.
Handles the build-finished event to:
- Copy logo files from source to _static directory
- Validate that logo files exist
- Skip URLs (external logos)
- Log warnings for missing files
Parameters:
- app (Sphinx): The Sphinx application instance
- exc (Exception | None): Build exception if any occurred
"""# In conf.py - Single logo (traditional Sphinx approach)
html_logo = "assets/logo.svg"
# Theme will use this logo for both light and dark modes# In conf.py - Separate logos for light and dark modes
html_theme_options = {
"logo_light": "assets/logo-light.svg",
"logo_dark": "assets/logo-dark.svg"
}
# Both logos are required when using separate mode approachhtml_theme_options = {
"logo_light": "https://example.com/logo-light.svg",
"logo_dark": "https://example.com/logo-dark.svg"
}
# URLs are not copied, used directly in templatesdocs/
├── conf.py
├── assets/
│ ├── logo-light.svg
│ ├── logo-dark.svg
│ └── favicon.ico
└── _static/
└── custom.cssThe logos are made available in templates as:
<!-- In Jinja2 templates -->
{% if theme_logo_light and theme_logo_dark %}
<img src="{{ pathto('_static/' + theme_logo_light, 1) }}"
class="logo light-mode" alt="Logo">
<img src="{{ pathto('_static/' + theme_logo_dark, 1) }}"
class="logo dark-mode" alt="Logo">
{% elif html_logo %}
<img src="{{ pathto('_static/' + html_logo, 1) }}"
class="logo" alt="Logo">
{% endif %}The system detects and warns about configuration conflicts:
# This will generate a warning
html_logo = "assets/logo.svg"
html_theme_options = {
"logo_light": "assets/logo-light.svg", # Conflict!
"logo_dark": "assets/logo-dark.svg"
}# This will generate a warning
html_theme_options = {
"logo_light": "assets/logo-light.svg",
# Missing logo_dark - both are required!
}# If logo files don't exist, warnings are logged:
# "Path to logo assets/missing-logo.svg does not exist."The logo system supports any file type that browsers can display:
Logo paths are resolved relative to the Sphinx configuration directory:
# In conf.py located at /project/docs/conf.py
html_theme_options = {
"logo_light": "assets/logo.svg" # Resolves to /project/docs/assets/logo.svg
}During build:
_output/_static/ directorypathto() referencesThe theme's CSS automatically handles logo display modes:
.logo.light-mode {
display: block;
}
.logo.dark-mode {
display: none;
}
@media (prefers-color-scheme: dark) {
.logo.light-mode {
display: none;
}
.logo.dark-mode {
display: block;
}
}Install with Tessl CLI
npx tessl i tessl/pypi-sphinxawesome-theme