* Add support for theme options.

* Make the right-/stickysidebar alternatives for the default design options.
* Add theme-related options to quickstart.
This commit is contained in:
Georg Brandl 2009-02-15 01:43:10 +01:00
parent 2d62179bb0
commit 25b71e4143
12 changed files with 84 additions and 23 deletions

View File

@ -1,8 +1,8 @@
{% extends "!layout.html" %}
{% block rootrellink %}
<li><a href="{{ pathto('index') }}">Sphinx home </a> |&nbsp;</li>
<li><a href="{{ pathto('contents') }}">Documentation </a> &raquo;</li>
<li><a href="{{ pathto('index') }}">Sphinx home</a> &nbsp;|&nbsp;</li>
<li><a href="{{ pathto('contents') }}">Documentation</a>&nbsp;&raquo;</li>
{% endblock %}
{% block header %}

View File

@ -179,6 +179,9 @@ class StandaloneHTMLBuilder(Builder):
logo = logo,
favicon = favicon,
)
self.globalcontext.update(
('theme_' + key, val) for (key, val) in
self.theme.get_options(self.config.html_theme_options).iteritems())
self.globalcontext.update(self.config.html_context)
def _get_local_toctree(self, docname):

View File

@ -58,6 +58,7 @@ class Config(object):
# HTML options
html_theme = ('default', False),
html_theme_path = ([], False),
html_theme_options = ({}, False),
html_title = (lambda self: '%s v%s documentation' %
(self.project, self.release),
False),

View File

@ -18,6 +18,12 @@ from sphinx.util import mtimes_of_files
from sphinx.application import TemplateBridge
def _tobool(val):
if isinstance(val, basestring):
return val.lower() in ('true', '1', 'yes', 'on')
return bool(val)
class BuiltinTemplateLoader(TemplateBridge, jinja2.BaseLoader):
"""
Interfaces the rendering environment of jinja2 for use in Sphinx.
@ -38,6 +44,8 @@ class BuiltinTemplateLoader(TemplateBridge, jinja2.BaseLoader):
chain[0:0] = [path.join(builder.confdir, tp)
for tp in builder.config.templates_path]
self.pathchain = chain
# make the paths into loaders
self.loaders = map(jinja2.FileSystemLoader, chain)
@ -45,6 +53,7 @@ class BuiltinTemplateLoader(TemplateBridge, jinja2.BaseLoader):
extensions = use_i18n and ['jinja2.ext.i18n'] or []
self.environment = jinja2.Environment(loader=self,
extensions=extensions)
self.environment.filters['tobool'] = _tobool
if use_i18n:
self.environment.install_gettext_translations(builder.translator)
@ -52,7 +61,7 @@ class BuiltinTemplateLoader(TemplateBridge, jinja2.BaseLoader):
return self.environment.get_template(template).render(context)
def newest_template_mtime(self):
return max(mtimes_of_files(self.theme.get_dirchain(), '.html'))
return max(mtimes_of_files(self.pathchain, '.html'))
# Loader interface

View File

@ -114,10 +114,17 @@ pygments_style = 'sphinx'
# -- Options for HTML output ---------------------------------------------------
# The style sheet to use for HTML and HTML Help pages. A file of that name
# must exist either in Sphinx' static/ path, or in one of the custom paths
# given in html_static_path.
html_style = 'default.css'
# The theme to use for HTML and HTML Help pages. Major themes that come with
# Sphinx are currently 'default' and 'sphinxdoc'.
html_theme = 'default'
# 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
# documentation.
#html_theme_options = {}
# Add any paths that contain custom themes here, relative to this directory.
#html_theme_path = []
# The name for this set of Sphinx documents. If None, it defaults to
# "<project> v<release> documentation".

View File

@ -27,7 +27,7 @@
{%- endmacro %}
{%- macro sidebar() %}
{%- if not embedded %}
{%- if not embedded %}{% if not theme_nosidebar|tobool %}
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
{%- block sidebarlogo %}
@ -86,7 +86,7 @@
{%- endblock %}
</div>
</div>
{%- endif %}
{%- endif %}{% endif %}
{%- endmacro %}
<html xmlns="http://www.w3.org/1999/xhtml">
@ -155,15 +155,15 @@
{%- block document %}
<div class="document">
<div class="documentwrapper">
{%- if not embedded %}
{%- if not embedded %}{% if not theme_nosidebar|tobool %}
<div class="bodywrapper">
{%- endif %}
{%- endif %}{% endif %}
<div class="body">
{% block body %} {% endblock %}
</div>
{%- if not embedded %}
{%- if not embedded %}{% if not theme_nosidebar|tobool %}
</div>
{%- endif %}
{%- endif %}{% endif %}
</div>
{%- endblock %}

View File

@ -2,3 +2,6 @@
inherit = none
stylesheet = basic.css
pygments_style = none
[options]
nosidebar = false

View File

@ -0,0 +1,12 @@
{% extends "basic/layout.html" %}
{% block extrahead %}
{%- if theme_rightsidebar|tobool %}
<link rel="stylesheet" href="{{ pathto('_static/rightsidebar.css', 1) }}"
type="text/css" />
{%- endif %}
{%- if theme_stickysidebar|tobool %}
<link rel="stylesheet" href="{{ pathto('_static/stickysidebar.css', 1) }}"
type="text/css" />
{%- endif %}
{{ super() }}
{% endblock %}

View File

@ -1,10 +1,8 @@
/**
* Sphinx Doc Design -- Right Side Bar Overrides
*/
/* rightsidebar overrides for default design */
div.sphinxsidebar {
float: right;
right: 0; /* for sticky sidebar */
}
div.bodywrapper {

View File

@ -1,15 +1,17 @@
/**
* Sphinx Doc Design -- Sticky sidebar Overrides
*/
/* stickysidebar overrides for default design */
div.sphinxsidebar {
top: 30px;
left: 0px;
height: 100%;
overflow: auto;
position: fixed;
margin: 0;
float: none;
background-color: #1c4e63;
}
/* this is nice, but it it leads to hidden headings when jumping
to an anchor */
/*
div.related {
position: fixed;
}
@ -17,3 +19,4 @@ div.related {
div.documentwrapper {
margin-top: 30px;
}
*/

View File

@ -2,3 +2,7 @@
inherit = basic
stylesheet = default.css
pygments_style = sphinx
[options]
rightsidebar = false
stickysidebar = false

View File

@ -108,7 +108,7 @@ class Theme(object):
"""
try:
return self.themeconf.get(section, name)
except ConfigParser.NoOptionError:
except (ConfigParser.NoOptionError, ConfigParser.NoSectionError):
if self.base is not None:
return self.base.get_confstr(section, name)
if default is NODEFAULT:
@ -117,6 +117,27 @@ class Theme(object):
else:
return default
def get_options(self, overrides):
"""
Return a dictionary of theme options and their values.
"""
chain = [self.themeconf]
base = self.base
while base is not None:
chain.append(base.themeconf)
base = base.base
options = {}
for conf in reversed(chain):
try:
options.update(conf.items('options'))
except ConfigParser.NoSectionError:
pass
for option, value in overrides.iteritems():
if option not in options:
raise ThemeError('unsupported theme option %r given' % option)
options[option] = value
return options
def get_dirchain(self):
"""
Return a list of theme directories, beginning with this theme's,