summaryrefslogtreecommitdiffstats
path: root/doc/development/theming.rst
diff options
context:
space:
mode:
Diffstat (limited to 'doc/development/theming.rst')
-rw-r--r--doc/development/theming.rst433
1 files changed, 0 insertions, 433 deletions
diff --git a/doc/development/theming.rst b/doc/development/theming.rst
deleted file mode 100644
index 13a5802..0000000
--- a/doc/development/theming.rst
+++ /dev/null
@@ -1,433 +0,0 @@
-HTML theme development
-======================
-
-.. versionadded:: 0.6
-
-.. note::
-
- This document provides information about creating your own theme. If you
- simply wish to use a pre-existing HTML themes, refer to
- :doc:`/usage/theming`.
-
-Sphinx supports changing the appearance of its HTML output via *themes*. A
-theme is a collection of HTML templates, stylesheet(s) and other static files.
-Additionally, it has a configuration file which specifies from which theme to
-inherit, which highlighting style to use, and what options exist for customizing
-the theme's look and feel.
-
-Themes are meant to be project-unaware, so they can be used for different
-projects without change.
-
-.. note::
-
- See :ref:`dev-extensions` for more information that may
- be helpful in developing themes.
-
-
-Creating themes
----------------
-
-Themes take the form of either a directory or a zipfile (whose name is the
-theme name), containing the following:
-
-* Either a :file:`theme.toml` file (preferred) or a :file:`theme.conf` file.
-* HTML templates, if needed.
-* A ``static/`` directory containing any static files that will be copied to the
- output static directory on build. These can be images, styles, script files.
-
-Theme configuration (``theme.toml``)
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The :file:`theme.toml` file is a TOML_ document,
-containing two tables: ``[theme]`` and ``[options]``.
-
-The ``[theme]`` table defines the theme's settings:
-
-* **inherit** (string): The name of the base theme from which to inherit
- settings, options, templates, and static files.
- All static files from theme 'ancestors' will be used.
- The theme will use all options defined in inherited themes.
- Finally, inherited themes will be used to locate missing templates
- (for example, if ``"basic"`` is used as the base theme, most templates will
- already be defined).
-
- If set to ``"none"``, the theme will not inherit from any other theme.
- Inheritance is recursive, forming a chain of inherited themes
- (e.g. ``default`` -> ``classic`` -> ``basic`` -> ``none``).
-
-* **stylesheets** (list of strings): A list of CSS filenames which will be
- included in generated HTML header.
- Setting the :confval:`html_style` config value will override this setting.
-
- Other mechanisms for including multiple stylesheets include ``@import`` in CSS
- or using a custom HTML template with appropriate ``<link rel="stylesheet">`` tags.
-
-* **sidebars** (list of strings): A list of sidebar templates.
- This can be overridden by the user via the :confval:`html_sidebars` config value.
-
-* **pygments_style** (table): A TOML table defining the names of Pygments styles
- to use for highlighting syntax.
- The table has two recognised keys: ``default`` and ``dark``.
- The style defined in the ``dark`` key will be used when
- the CSS media query ``(prefers-color-scheme: dark)`` evaluates to true.
-
- ``[theme.pygments_style.default]`` can be overridden by the user via the
- :confval:`pygments_style` config value.
-
-The ``[options]`` table defines the options for the theme.
-It is structured such that each key-value pair corresponds to a variable name
-and the corresponding default value.
-These options can be overridden by the user in :confval:`html_theme_options`
-and are accessible from all templates as ``theme_<name>``.
-
-.. versionadded:: 7.3
- ``theme.toml`` support.
-
-.. _TOML: https://toml.io/en/
-
-Exemplar :file:`theme.toml` file:
-
-.. code-block:: toml
-
- [theme]
- inherit = "basic"
- stylesheets = [
- "main-CSS-stylesheet.css",
- ]
- sidebars = [
- "localtoc.html",
- "relations.html",
- "sourcelink.html",
- "searchbox.html",
- ]
- # Style names from https://pygments.org/styles/
- pygments_style = { default = "style_name", dark = "dark_style" }
-
- [options]
- variable = "default value"
-
-Theme configuration (``theme.conf``)
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The :file:`theme.conf` file is in INI format [1]_ (readable by the standard
-Python :mod:`configparser` module) and has the following structure:
-
-.. sourcecode:: ini
-
- [theme]
- inherit = base theme
- stylesheet = main CSS name
- pygments_style = stylename
- sidebars = localtoc.html, relations.html, sourcelink.html, searchbox.html
-
- [options]
- variable = default value
-
-* The **inherit** setting gives the name of a "base theme", or ``none``. The
- base theme will be used to locate missing templates (most themes will not have
- to supply most templates if they use ``basic`` as the base theme), its options
- will be inherited, and all of its static files will be used as well. If you
- want to also inherit the stylesheet, include it via CSS' ``@import`` in your
- own.
-
-* The **stylesheet** setting gives a list of CSS filenames separated commas which
- will be referenced in the HTML header. You can also use CSS' ``@import``
- technique to include one from the other, or use a custom HTML template that
- adds ``<link rel="stylesheet">`` tags as necessary. Setting the
- :confval:`html_style` config value will override this setting.
-
-* The **pygments_style** setting gives the name of a Pygments style to use for
- highlighting. This can be overridden by the user in the
- :confval:`pygments_style` config value.
-
-* The **pygments_dark_style** setting gives the name of a Pygments style to use
- for highlighting when the CSS media query ``(prefers-color-scheme: dark)``
- evaluates to true. It is injected into the page using
- :meth:`~sphinx.application.Sphinx.add_css_file()`.
-
-* The **sidebars** setting gives the comma separated list of sidebar templates
- for constructing sidebars. This can be overridden by the user in the
- :confval:`html_sidebars` config value.
-
-* The **options** section contains pairs of variable names and default values.
- These options can be overridden by the user in :confval:`html_theme_options`
- and are accessible from all templates as ``theme_<name>``.
-
-.. versionadded:: 1.7
- sidebar settings
-
-.. versionchanged:: 5.1
-
- The stylesheet setting accepts multiple CSS filenames
-
-Convert ``theme.conf`` to ``theme.toml``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-INI-style theme configuration files (``theme.conf``) can be converted to TOML
-via a helper programme distributed with Sphinx.
-This is intended for one-time use, and may be removed without notice in a future
-version of Sphinx.
-
-.. code-block:: console
-
- $ python -m sphinx.theming conf_to_toml [THEME DIRECTORY PATH]
-
-The required argument is a path to a directory containing a ``theme.conf`` file.
-The programme will write a ``theme.toml`` file in the same directory,
-and will not modify the original ``theme.conf`` file.
-
-.. versionadded:: 7.3
-
-.. _distribute-your-theme:
-
-Distribute your theme as a Python package
------------------------------------------
-
-As a way to distribute your theme, you can use a Python package. This makes it
-easier for users to set up your theme.
-
-To distribute your theme as a Python package, please define an entry point
-called ``sphinx.html_themes`` in your ``pyproject.toml`` file,
-and write a ``setup()`` function to register your theme
-using the :meth:`~sphinx.application.Sphinx.add_html_theme` API:
-
-.. code-block:: toml
-
- # pyproject.toml
-
- [project.entry-points."sphinx.html_themes"]
- name_of_theme = "your_theme_package"
-
-.. code-block:: python
-
- # your_theme_package.py
- from os import path
-
- def setup(app):
- app.add_html_theme('name_of_theme', path.abspath(path.dirname(__file__)))
-
-If your theme package contains two or more themes, please call
-``add_html_theme()`` twice or more.
-
-.. versionadded:: 1.2
- 'sphinx_themes' entry_points feature.
-
-.. deprecated:: 1.6
- ``sphinx_themes`` entry_points has been deprecated.
-
-.. versionadded:: 1.6
- ``sphinx.html_themes`` entry_points feature.
-
-
-Templating
-----------
-
-The :doc:`guide to templating <templating>` is helpful if you want to write your
-own templates. What is important to keep in mind is the order in which Sphinx
-searches for templates:
-
-* First, in the user's ``templates_path`` directories.
-* Then, in the selected theme.
-* Then, in its base theme, its base's base theme, etc.
-
-When extending a template in the base theme with the same name, use the theme
-name as an explicit directory: ``{% extends "basic/layout.html" %}``. From a
-user ``templates_path`` template, you can still use the "exclamation mark"
-syntax as :ref:`described in the templating document <templating-primer>`.
-
-
-.. _theming-static-templates:
-
-Static templates
-~~~~~~~~~~~~~~~~
-
-Since theme options are meant for the user to configure a theme more easily,
-without having to write a custom stylesheet, it is necessary to be able to
-template static files as well as HTML files. Therefore, Sphinx supports
-so-called "static templates", like this:
-
-If the name of a file in the ``static/`` directory of a theme (or in the user's
-static path, for that matter) ends with ``_t``, it will be processed by the
-template engine. The ``_t`` will be left from the final file name. For
-example, the *classic* theme has a file ``static/classic.css_t`` which uses
-templating to put the color options into the stylesheet. When a documentation
-project is built with the classic theme, the output directory will contain a
-``_static/classic.css`` file where all template tags have been processed.
-
-
-Use custom page metadata in HTML templates
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Any key / value pairs in :doc:`field lists </usage/restructuredtext/field-lists>`
-that are placed *before* the page's title will be available to the Jinja
-template when building the page within the :data:`meta` attribute. For example,
-if a page had the following text before its first title:
-
-.. code-block:: rst
-
- :mykey: My value
-
- My first title
- --------------
-
-Then it could be accessed within a Jinja template like so:
-
-.. code-block:: jinja
-
- {%- if meta is mapping %}
- {{ meta.get("mykey") }}
- {%- endif %}
-
-Note the check that ``meta`` is a dictionary ("mapping" in Jinja
-terminology) to ensure that using it in this way is valid.
-
-
-Defining custom template functions
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Sometimes it is useful to define your own function in Python that you wish to
-then use in a template. For example, if you'd like to insert a template value
-with logic that depends on the user's configuration in the project, or if you'd
-like to include non-trivial checks and provide friendly error messages for
-incorrect configuration in the template.
-
-To define your own template function, you'll need to define two functions
-inside your module:
-
-* A **page context event handler** (or **registration**) function. This is
- connected to the :class:`.Sphinx` application via an event callback.
-* A **template function** that you will use in your Jinja template.
-
-First, define the registration function, which accepts the arguments for
-:event:`html-page-context`.
-
-Within the registration function, define the template function that you'd like to
-use within Jinja. The template function should return a string or Python objects
-(lists, dictionaries) with strings inside that Jinja uses in the templating process
-
-.. note::
-
- The template function will have access to all of the variables that
- are passed to the registration function.
-
-At the end of the registration function, add the template function to the
-Sphinx application's context with ``context['template_func'] = template_func``.
-
-Finally, in your extension's ``setup()`` function, add your registration
-function as a callback for :event:`html-page-context`.
-
-.. code-block:: python
-
- # The registration function
- def setup_my_func(app, pagename, templatename, context, doctree):
- # The template function
- def my_func(mystring):
- return "Your string is %s" % mystring
- # Add it to the page's context
- context['my_func'] = my_func
-
- # Your extension's setup function
- def setup(app):
- app.connect("html-page-context", setup_my_func)
-
-Now, you will have access to this function in jinja like so:
-
-.. code-block:: jinja
-
- <div>
- {{ my_func("some string") }}
- </div>
-
-
-Add your own static files to the build assets
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-By default, Sphinx copies static files on the ``static/`` directory of the template
-directory. However, if your package needs to place static files outside of the
-``static/`` directory for some reasons, you need to copy them to the ``_static/``
-directory of HTML outputs manually at the build via an event hook. Here is an
-example of code to accomplish this:
-
-.. code-block:: python
-
- from os import path
- from sphinx.util.fileutil import copy_asset_file
-
- def copy_custom_files(app, exc):
- if app.builder.format == 'html' and not exc:
- staticdir = path.join(app.builder.outdir, '_static')
- copy_asset_file('path/to/myextension/_static/myjsfile.js', staticdir)
-
- def setup(app):
- app.connect('build-finished', copy_custom_files)
-
-
-Inject JavaScript based on user configuration
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-If your extension makes use of JavaScript, it can be useful to allow users
-to control its behavior using their Sphinx configuration. However, this can
-be difficult to do if your JavaScript comes in the form of a static library
-(which will not be built with Jinja).
-
-There are two ways to inject variables into the JavaScript space based on user
-configuration.
-
-First, you may append ``_t`` to the end of any static files included with your
-extension. This will cause Sphinx to process these files with the templating
-engine, allowing you to embed variables and control behavior.
-
-For example, the following JavaScript structure:
-
-.. code-block:: none
-
- mymodule/
- ├── _static
- │   └── myjsfile.js_t
- └── mymodule.py
-
-Will result in the following static file placed in your HTML's build output:
-
-.. code-block:: none
-
- _build/
- └── html
- └── _static
-    └── myjsfile.js
-
-See :ref:`theming-static-templates` for more information.
-
-Second, you may use the :meth:`.Sphinx.add_js_file` method without pointing it
-to a file. Normally, this method is used to insert a new JavaScript file
-into your site. However, if you do *not* pass a file path, but instead pass
-a string to the "body" argument, then this text will be inserted as JavaScript
-into your site's head. This allows you to insert variables into your project's
-JavaScript from Python.
-
-For example, the following code will read in a user-configured value and then
-insert this value as a JavaScript variable, which your extension's JavaScript
-code may use:
-
-.. code-block:: python
-
- # This function reads in a variable and inserts it into JavaScript
- def add_js_variable(app):
- # This is a configuration that you've specified for users in `conf.py`
- js_variable = app.config['my_javascript_variable']
- js_text = "var my_variable = '%s';" % js_variable
- app.add_js_file(None, body=js_text)
- # We connect this function to the step after the builder is initialized
- def setup(app):
- # Tell Sphinx about this configuration variable
- app.add_config_value('my_javascript_variable', 0, 'html')
- # Run the function after the builder is initialized
- app.connect('builder-inited', add_js_variable)
-
-As a result, in your theme you can use code that depends on the presence of
-this variable. Users can control the variable's value by defining it in their
-:file:`conf.py` file.
-
-
-.. [1] It is not an executable Python file, as opposed to :file:`conf.py`,
- because that would pose an unnecessary security risk if themes are
- shared.