HTML主题开发

Added in version 0.6.

备注

本文档提供有关创建自己的主题的信息。如果您只是想使用预先存在的HTML主题,请参阅 HTML主题 .

Sphinx支持更改其HTML输出的外观, themes . 主题是HTML模板、样式表和其他静态文件的集合。此外,它有一个配置文件,指定从哪个主题继承,使用哪种突出显示样式,以及存在哪些选项用于自定义主题的外观和感觉。

主题旨在不受项目影响,因此无需更改即可用于不同的项目。

备注

看到 SphinxAPI 了解可能有助于开发主题的更多信息。

创建主题

主题采用目录或zipfile(其名称为主题名称)的形式,包含以下内容:

  • 要么 theme.toml 文件(首选)或 theme.conf 文件.

  • 如果需要,HTML模板。

  • A static/ 包含任何将在生成时复制到输出静态目录的静态文件的目录。 这些可以是图像、样式、脚本文件。

主题配置 (theme.toml )

theme.toml 文件是一个 TOML 文档,包含两个表格: [theme][options] .

[theme] 表定义主题的设置:

  • inherit (字符串):要从中继承设置、选项、模板和静态文件的基本主题的名称。主题“祖先”中的所有静态文件都将被使用。该主题将使用继承主题中定义的所有选项。最后,继承的主题将用于定位缺失的模板(例如,如果 "basic" 用作基本主题,大多数模板都已经定义了)。

    如果设置为 "none" ,该主题不会继承任何其他主题。继承是循环的,形成一系列继承主题(例如 default -> classic -> basic -> none ).

  • stylesheets (list字符串):CSS文件名列表,将包含在生成的HTML标头中。设置 html_style 配置值将覆盖此设置。

    包含多个样式表的其他机制包括 @import 在CSS中或使用自定义HTML模板, <link rel="stylesheet"> 标签.

  • sidebars (list字符串):侧边栏模板列表。用户可以通过 html_sidebars 配置值。

  • pygments_style (表):一个TOML表,定义用于突出显示语法的Pygments样式的名称。该表格有两个可识别的键: defaultdark .中定义的风格 dark CSS媒体查询时将使用键 (prefers-color-scheme: dark) 评估为真。

    [theme.pygments_style.default] 用户可以通过 pygments_style 配置值。

[options] 表定义了主题的选项。它的结构使得每个关键字-值对对应于变量名称和相应的默认值。用户可以在中重写这些选项 html_theme_options 并且可以从所有模板访问, theme_<name> .

Added in version 7.3: theme.toml 支持.

示例性 theme.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.conf )

theme.conf 文件为INI格式 [1] (可由标准Python读取 configparser 模块)并具有以下结构:

[theme]
inherit = base theme
stylesheet = main CSS name
pygments_style = stylename
sidebars = localtoc.html, relations.html, sourcelink.html, searchbox.html

[options]
variable = default value
  • inherit 设置给出“基本主题”的名称,或者 none . 基本主题将用于定位缺失的模板(如果使用,大多数主题将不必提供大多数模板 basic 作为基本主题),它的选项将被继承,并且它的所有静态文件也将被使用。如果您还想继承样式表,请通过CSS包含它' @import 在你自己的。

  • stylesheet 设置给出了一个CSS文件名列表,以逗号分隔,这些文件将在HTML标头中引用。 您还可以使用CSS ' @import 将其中一个与另一个包含的技术,或使用添加的自定义HTML模板 <link rel="stylesheet"> 根据需要标记。 设置 html_style 配置值将覆盖此设置。

  • pygments_style 设置给出了用于突出显示的Pygments样式的名称。 用户可以在 pygments_style 配置值。

  • pygments_dark_style 设置给出了在CSS媒体查询时用于突出显示的Pygents样式的名称 (prefers-color-scheme: dark) 评估为真。它通过使用注入页面 add_css_file() .

  • sidebars 设置给出了用于构建边栏的边栏模板的逗号分隔列表。 用户可以在 html_sidebars 配置值。

  • options 部分包含变量名和默认值对。用户可以在中重写这些选项 html_theme_options 并且可以从所有模板访问, theme_<name> .

Added in version 1.7: 侧边栏设置

