This is a basic demo site for the Sphinx Bootstrap Theme that provides a minimal working Sphinx site using the theme.
Please see the Sphinx Bootstrap Theme page (also linked below in the TOC) for full details and installation instructions.
Setting up and using the theme.
This Sphinx theme integrates the Bootstrap CSS / JavaScript framework with various layout options, hierarchical menu navigation, and mobile-friendly responsive design. It is configurable, extensible, and can use any number of different Bootswatch CSS themes.
The theme is introduced and discussed in the following posts:
Examples of the theme in use for some public projects:
'bootswatch_theme': "sandstone"
to use the “Sandstone” Bootswatch theme.The theme demo website also includes an examples page for some useful illustrations of getting Sphinx to play nicely with Bootstrap (also take a look at the examples source for the underlying reStructuredText).
Installation from PyPI is fairly straightforward:
Install the package:
$ pip install sphinx_bootstrap_theme
Edit the “conf.py” configuration file to point to the bootstrap theme:
# At the top.
import sphinx_bootstrap_theme
# ...
# Activate the theme.
html_theme = 'bootstrap'
html_theme_path = sphinx_bootstrap_theme.get_html_theme_path()
The can be customized in varying ways (some a little more work than others).
The theme provides many built-in options that can be configured by editing your “conf.py” file:
# (Optional) Logo. Should be small enough to fit the navbar (ideally 24x24).
# Path should be relative to the ``_static`` files directory.
html_logo = "my_logo.png"
# Theme options are theme-specific and customize the look and feel of a
# theme further.
html_theme_options = {
# Navigation bar title. (Default: ``project`` value)
'navbar_title': "Demo",
# Tab name for entire site. (Default: "Site")
'navbar_site_name': "Site",
# A list of tuples containing pages or urls to link to.
# Valid tuples should be in the following forms:
# (name, page) # a link to a page
# (name, "/aa/bb", 1) # a link to an arbitrary relative url
# (name, "http://example.com", True) # arbitrary absolute url
# Note the "1" or "True" value above as the third argument to indicate
# an arbitrary url.
'navbar_links': [
("Examples", "examples"),
("Link", "http://example.com", True),
],
# Render the next and previous page links in navbar. (Default: true)
'navbar_sidebarrel': True,
# Render the current pages TOC in the navbar. (Default: true)
'navbar_pagenav': True,
# Tab name for the current pages TOC. (Default: "Page")
'navbar_pagenav_name': "Page",
# Global TOC depth for "site" navbar tab. (Default: 1)
# Switching to -1 shows all levels.
'globaltoc_depth': 2,
# Include hidden TOCs in Site navbar?
#
# Note: If this is "false", you cannot have mixed ``:hidden:`` and
# non-hidden ``toctree`` directives in the same page, or else the build
# will break.
#
# Values: "true" (default) or "false"
'globaltoc_includehidden': "true",
# HTML navbar class (Default: "navbar") to attach to <div> element.
# For black navbar, do "navbar navbar-inverse"
'navbar_class': "navbar navbar-inverse",
# Fix navigation bar to top of page?
# Values: "true" (default) or "false"
'navbar_fixed_top': "true",
# Location of link to source.
# Options are "nav" (default), "footer" or anything else to exclude.
'source_link_position': "nav",
# Bootswatch (http://bootswatch.com/) theme.
#
# Options are nothing (default) or the name of a valid theme
# such as "cosmo" or "sandstone".
'bootswatch_theme': "united",
# Choose Bootstrap version.
# Values: "3" (default) or "2" (in quotes)
'bootstrap_version': "3",
}
Note for the navigation bar title that if you don’t specify a theme option of
navbar_title
that the “conf.py” project
string will be used. We don’t
use the html_title
or html_short_title
values because by default those
both contain version strings, which the navigation bar treats differently.
The theme supports Bootstrap v2.3.2
and v3.3.7
via the
bootstrap_version
theme option (of "2"
or "3"
). Some notes
regarding version differences:
As a more “hands on” approach to customization, you can override any template
in this Sphinx theme or any others. A good candidate for changes is
“layout.html”, which provides most of the look and feel. First, take a look
at the “layout.html” file that the theme provides, and figure out
what you need to override. As a side note, we have some theme-specific
enhancements, such as the navbarextra
template block for additional
content in the navbar.
Then, create your own “_templates” directory and “layout.html” file (assuming you build from a “source” directory):
$ mkdir source/_templates
$ touch source/_templates/layout.html
Then, configure your “conf.py”:
templates_path = ['_templates']
Finally, edit your override file “source/_templates/layout.html”:
{# Import the theme's layout. #}
{% extends "!layout.html" %}
{# Add some extra stuff before and use existing with 'super()' call. #}
{% block footer %}
<h2>My footer of awesomeness.</h2>
{{ super() }}
{% endblock %}
Alternately, you could add your own custom static media directory with a CSS file to override a style, which in the demo would be something like:
$ mkdir source/_static
$ touch source/_static/my-styles.css
In the new file “source/_static/my-styles.css”, add any appropriate styling, e.g. a bold background color:
footer {
background-color: red;
}
Then, in “conf.py”, edit this line:
html_static_path = ["_static"]
From there it depends on which version of Sphinx you are using:
Sphinx <= 1.5
You will need the override template “source/_templates/layout.html” file configured as above, but with the following code:
{# Import the theme's layout. #}
{% extends "!layout.html" %}
{# Custom CSS overrides #}
{% set css_files = css_files + ['_static/my-styles.css'] %}
Note
See Issue #159 for more information.
Sphinx >= 1.6.1
Add a setup
function in “conf.py” with stylesheet paths added relative to the
static path:
def setup(app):
app.add_stylesheet("my-styles.css") # also can be a full URL
# app.add_stylesheet("ANOTHER.css")
# app.add_stylesheet("AND_ANOTHER.css")
Tip
Sphinx automatically calls your setup
function defined in “conf.py” during
the build process for you. There is no need to, nor should you, call this
function directly in your code.
The theme places the global TOC, local TOC, navigation (prev, next) and source links all in the top Bootstrap navigation bar, along with the Sphinx search bar on the left side.
The global (site-wide) table of contents is the “Site” navigation dropdown,
which is a configurable level rendering of the toctree
for the entire site.
The local (page-level) table of contents is the “Page” navigation dropdown,
which is a multi-level rendering of the current page’s toc
.
The theme offers Bootstrap v2.x and v3.x, both of which rely on
jQuery v.1.9.x. As the jQuery that Bootstrap wants can radically depart from
the jQuery Sphinx internal libraries use, the library from this theme is
integrated via noConflict()
as $jqTheme
.
You can override any static JS/CSS files by dropping different versions in your Sphinx “_static” directory.
Contributions to this project are most welcome. Please make sure that the demo site builds cleanly, and looks like what you want. First build the demo:
$ fab clean && fab demo
Then, view the site in the development server:
$ fab demo_server
Also, if you are adding a new type of styling or Sphinx or Bootstrap construct, please add a usage example to the “Examples” page.
Note: If you are in Python 3, Fabric isn’t available, so we have a very rough Makefile in its place. Try:
$ make clean && make demo
Then, view the site in the development server:
$ make demo_server
Sphinx Bootstrap Theme is licensed under the MIT license.
Bootstrap v2 is licensed under the Apache license 2.0.
Bootstrap v3.1.0+ is licensed under the MIT license.
Various examples of Bootstrap styling applied to Sphinx constructs. You can view the source of this page to see the specific reStructuredText used to create these examples.
This is a first level heading (h1
).
The Sphinx Bootstrap Theme uses Bootstrap styling for inline code text
and
multiline
code text
Here’s an included example with line numbers.
1 2 3 4 5 6 7 8 9 10 11 12 | """Sphinx bootstrap theme."""
import os
VERSION = (0, 6, 0)
__version__ = ".".join(str(v) for v in VERSION)
__version_full__ = __version__
def get_html_theme_path():
"""Return list of HTML theme paths."""
cur_dir = os.path.abspath(os.path.dirname(__file__))
return [cur_dir]
|
It also works with existing Sphinx highlighting:
<html>
<body>Hello World</body>
</html>
def hello():
"""Greet."""
return "Hello World"
/**
* Greet.
*/
function hello(): {
return "Hello World";
}
The Sphinx Bootstrap Theme uses the Bootstrap alert
classes for Sphinx
admonitions.
Note
This is a note.
Todo
This is a todo.
Warning
This is a warning.
Danger
This is danger-ous.
I have footnoted a first item [1] and second item [2]. This also references the second item [2].
Footnotes
[1] | My first footnote. |
[2] | (1, 2) My second footnote. |
Icons are different in Bootstrap 2 and 3, so you will only see an icon below for the version of Bootstrap that we used to build these docs.
The following template HTML:
<span class="icon-star-empty"></span>
translates to a neat star:
The following template HTML:
<span class="glyphicon glyphicon-star-empty"></span>
translates to a neat star:
Here are some examples of Sphinx
tables. The Sphinx Bootstrap
Theme removes all Sphinx docutils
classes and replaces them with the
default Bootstrap table
class. You can add additional table classes
using the Sphinx cssclass::
directive, as demonstrated in the following
tables.
A “bordered” grid table:
Header1 | Header2 | Header3 | Header4 |
---|---|---|---|
row1, cell1 | cell2 | cell3 | cell4 |
row2 … | … | … | |
… | … | … |
which uses the directive:
.. cssclass:: table-bordered
A simple “striped” table:
H1 | H2 | H3 |
---|---|---|
cell1 | cell2 | cell3 |
… | … | … |
… | … | … |
which uses the directive:
.. cssclass:: table-striped
And a “hoverable” table:
H1 | H2 | H3 |
---|---|---|
cell1 | cell2 | cell3 |
… | … | … |
… | … | … |
which uses the directive:
.. cssclass:: table-hover
An example Python function.
format_exception
(etype, value, tb[, limit=None])¶Format the exception with a traceback.
Parameters: |
|
---|---|
Return type: | list of strings |
An example JavaScript function.
MyAnimal
(name[, age])¶Arguments: |
|
---|
This page demonstrates the use of a simple navigation sidebar.
This is a first level heading (h1
).
… and now some Lorem text so that we can check scrolling
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Development history and feature wish lists.
bad release
@import url()
CSS imports to be relative paths so that you can have a
non-root / nested site.'navbar_fixed_top': "false"
and
'bootstrap_version': "2"
.
Fixes #121.
(@EricFromCanada).container
padding after Sphinx 1.3b commit overrode CSS.
Fixes #114.
(@EricFromCanada)theme_bootswatch_theme
by permissively allowing old (empty quotes) or
new (empty or None
) styles.
Fixes #115.
(@EricFromCanada, @peteut, @mdboom)fonts/
directories to bootswatch. (@gkthiruvathukal)<img>
tags for logos.
Fixes #52.navbar_links
theme option lost in bad merge. (@newgene)bootswatch_theme
option for Bootswatch
CSS theme support. (@zyga)globaltoc_includehidden
option.navbar_title
theme configuration. The documentation
originally stated that html_short_title
was supported for overriding the
navbar title (brand), but this never actually worked.
(Thanks to Tim Kedmenec for pointing this out).Site
nav button if no other pages.noConflict()
to allow underlying Sphinx to use
whatever jQuery it wants.code
elements.code
elements.globaltoc_depth
theme option.navbar_class
, source_link_position
.localtoc
from the top navigation bar into it’s own
navbar below the page title.When upgrading, you must upgrade both Bootstrap and Bootswatch — Bootswatch releases are custom tailored to the a specific version of Bootstrap. The version of jQuery (1.11) should be OK to leave as is unless a specific issue arises.
In the below examples we are upgrading to bootstrap 3.3.7; Bootstrap 2 versions should not have a need to be changed.
Get new bootstrap-VERSION
and drop in bootstrap/static
.
New versions should be available here.
Choose “Bootstrap”:
Compiled and minified CSS, JavaScript, and fonts. No docs or original source files are included.
Manually grep and replace instances of (jQuery)
with
(window.$jqTheme || window.jQuery)
in files in the new
bootstrap-VERSION/js
directory. See below.
Update VERSION
in sphinx_bootstrap_theme/bootstrap/layout.html
:
{% if theme_bootstrap_version == "3" %}
{% set bootstrap_version, navbar_version = "3.3.7", "" %}
{% set bs_span_prefix = "col-md-" %}
{% else %}
{% set bootstrap_version, navbar_version = "2.3.2", "-2" %}
{% set bs_span_prefix = "span" %}
{% endif %}
Update VERSION
in sphinx_bootstrap_theme/bootstrap/static/bootstrap-sphinx.css_t
{% if theme_bootstrap_version == "3" %}
{% set bootstrap_version, bootstrap_additional_css = "3.3.7", "theme" %}
{% else %}
{% set bootstrap_version, bootstrap_additional_css = "2.3.2", "responsive" %}
{% endif %}
Choose your favorite text replacement tool for step 2, we will use grep
and sed
.
The example here will be with the file bootstrap.js
for understandability (since it
is not minified).
# First, locate the all of the calls to jQuery
$ grep -Hn --color=auto '(jQuery)' bootstrap.js
bootstrap.js:17:}(jQuery);
bootstrap.js:77:}(jQuery);
bootstrap.js:172:}(jQuery);
bootstrap.js:298:}(jQuery);
bootstrap.js:536:}(jQuery);
bootstrap.js:749:}(jQuery);
bootstrap.js:915:}(jQuery);
bootstrap.js:1255:}(jQuery);
bootstrap.js:1776:}(jQuery);
bootstrap.js:1885:}(jQuery);
bootstrap.js:2058:}(jQuery);
bootstrap.js:2214:}(jQuery);
bootstrap.js:2377:}(jQuery);
# Make the replacement in-place while creating
# a bootstrap.js.bak file (backup of the original)
$ sed -i.bak 's/(jQuery)/(window.$jqTheme || window.jQuery)/g' bootstrap.js
# Verify there are no more (jQuery) left, and search our replacement
# for sanity checking (all the line numbers should match up)
$ grep -Hn --color=auto '(jQuery)' bootstrap.js
$ grep -Hn --color=auto '(window.$jqTheme || window.jQuery)' bootstrap.js
bootstrap.js:17:}(window.$jqTheme || window.jQuery);
bootstrap.js:77:}(window.$jqTheme || window.jQuery);
bootstrap.js:172:}(window.$jqTheme || window.jQuery);
bootstrap.js:298:}(window.$jqTheme || window.jQuery);
bootstrap.js:536:}(window.$jqTheme || window.jQuery);
bootstrap.js:749:}(window.$jqTheme || window.jQuery);
bootstrap.js:915:}(window.$jqTheme || window.jQuery);
bootstrap.js:1255:}(window.$jqTheme || window.jQuery);
bootstrap.js:1776:}(window.$jqTheme || window.jQuery);
bootstrap.js:1885:}(window.$jqTheme || window.jQuery);
bootstrap.js:2058:}(window.$jqTheme || window.jQuery);
bootstrap.js:2214:}(window.$jqTheme || window.jQuery);
bootstrap.js:2377:}(window.$jqTheme || window.jQuery);
# IMPORTANT! Check your work! Most of these were all in either
# comments or error strings (that we want to leave as is),
# but line 7 below needs to be updated!
#
# So line 7 should be changed (by you) to be
#
# if (typeof (window.$jqTheme || window.jQuery) === 'undefined') {
$ grep -Hn --color=auto 'jQuery' bootstrap.js
bootstrap.js:7:if (typeof jQuery === 'undefined') {
bootstrap.js:8: throw new Error('Bootstrap\'s JavaScript requires jQuery')
bootstrap.js:15: throw new Error('Bootstrap\'s JavaScript requires jQuery version 1.9.1 or higher, but lower than version 4')
bootstrap.js:17:}(window.$jqTheme || window.jQuery);
bootstrap.js:77:}(window.$jqTheme || window.jQuery);
bootstrap.js:172:}(window.$jqTheme || window.jQuery);
bootstrap.js:298:}(window.$jqTheme || window.jQuery);
bootstrap.js:536:}(window.$jqTheme || window.jQuery);
bootstrap.js:749:}(window.$jqTheme || window.jQuery);
bootstrap.js:915:}(window.$jqTheme || window.jQuery);
bootstrap.js:1255:}(window.$jqTheme || window.jQuery);
bootstrap.js:1260: * Inspired by the original jQuery.tipsy by Jason Frame
bootstrap.js:1624: // Avoid using $.offset() on SVGs since it gives incorrect results in jQuery 3.
bootstrap.js:1776:}(window.$jqTheme || window.jQuery);
bootstrap.js:1885:}(window.$jqTheme || window.jQuery);
bootstrap.js:2058:}(window.$jqTheme || window.jQuery);
bootstrap.js:2076: // jscs:disable requireDollarBeforejQueryAssignment
bootstrap.js:2078: // jscs:enable requireDollarBeforejQueryAssignment
bootstrap.js:2214:}(window.$jqTheme || window.jQuery);
bootstrap.js:2377:}(window.$jqTheme || window.jQuery);
# If all went according to plan, delete the backup
$ rm bootstrap.js.bak
In this example we will walk through how to create the necessary structure using version
3.3.7 of Bootswatch. When updating in the future, replace 3.3.7
in the below with
the version of Bootswatch you are upgrading to. Make sure that you are upgrading
to the same version as Bootstrap!
# Go to a familiar working location, we choose ~/Desktop for this example
$ cd ~/Desktop
# Download the source code for bootswatch
$ git clone https://github.com/thomaspark/bootswatch.git
$ cd bootswatch
# Checkout the tagged release (use `git tag -l` to see all options)
$ git checkout v3.3.7
# We need to package every "theme/bootstrap.min.css", as well as the
# fonts directory. In the below, we are using a clever hack to include
# the fonts directory by echoing it first so `tar` at the end will know
# to copy it. We then want to find all bootstrap.min.css files, but
# need to ignore three directories: "2", "custom", and "bower_components".
#
# NOTE: the `echo` and `find` commands **MUST** be (in the same parentheses)
#
# You should be able to copy-paste this _without_ the leading $
$ (echo "./fonts" && \
find . -name "bootstrap.min.css" \
-not -path "./2/*" \
-not -path "./bower_components/*" \
-not -path "./custom/*") | \
xargs tar -cf ~/Desktop/bootswatch-flat-3.3.7.tar
# Now that we've extracted the relevant files, add them to the
# sphinx_bootstrap_theme repo
$ cd /path/to/sphinx-bootstrap-theme/sphinx_bootstrap_theme/bootstrap/static
# Make the directory relevant to your bootswatch version and enter it;
# the archive we made is not self-contained
$ mkdir bootswatch-3.3.7
$ cd bootswatch-3.3.7
# Extract the archive we just created here
$ cat ~/Desktop/bootswatch-flat-3.3.7.tar | tar -x
# Make sure the themes you were expecting, **AND** the fonts directory are here
$ ls