Customization
=============

If you want to go beyond :doc:`configuration`, you've come to the right page!


Custom CSS files
----------------

Adding your own CSS files is very easy.
Just add their file names to :confval:`html_css_files`
and make sure they are living in a directory
that's part of :confval:`html_static_path`.

For example, if the path to your CSS file is :file:`_static/funky.css`
(relative to your :file:`conf.py`), you can use something like this:

.. code-block:: python

    html_css_files = ['funky.css']
    html_static_path = ['_static']


Custom JavaScript Files
-----------------------

Similarly, you can add JavaScript files located in the
:confval:`html_static_path` by adding their paths to :confval:`html_js_files`.


Custom Templates
----------------

Each HTML page generated by Sphinx is pieced together from multiple components,
called *templates*.
You can create your own templates in order to customize certain parts.
All your templates must live in a directory that's part of the
:confval:`templates_path` (or a sub-directory thereof).

.. code-block:: python

    templates_path = ['_templates']

Some parts of the generated pages are just lists of templates,
namely :confval:`html_sidebars`,
:theme-option:`left_buttons` and
:theme-option:`right_buttons`.
You can create arbitrary new files and add them to those lists.

You can also extend (or completely replace) existing templates
(:gh-template:`layout.html`, :gh-template:`page.html`,
:gh-template:`footer.html` etc.).
For example, you can extend the template :gh-template:`layout.html`
by creating your own file named :file:`layout.html`:

.. code-block:: html+jinja
    :name: layout-html
    :caption: :file:`_templates/layout.html`

    {% extends "!layout.html" %}

    {% block htmltitle %}
    <title>Best docs ever!</title>
    {% endblock %}

    {% block relbar1 %}{% endblock %}

    {% block relbar2 %}{% endblock %}

    {% block comments %}
    <!-- embed some comment service here -->
    {% endblock %}

    {% block footer %}
    {{ super() }}
    <!-- embed some analytics service here -->
    {% endblock %}

The ``relbar1`` and ``relbar2`` blocks are used to overwrite
the previous/next links at the top and bottom of each page, respectively.

Use ``{{ super() }}`` to include the contents of the original block.
Otherwise, the contents are overwritten.

If you don't use the ``extends`` tag,
you can completely replace a given template.
By leaving the file empty, you can disable a template.

For example, if the setting :confval:`copyright` is not flexible enough
(because it inserts a "copyright" symbol which may not be desired),
one could create a customized note by replacing the existing template
:gh-template:`copyright.html`:

.. code-block:: html+jinja
    :name: copyright-html
    :caption: :file:`_templates/copyright.html`

    Dedicated to the public domain with
    <a href="https://creativecommons.org/publicdomain/zero/1.0/"
       class="reference external">CC0 1.0</a>.

For further information, see :ref:`sphinx:templating`.


Custom SVG Icons
----------------

The :gh-template:`icons` used by the ``insipid`` theme are templates as well.
Their content is copied into the generated HTML files.

You can replace icons the same way as any other template.
For example, to replace the :file:`icons/menu.svg` icon,
simply store a new SVG file at :file:`_templates/icons/menu.svg`.

To include the contents of an SVG file in your own HTML template,
use the ``include`` tag, e.g.:

.. code-block:: html+jinja

    <a href="https://mastodon.online/@...">
      {% include 'icons/mastodon.svg' %}
    </a>

Derive Your Own Theme
---------------------

If you want to re-use your custom templates in multiple Sphinx projects,
you can create your own theme derived from the ``insipid`` theme
(you can of course also derive from any other theme, if you prefer!).

For all the details, have a look at :doc:`sphinx:usage/theming`.
Here, we'll just give a quick summary.

You should create a directory named after your theme,
containing all your custom templates.

.. note::

    .. compound::

        You'll have to change your templates from using

        .. code-block:: html+jinja

            {% extends "!layout.html" %}

        to using

        .. code-block:: html+jinja

            {% extends "insipid/layout.html" %}

In the same directory,
you'll also have to create a file named :file:`theme.conf`
with a content similar to this:

.. code-block:: ini
    :name: derived-theme-conf
    :caption: Starting point for your own :file:`theme.conf`

    [theme]
    inherit = insipid
    stylesheet = ???.css
    sidebars = ???.html, ???.html, ???.html
    pygments_style = ???

    [options]
    left_buttons = ???.html, ???.html
    right_buttons = ???.html

    breadcrumbs = true

    your_own_option1 = 4em
    your_own_option2 = true

    # and so on and so on ...

Everything except ``inherit`` is optional
(and even that can be set to ``none``
if you insist on not deriving from any theme).

You should also create a sub-directory named :file:`static`
containing your main CSS file (and probably additional CSS files)
and any custom JavaScript files you want to use.
Write the name of your main CSS file to the ``stylesheet`` field in your
:file:`theme.conf`.
Remove the ``stylesheet`` field if you don't want to use your own CSS file.

By default, the CSS file :file:`insipid.css` will *not* be included,
but :file:`basic.css` and :file:`insipid-sidebar-readthedocs.css`
will be included.

To include :file:`insipid.css`, add this to your :file:`layout.html` template:

.. code-block:: html+jinja

    {% extends "insipid/layout.html" %}

    {% block css %}
        <link rel="stylesheet" href="{{ pathto('_static/insipid.css', 1) }}" type="text/css" />
    {{ super() }}
    {% endblock %}

Similarly, you can add further custom CSS files, if you want.

.. note::

    You *could* alternatively use  this in your CSS file:

    .. code-block:: css

        @import 'insipid.css';

    But this will increase the load time of the HTML pages!

If you want to use custom JavaScript files,
store them in the :file:`static` sub-directory of your theme directory
(they will automatically be copied into the :file:`_static` sub-directory
of the HTML output directory)
and add something like this to your :file:`layout.html` template:

.. code-block:: html+jinja

    {% block scripts %}
    {{ super() }}
        <script defer src="{{ pathto('_static/my-script.js', 1) }}"></script>
    {% endblock %}

If you want your JavaScript code to be available during page load,
drop the ``defer`` flag.

For more information and inspiration,
have a look at the ``insipid`` theme's sources
and at the aforementioned :doc:`sphinx:usage/theming` page.