在 5.1 版本发生变更: 样式表设置接受多个CSS文件名

转换 theme.conftheme.toml

INI风格的主题配置文件 (theme.conf )可以通过随Sphinx一起分发的帮助程序转换为TOML。这仅供一次性使用,可能会在Sphinx的未来版本中删除,恕不另行通知。

$ python -m sphinx.theming conf_to_toml [THEME DIRECTORY PATH]

所需的参数是一个目录的路径,该目录包含 theme.conf 文件.该方案将编写一个 theme.toml 文件在同一个目录中,并不会修改原来的 theme.conf 文件.

Added in version 7.3.

将主题作为Python包分发

作为分发主题的一种方式,您可以使用Python包。 这使用户更容易设置主题。

要将主题分发为Python包,请定义名为的入口点 sphinx.html_themes 在你 pyproject.toml 文件,并编写 setup() 使用注册主题的功能 add_html_theme() API:

# pyproject.toml

[project.entry-points."sphinx.html_themes"]
name_of_theme = "your_theme_package"
# your_theme_package.py
from pathlib import Path

def setup(app):
    app.add_html_theme('name_of_theme', Path(__file__).resolve().parent)

如果您的主题包包含两个或两个以上的主题,请致电 add_html_theme() 两次或更多。

Added in version 1.2: “phinx_themes”entry_points功能。

自 1.6 版本弃用: sphinx_themes entry_points已被弃用。

Added in version 1.6: sphinx.html_themes entry_points功能。

使用CSS造型

stylesheets 设置可用于将自定义CSS文件添加到主题。

小心

HTML元素及其类的结构目前还不是一个定义良好的公共API。请通过检查构建的HTML页面来推断它们。虽然我们不能保证完全稳定,但它们往往相当稳定。

按类别设计搜索结果条目

Added in version 8.0.

备注

下面命名的CSS类由Sphinx的独立搜索代码生成。 如果您正在使用第三方搜索提供商,例如 ReadTheDocs, 为了提供搜索结果,可用的主题选项可能会有所不同。

搜索结果项具有指示搜索项所在上下文的类。您可以使用CSS选择器:

  • ul.search li.kind-index :对于索引中的结果,例如术语表

  • ul.search li.kind-object :对于源代码中的结果,例如Python函数定义

  • ul.search li.kind-title :对于部分标题中的结果

  • ul.search li.kind-text :对于文档文本中其他任何地方找到的结果

作为其他主题继承的基础, basic 主题是故意最小化的,并且不使用这些来定义CSS规则。鼓励衍生主题在他们认为合适的情况下使用这些选择器。例如,以下样式表将上下文图标添加到搜索结果列表中:

ul.search {
    padding-left: 30px;
}
ul.search li {
    padding: 5px 0 5px 10px;
    list-style-type: "\25A1";  /* Unicode: White Square */
}
ul.search li.kind-index {
    list-style-type: "\1F4D1";  /* Unicode: Bookmark Tabs */
}
ul.search li.kind-object {
    list-style-type: "\1F4E6";  /* Unicode: Package */
}
ul.search li.kind-title {
    list-style-type: "\1F4C4";  /* Unicode: Page Facing Up */
}
ul.search li.kind-text {
    list-style-type: "\1F4C4";  /* Unicode: Page Facing Up */
}

模板

guide to templating 如果您想编写自己的模板,这很有帮助。 重要的是要记住的是Sphinx搜索模板的顺序:

  • 首先,在用户的 templates_path 的目录

  • 然后,在选定的主题中。

  • 然后,在它的基本主题中,它的基本主题中,等等

在基主题中扩展同名模板时,请使用主题名称作为显式目录: {% extends "basic/layout.html" %} . 从用户 templates_path 模板,您仍然可以使用“感叹号”语法作为 described in the templating document .

静态模板

由于主题选项旨在让用户更轻松地配置主题,而无需编写自定义样式表,因此必须能够为静态文件和HTML文件模板。 因此,Sphinx支持所谓的“静态模板”,就像这样:

如果中的文件名称 static/ 主题的目录(或用户的静态路径中)以 .jinja_t ,它将由模板引擎处理。 后缀将从最终文件名中删除。

例如,具有 static/theme_styles.css.jinja 文件可以使用模板将选项放入样式表中。当使用该主题构建文档项目时,输出目录将包含 _static/theme_styles.css 已处理所有模板标签的文件。

在 7.4 版本发生变更:

静态模板的首选后缀现在是 .jinja ,与Jinja项目一致 recommended file extension .

_t 静态模板的文件后缀现在被认为是“遗留的”,并且支持最终可能会被删除。

如果静态模板具有 _t 后缀或a .jinja 如果检测到后缀,模板引擎将处理该后缀,并从最终文件名中删除该后缀。

在HTML模板中使用自定义页面元数据

中的任何键/值对 field lists 放置的 before 在中构建页面时,页面标题将可供Jinja模板使用 meta 属性例如,如果一个页面的第一个标题之前有以下文本:

:mykey: My value

My first title
--------------

然后可以在Jinja模板中访问它,如下所示:

{%- if meta is mapping %}
    {{ meta.get("mykey") }}
{%- endif %}

请注意检查 meta 是一本字典(Jinja术语中的“映射”),以确保以这种方式使用它是有效的。

定义自定义模板函数

有时,在Python中定义您自己的函数会很有用,然后您希望在模板中使用这些函数。例如,如果您想插入具有取决于项目中用户配置的逻辑的模板值,或者如果您想在模板中包含重要检查并提供友好的错误消息。

要定义您自己的模板函数,您需要在模块内定义两个函数:

  • A page context event handler (或 registration )功能。这与 Sphinx 通过事件回调应用程序。

  • A template function 您将在Jinja模板中使用它。

首先,定义注册函数,该函数接受参数 html-page-context .

在注册函数中,定义您想在Jinja中使用的模板函数。模板函数应该返回Jinja在模板化过程中使用的字符串或内部包含字符串的Python对象(列表、字典)

备注

模板函数将有权访问传递给注册函数的所有变量。

在注册函数的最后,将模板函数添加到Sphinx应用程序的上下文中, context['template_func'] = template_func .

最后,在您的扩展中 setup() 函数,添加您的注册函数作为回调 html-page-context .

# 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)

现在,您将可以在jinja中访问此功能,如下所示:

<div>
{{ my_func("some string") }}
</div>

将您自己的静态文件添加到构建资源

默认情况下,Sphinx复制 static/ 模板目录的目录。 但是,如果您的包需要将静态文件放置在 static/ 由于某些原因,您需要将它们复制到 _static/ 通过事件挂钩在构建时手动输出HTML目录。 以下是实现此功能的代码示例:

import shutil

def copy_custom_files(app, exc):
    if app.builder.format == 'html' and not exc:
        static_dir = app.outdir / '_static'
        shutil.copyfile('path/to/myextension/_static/myjsfile.js', static_dir)

def setup(app):
    app.connect('build-finished', copy_custom_files)

根据用户配置注入JavaScript

如果您的扩展使用JavaScript,则允许用户使用Sphinx配置控制其行为可能会很有用。然而,如果您的JavaScript采用静态库的形式(不会使用Jinja构建),这可能很难做到。

有两种方法可以根据用户配置将变量注入JavaScript空间。

首先,您可以添加 _t 到扩展名中包含的任何静态文件的末尾。这将导致Sphinx使用模板引擎处理这些文件,从而允许您嵌入变量并控制行为。

例如,以下JavaScript结构:

mymodule/
├── _static
│   └── myjsfile.js_t
└── mymodule.py

将导致以下静态文件放置在HTML的构建输出中:

_build/
└── html
    └── _static
        └── myjsfile.js

看到 静态模板 for more information.

其次,您可以使用 Sphinx.add_js_file() 方法,而不将其指向文件。通常,此方法用于将新的JavaScript文件插入您的网站。但如果 not 传递一个文件路径,而是传递一个字符串给“body”参数,那么这个文本将作为JavaScript插入到你的网站的头部。这允许您从Python将变量插入项目的JavaScript中。

例如,以下代码将读取用户配置的值,然后将此值作为JavaScript变量插入,您的扩展的JavaScript代码可能会用途:

# 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)

因此,在您的主题中,您可以使用取决于此变量是否存在的代码。用户可以通过在 conf.py 文件.