テーマの開発

カスタムテーマの作成と配布に関するガイドです。


注意

既存のサードパーティ製のテーマをお探しであれば、コミュニティWikiページとMkDocsプロジェクトカタログに一覧があります。作成したテーマを共有したい場合は、そこに掲載してください。

新しいテーマを作成する際には、このガイドの手順に従ってゼロから作成するか、必要なすべてのボイラープレートを含む基本的な完全なテーマとしてmkdocs-basic-themeをダウンロードできます。**この基本テーマはGitHubにあります。**コードには、さまざまな機能とその使用方法を説明する詳細なコメントが含まれています。

カスタムテーマの作成

カスタムテーマに必要な最小限のものは、Jinja2テンプレートファイルであるmain.htmlです。これは、docs_dirの子ディレクトリではないディレクトリに配置されます。mkdocs.yml内で、main.htmlを含むディレクトリのパスにtheme.custom_dirオプションを設定します。パスは設定ファイルからの相対パスである必要があります。たとえば、次の例プロジェクトレイアウトの場合

mkdocs.yml
docs/
    index.md
    about.md
custom_theme/
    main.html
    ...

…カスタムテーマディレクトリを使用するには、mkdocs.ymlに次の設定を含めます。

theme:
  name: null
  custom_dir: 'custom_theme/'

注意

一般的に、独自のカスタムテーマを構築する際には、theme.name設定はnullに設定されます。ただし、theme.custom_dir設定値を既存のテーマと組み合わせて使用する場合、theme.custom_dirを使用して、組み込みテーマの特定の部分のみを置き換えることができます。たとえば、上記のレイアウトでname: "mkdocs"と設定した場合、theme.custom_dir内のmain.htmlファイルはmkdocsテーマ内の同じ名前のファイルを置き換えますが、それ以外はmkdocsテーマは変更されません。これは、既存のテーマに小さな調整を加えたい場合に役立ちます。

詳細については、テーマのカスタマイズを参照してください。

警告

mkdocs_theme.ymlファイルで定義されているテーマの設定は、theme.custom_dirからは読み込まれません。theme.custom_dirにテーマ全体が存在し、theme.namenullに設定されている場合、テーマの設定全体をmkdocs.ymlファイルのtheme設定オプションで定義する必要があります。

ただし、テーマがパッケージ化されて配布用になり、theme.name設定オプションを使用してロードされる場合、テーマにはmkdocs_theme.ymlファイルが必要です。

基本テーマ

最も単純なmain.htmlファイルは次のとおりです。

<!DOCTYPE html>
<html>
  <head>
    <title>{% if page.title %}{{ page.title }} - {% endif %}{{ config.site_name }}</title>
    {%- for path in config.extra_css %}
      <link href="{{ path | url }}" rel="stylesheet">
    {%- endfor %}
  </head>
  <body>
    {{ page.content }}

    {%- for script in config.extra_javascript %}
      {{ script | script_tag }}
    {%- endfor %}
  </body>
</html>

mkdocs.ymlで指定された各ページの本文の内容は、{{ page.content }}タグを使用して挿入されます。スタイルシートとスクリプトは、通常のHTMLファイルと同様にこのテーマに組み込むことができます。ナビゲーションバーと目次も、それぞれnavオブジェクトとtocオブジェクトを通じて自動的に生成して含めることができます。独自のテーマを作成する場合は、組み込みテーマのいずれかから始めて、それに応じて変更することをお勧めします。

注意

MkDocsはJinjaをテンプレートエンジンとして使用しているため、テンプレート継承を含むJinjaのすべての機能を使用できます。MkDocsに含まれるテーマは、テンプレート継承とブロックを多用していることに気付くかもしれません。これにより、ユーザーはテーマcustom_dirからテンプレートの小さな部分を簡単に上書きできます。そのため、組み込みテーマはbase.htmlファイルで実装され、main.htmlがそれを拡張します。必須ではありませんが、サードパーティのテンプレート作成者は同様のパターンに従うことが推奨され、一貫性のために組み込みテーマで使用されているのと同じブロックを定義したい場合があります。

設定からのCSSとJavaScriptの取得

MkDocsは最上位レベルのextra_cssextra_javascript設定を定義します。これらはファイルのリストです。

テーマには、これらの設定からの項目をリンクするHTMLを含める必要があります。そうでなければ、設定は機能しません。上記の基本例では、両方をレンダリングする推奨方法を確認できます。

バージョン1.5での変更

config.extra_javascriptリストの項目は、以前は単純な文字列でしたが、現在はpathtypeasyncdeferフィールドを持つオブジェクトになりました。

そのバージョンでは、MkDocsはscript_tagフィルタも獲得しました。

古いスタイル
  {%- for path in extra_javascript %}
    <script src="{{ path }}"></script>
  {%- endfor %}

この古いスタイルの例では、廃止された最上位レベルのextra_javascriptリストも使用されています。常にconfig.extra_javascriptを使用してください。

そのため、少し最新の方法は次のとおりですが、スクリプトの追加属性を無視するため、まだ廃止されています。

  {%- for path in config.extra_javascript %}
    <script src="{{ path | url }}"></script>
  {%- endfor %}
? 例:**新しいスタイル:**

  {%- for script in config.extra_javascript %}
    {{ script | script_tag }}
  {%- endfor %}

古いバージョンのMkDocsとの互換性を維持しながら、新しいカスタマイズを取り込みたい場合は、このスニペットを使用してください。

下位互換性のあるスタイル
  {%- for script in config.extra_javascript %}
    {%- if script.path %}  {# Detected MkDocs 1.5+ which has `script.path` and `script_tag` #}
      {{ script | script_tag }}
    {%- else %}  {# Fallback - examine the file name directly #}
      <script src="{{ script | url }}"{% if script.endswith(".mjs") %} type="module"{% endif %}></script>
    {%- endif %}
  {%- endfor %}

テーマファイル

テーマが何らかの方法で特別に扱うさまざまなファイルがあります。その他のファイルは、サイトが構築されると、テーマディレクトリからsite_dirの同じパスに単純にコピーされます。たとえば、画像ファイルやCSSファイルは特別な意味を持たず、そのままコピーされます。ただし、ユーザーがdocs_dirに同じパスのファイルを提供した場合、ユーザーのファイルがテーマファイルを置き換えます。

テンプレートファイル

.html拡張子のファイルは、テンプレートファイルと見なされ、テーマディレクトリまたはそのサブディレクトリからコピーされません。static_templatesにリストされているファイルも、ファイル拡張子に関係なくテンプレートとして扱われます。

テーマメタファイル

テーマのパッケージ化に必要なさまざまなファイルも無視されます。具体的には、mkdocs_theme.yml設定ファイルとPythonファイルです。

ドットファイル

テーマ作成者は、ファイル名またはディレクトリ名をドットで始めることで、MkDocsが明示的にファイルを無視するように強制できます。次のファイルは無視されます。

.ignored.txt
.ignored/file.txt
foo/.ignored.txt
foo/.ignored/file.txt

ドキュメントファイル

すべてのドキュメントファイルは無視されます。具体的には、MKDocsでサポートされているファイル拡張子を使用するすべてのMarkdownファイルです。さらに、テーマディレクトリに存在する可能性のあるREADMEファイルも無視されます。

テンプレート変数

テーマの各テンプレートは、テンプレートコンテキストを使用して構築されます。これらは、テーマで使用できる変数です。コンテキストは、構築されているテンプレートによって異なります。現時点では、テンプレートはグローバルコンテキストまたはページ固有のコンテキストを使用して構築されます。グローバルコンテキストは、個々のMarkdownドキュメントを表さないHTMLページ(たとえば、404.htmlページやsearch.html)に使用されます。

グローバルコンテキスト

次の変数は、すべてのテンプレートでグローバルに使用できます。

config

config変数は、mkdocs.yml設定ファイルから生成されたMkDocsの設定オブジェクトのインスタンスです。任意の設定オプションを使用できますが、一般的に使用されるオプションには次のものがあります。

nav変数は、ドキュメントのナビゲーションを作成するために使用されます。navオブジェクトは、nav設定で定義されているナビゲーションオブジェクトのイテラブルです。

ナビゲーションオブジェクトのイテラブルに加えて、navオブジェクトには次の属性が含まれています。

homepage: Page | None instance-attribute

サイトのホームページのpageオブジェクトです。

pages: list[Page] instance-attribute

ナビゲーションに含まれるすべてのpageオブジェクトのフラットリストです。

このリストは、ナビゲーションに含まれていないページを含まないため、必ずしもすべてのサイトページの完全なリストではありません。このリストは、「次のページ」と「前のページ」のすべてのリンクに使用されるページのリストと順序と一致します。すべてのページのリストについては、pagesテンプレート変数を使用してください。

以下は、1レベル目と2レベル目のナビゲーションをネストされたリストとして出力する基本的な使用方法の例です。

{% if nav|length > 1 %}
    <ul>
    {% for nav_item in nav %}
        {% if nav_item.children %}
            <li>{{ nav_item.title }}
                <ul>
                {% for nav_item in nav_item.children %}
                    <li class="{% if nav_item.active %}current{% endif %}">
                        <a href="{{ nav_item.url|url }}">{{ nav_item.title }}</a>
                    </li>
                {% endfor %}
                </ul>
            </li>
        {% else %}
            <li class="{% if nav_item.active %}current{% endif %}">
                <a href="{{ nav_item.url|url }}">{{ nav_item.title }}</a>
            </li>
        {% endif %}
    {% endfor %}
    </ul>
{% endif %}

base_url

base_urlは、MkDocsプロジェクトのルートへの相対パスを提供します。これは、ローカルの相対URLの前に付けることで直接使用できますが、base_urlを適用する方法がよりスマートなurlテンプレートフィルタを使用することをお勧めします。

mkdocs_version

現在のMkDocsバージョンを含みます。

build_date_utc

ドキュメントがUTCで構築された日付と時刻を表すPythonのdatetimeオブジェクトです。これは、ドキュメントが最近更新されたことを示すのに役立ちます。

pages

プロジェクトのすべてのページのFileオブジェクトのフラットリストです。このリストには、グローバルナビゲーションに含まれていないページが含まれている場合があり、そのナビゲーション内のページの順序と一致しない場合があります。pageFileのオブジェクトは、file.pageからアクセスできます。

page

Markdownソースファイルからレンダリングされないテンプレートでは、page変数はNoneです。Markdownソースファイルからレンダリングされるテンプレートでは、page変数にはpageオブジェクトが含まれています。同じpageオブジェクトは、グローバルナビゲーションおよびpagesテンプレート変数内のpage ナビゲーションオブジェクトとして使用されます。

ベース: StructureItem

すべてのpageオブジェクトには、次の属性が含まれています。

title() -> str | None

現在のページのタイトルを返します。

read_source()を呼び出す前、この値は空です。render()によって更新することもできます。

これらの順序でチェックし、有効なタイトルを返す最初のものを返します。

  • 初期化時に提供された値(設定から渡された値)
  • メタデータ'title'の値
  • Markdownコンテンツの最初のH1の内容
  • ファイル名をタイトルに変換する
content: str | None インスタンス属性

HTMLとしてレンダリングされたMarkdown。これはドキュメントの内容です。

.render()の後で設定されます。

toc: TableOfContents インスタンス属性

ページの目次を表す反復可能なオブジェクトです。toc内の各項目はAnchorLinkです。

次の例では、ページの目次の上位2レベルを表示します。

<ul>
{% for toc_item in page.toc %}
    <li><a href="{{ toc_item.url }}">{{ toc_item.title }}</a></li>
    {% for toc_item in toc_item.children %}
        <li><a href="{{ toc_item.url }}">{{ toc_item.title }}</a></li>
    {% endfor %}
{% endfor %}
</ul>
meta: MutableMapping[str, Any] インスタンス属性

Markdownページの先頭に含まれるメタデータのマッピングです。

この例では、ページタイトルの上にsourceプロパティを定義します。

source: generics.py
        mixins.py

# Page title

Content...

テンプレートは、meta.source変数を使用して、ページのこのメタデータにアクセスできます。これは、ドキュメントページに関連するソースファイルへのリンクに使用できます。

{% for filename in page.meta.source %}
  <a class="github" href="https://github.com/.../{{ filename }}">
    <span class="label label-info">{{ filename }}</span>
  </a>
{% endfor %}
url: str プロパティ

MkDocsのsite_dirを基準としたページのURLです。

これは、URLが現在のページを基準とした相対URLになるようにurlフィルタと共に使用されることが想定されています。

<a href="{{ page.url|url }}">{{ page.title }}</a>
file: File インスタンス属性

ページがレンダリングされているドキュメントFileです。

abs_url: str | None インスタンス属性

site_url設定に割り当てられた値によって決定される、サーバールートからのページの絶対URLです。この値には、site_urlに含まれるサブディレクトリが含まれますが、ドメインは含まれません。base_urlはこの変数と共に使用しないでください。

例えば、site_url: https://example.com/の場合、ページfoo.mdpage.abs_urlの値は/foo/になります。しかし、site_url: https://example.com/bar/の場合、ページfoo.mdpage.abs_urlの値は/bar/foo/になります。

canonical_url: str | None インスタンス属性

site_url設定に割り当てられた値によって決定される、現在のページへの完全な標準URLです。この値には、ドメインとsite_urlに含まれるサブディレクトリが含まれます。base_urlはこの変数と共に使用しないでください。

edit_url: str | None インスタンス属性

ソースリポジトリ内のソースページへの完全なURLです。通常、ソースページを編集するためのリンクを提供するために使用されます。base_urlはこの変数と共に使用しないでください。

is_homepage: bool プロパティ

サイトのホームページの場合はTrue、その他のすべてのページの場合はFalseになります。

これは、pageオブジェクトの他の属性と組み合わせて動作を変更するために使用できます。たとえば、ホームページに異なるタイトルを表示するには

{% if not page.is_homepage %}{{ page.title }} - {% endif %}{{ site_name }}
previous_page: Page | None インスタンス属性

前のページのpageオブジェクト、またはNoneです。現在のページがサイトナビゲーションの最初の項目である場合、または現在のページがナビゲーションにまったく含まれていない場合は、値はNoneになります。

next_page: Page | None インスタンス属性

次のページのpageオブジェクト、またはNoneです。現在のページがサイトナビゲーションの最後の項目である場合、または現在のページがナビゲーションにまったく含まれていない場合は、値はNoneになります。

parent: Section | None = None クラス属性 インスタンス属性

サイトナビゲーション内の項目の直接の親です。最上位レベルの場合はNoneです。

children: None = None クラス属性 インスタンス属性

ページには子を含まず、属性は常にNoneです。

active: bool プロパティ 書き込み可能

Trueの場合、このページが現在表示されているページであることを示します。デフォルトはFalseです。

is_section: bool = False クラス属性 インスタンス属性

ナビゲーションオブジェクトが「セクション」オブジェクトであることを示します。ページオブジェクトの場合は常にFalseです。

is_page: bool = True クラス属性 インスタンス属性

ナビゲーションオブジェクトが「ページ」オブジェクトであることを示します。ページオブジェクトの場合は常にTrueです。

ナビゲーションオブジェクトが「リンク」オブジェクトであることを示します。ページオブジェクトの場合は常にFalseです。

目次内の1つのエントリです。

title: str インスタンス属性

項目のテキスト(HTML形式)。

url: str プロパティ

項目を指すURLのハッシュフラグメントです。

level: int インスタンス属性

項目の0ベースのレベルです。

children: list[AnchorLink] インスタンス属性

子項目の反復可能なオブジェクトです。

navテンプレート変数に含まれるナビゲーションオブジェクトは、sectionオブジェクト、pageオブジェクト、linkオブジェクトのいずれかです。sectionオブジェクトはネストされたナビゲーションオブジェクトを含むことができますが、pageオブジェクトとlinkオブジェクトは含みません。

Pageオブジェクトは、同じ属性がすべて使用可能な現在のpageに使用される完全なページオブジェクトです。SectionオブジェクトとLinkオブジェクトには、以下で定義されているように、それらの属性のサブセットが含まれています。

Section

sectionナビゲーションオブジェクトは、ナビゲーション内の名前付きセクションを定義し、子ナビゲーションオブジェクトのリストを含みます。セクションにはURLが含まれず、いかなる種類のリンクでもありません。ただし、デフォルトでは、MkDocsはインデックスページを最上位にソートし、テーマが選択した場合、最初の子供がセクションのURLとして使用される場合があります。

ベース: StructureItem

sectionオブジェクトで使用できる属性を次に示します。

title: str インスタンス属性

セクションのタイトルです。

parent: Section | None = None クラス属性 インスタンス属性

サイトナビゲーション内の項目の直接の親です。最上位レベルの場合はNoneです。

children: list[StructureItem] インスタンス属性

すべての子ナビゲーションオブジェクトの反復可能なオブジェクトです。子には、ネストされたセクション、ページ、リンクが含まれる場合があります。

active: bool プロパティ 書き込み可能

Trueの場合、このセクションの子ページが現在のページであることを示し、現在表示されているセクションとしてセクションを強調表示するために使用できます。デフォルトはFalseです。

is_section: bool = True クラス属性 インスタンス属性

ナビゲーションオブジェクトが「セクション」オブジェクトであることを示します。セクションオブジェクトの場合は常にTrueです。

is_page: bool = False クラス属性 インスタンス属性

ナビゲーションオブジェクトが「ページ」オブジェクトであることを示します。セクションオブジェクトの場合は常にFalseです。

ナビゲーションオブジェクトが「リンク」オブジェクトであることを示します。セクションオブジェクトの場合は常にFalseです。

link ナビゲーションオブジェクトには、内部MkDocsページを指していないリンクが含まれています。

ベース: StructureItem

linkオブジェクトで使用できる属性を以下に示します。

title: str インスタンス属性

リンクのタイトルです。一般的に、リンクのラベルとして使用されます。

url: str インスタンス属性

リンクが指すURLです。URLは常に絶対URLである必要があり、base_urlをプリペンドする必要はありません。

parent: Section | None = None クラス属性 インスタンス属性

サイトナビゲーション内の項目の直接の親です。最上位レベルの場合はNoneです。

children: None = None クラス属性 インスタンス属性

リンクには子を含まず、属性は常にNoneです。

active: bool = False クラス属性 インスタンス属性

外部リンクは「アクティブ」にできず、属性は常にFalseです。

is_section: bool = False クラス属性 インスタンス属性

ナビゲーションオブジェクトが「セクション」オブジェクトであることを示します。リンクオブジェクトの場合は常にFalseです。

is_page: bool = False クラス属性 インスタンス属性

ナビゲーションオブジェクトが「ページ」オブジェクトであることを示します。リンクオブジェクトの場合は常にFalseです。

ナビゲーションオブジェクトが「リンク」オブジェクトであることを示します。リンクオブジェクトの場合は常にTrueです。

追加コンテキスト

extra 構成オプションを使用して、テンプレートに追加の変数を渡すことができます。これは、カスタムテンプレートをはるかに柔軟にすることができる、キーと値のペアのセットです。

たとえば、これを使用して、すべてのページのプロジェクトバージョンと、プロジェクトに関連するリンクのリストを含めることができます。これは、次のextra構成を使用することで実現できます。

extra:
  version: 0.13.0
  links:
    - https://github.com/mkdocs
    - https://docs.readthedocs.org/en/latest/builds.html#mkdocs
    - https://mkdocs.dokyumento.jp/

そして、カスタムテーマでこのHTMLを使用して表示します。

{{ config.extra.version }}

{% if config.extra.links %}
  <ul>
  {% for link in config.extra.links %}
      <li>{{ link }}</li>
  {% endfor %}
  </ul>
{% endif %}

テンプレートフィルター

Jinjaのデフォルトフィルターに加えて、MkDocsテンプレートで使用できる次のカスタムフィルターがあります。

url

URLを正規化します。絶対URLは変更されずに渡されます。URLが相対的で、テンプレートコンテキストにページオブジェクトが含まれている場合、URLはページオブジェクトを基準とした相対URLとして返されます。それ以外の場合は、base_urlをプリペンドしたURLが返されます。

<a href="{{ page.url|url }}">{{ page.title }}</a>

tojson

PythonオブジェクトをJavaScriptスクリプトの値に安全に変換します。

<script>
    var mkdocs_page_name = {{ page.title|tojson|safe }};
</script>

script_tag

バージョン1.5の新機能

extra_javascriptの項目を、このconfigのカスタマイズをすべて考慮し、|url と同等の動作を組み込んだ<script>タグに変換します。

上記の基本的な例で使用方法を参照してください。

検索とテーマ

MkDocsバージョン0.17から、searchプラグインを介してクライアント側の検索サポートがMkDocsに追加されました。テーマでプラグインが機能するには、テーマがいくつかのものを提供する必要があります。

searchプラグインはデフォルトで有効になっていますが、ユーザーはプラグインを無効にでき、テーマはその点を考慮する必要があります。テーマテンプレートは、プラグインのチェックを使用して、検索固有のマークアップをラップすることをお勧めします。

{% if 'search' in config.plugins %}
    search stuff here...
{% endif %}

最も基本的な機能では、検索プラグインは、すべてのページの内容を含むJSONファイル以上のものがないインデックスファイルを提供します。テーマは、クライアント側で独自の検索機能を実装する必要があります。ただし、いくつかの設定と必要なテンプレートを使用すると、プラグインはlunr.jsに基づいて、完全に機能するクライアント側の検索ツールを提供できます。

提供されたJavaScriptが検索スクリプトを適切に読み込み、現在のページから検索結果への相対リンクを作成できるようにするために、次のHTMLをテーマに追加する必要があります。

<script>var base_url = {{ base_url|tojson }};</script>

適切に構成された設定を使用すると、テンプレート内の次のHTMLにより、テーマに完全な検索実装が追加されます。

<h1 id="search">Search Results</h1>

<form action="search.html">
  <input name="q" id="mkdocs-search-query" type="text" >
</form>

<div id="mkdocs-search-results">
  Sorry, page not found.
</div>

プラグインのJavaScriptは、上記のHTMLで使用されている特定のIDを探して機能します。ユーザーが検索クエリを入力するためのフォーム入力はid="mkdocs-search-query"で識別する必要があり、結果が表示されるdivはid="mkdocs-search-results"で識別する必要があります。

テーマの構成ファイルであるmkdocs_theme.ymlで、プラグインに次のオプションを設定できます。

include_search_page

検索プラグインが、search/search.htmlにあるテンプレートを介して、テーマが専用の検索ページを提供することを期待しているかどうかを決定します。

include_search_pagetrueに設定されている場合、検索テンプレートが構築され、search/search.htmlで利用可能になります。この方法は、readthedocsテーマで使用されています。

include_search_pagefalseに設定されているか、定義されていない場合、テーマが検索結果を表示するための他のメカニズムを提供することが期待されます。たとえば、mkdocsテーマは、モーダルを介して任意のページに結果を表示します。

search_index_only

検索プラグインが検索インデックスのみを生成するのか、完全な検索ソリューションを生成するのかを決定します。

search_index_onlyfalseに設定されている場合、検索プラグインは、独自のtemplatesディレクトリ(テーマよりも優先順位が低い)を追加し、スクリプトをextra_javascript構成設定に追加することにより、Jinja環境を変更します。

search_index_onlytrueに設定されているか、定義されていない場合、検索プラグインはJinja環境を変更しません。提供されたインデックスファイルを使用する完全なソリューションは、テーマの責任です。

検索インデックスは、site_dirsearch/search_index.jsonにあるJSONファイルに書き込まれます。ファイルに含まれるJSONオブジェクトには、最大3つのオブジェクトを含めることができます。

{
    config: {...},
    docs: [...],
    index: {...}
}

存在する場合、configオブジェクトには、ユーザーのmkdocs.yml構成ファイルのplugings.searchの下でプラグインに対して定義された構成オプションのキーと値のペアが含まれています。configオブジェクトはMkDocsバージョン1.0で新しく追加されました。

docsオブジェクトには、ドキュメントオブジェクトのリストが含まれています。各ドキュメントオブジェクトは、location(URL)、title、および検索インデックスの作成や検索結果の表示に使用できるtextで構成されています。

存在する場合、indexオブジェクトには、より大きなサイトのパフォーマンスを向上させる事前構築されたインデックスが含まれています。事前構築されたインデックスは、ユーザーがprebuild_index構成オプションを明示的に有効にした場合にのみ作成されることに注意してください。テーマはインデックスが存在しないことを想定する必要がありますが、利用可能な場合にインデックスを使用することを選択できます。indexオブジェクトはMkDocsバージョン1.0で新しく追加されました。

テーマのパッケージ化

MkDocsは、テーマを配布するためにPythonパッケージを使用します。これにはいくつかの要件が伴います。

1つのテーマを含むパッケージの例については、MkDocs Bootstrapテーマを参照し、多くのテーマを含むパッケージについては、MkDocs Bootswatchテーマを参照してください。

注意

テーマ全体をcustom_dirに含めることができるため、テーマをパッケージ化する必要はありません。「一度限りのテーマ」を作成した場合は、それで十分です。ただし、他のユーザーが使用できるようにテーマを配布する予定がある場合は、テーマをパッケージ化するといくつかの利点があります。テーマをパッケージ化することで、ユーザーはより簡単にインストールでき、デフォルトの構成が定義されていることを信頼し、custom_dirを利用してテーマを調整し、ニーズに最適化することができます。

パッケージレイアウト

テーマには次のレイアウトをお勧めします。最上位ディレクトリにはMANIFEST.insetup.pyという2つのファイルがあり、テーマディレクトリ(空の__init__.pyファイル、テーマ構成ファイル(mkdocs_theme.yml)、テンプレートファイル、メディアファイルを含む)の隣にあります。

.
|-- MANIFEST.in
|-- theme_name
|   |-- __init__.py
|   |-- mkdocs_theme.yml
|   |-- main.html
|   |-- styles.css
`-- setup.py

MANIFEST.in ファイルには、以下の内容を含める必要があります。ただし、`theme_name` を更新し、インクルードするファイル拡張子をすべて追加してください。

recursive-include theme_name *.ico *.js *.css *.png *.html *.eot *.svg *.ttf *.woff
recursive-exclude * __pycache__
recursive-exclude * *.py[co]

setup.py には、下記のテキストを含める必要があります。以下の説明に従って修正してください。

from setuptools import setup, find_packages

VERSION = '0.0.1'

setup(
    name="mkdocs-themename",
    version=VERSION,
    url='',
    license='',
    description='',
    author='',
    author_email='',
    packages=find_packages(),
    include_package_data=True,
    entry_points={
        'mkdocs.themes': [
            'themename = theme_name',
        ]
    },
    zip_safe=False
)

URL、ライセンス、説明、作成者、作成者のメールアドレスを入力してください。

名前は mkdocs-themename(例: mkdocs-bootstrapmkdocs-bootswatch)という規則に従い、MkDocs で始まり、単語をハイフンで区切り、テーマ名を含める必要があります。

ファイルの大部分は編集せずに残すことができます。変更する必要がある最後のセクションは、`entry_points` です。これは、MkDocs がパッケージに含めるテーマを見つける方法です。左側の名前は、ユーザーが `mkdocs.yml` で使用する名前であり、右側の名前はテーマファイルを含むディレクトリです。

このセクションの先頭で `main.html` ファイルと共に作成したディレクトリには、他のすべてのテーマファイルを含める必要があります。最小限の要件として、テーマの `main.html` が含まれている必要があります。また、空である必要がある `__init__.py` ファイルも含まれている必要があります。このファイルは、ディレクトリがパッケージであることを Python に伝えます。

テーマ設定

パッケージ化されたテーマには、テンプレートファイルのルートに配置される mkdocs_theme.yml という名前の設定ファイルを含める必要があります。このファイルには、テーマのデフォルト設定オプションを含める必要があります。ただし、テーマに設定オプションがない場合でも、このファイルは必須であり、空のままにすることができます。パッケージ化されていないテーマは、mkdocs_theme.yml ファイルは必要ありません。このファイルは theme.custom_dir からロードされないためです。

テーマ作成者は、必要に応じて任意のオプションを自由に定義できます。これらのオプションは、動作を制御するためにテンプレートで使用できます。たとえば、テーマでサイドバーをオプションにし、mkdocs_theme.yml ファイルに以下を含めたい場合があります。

show_sidebar: true

次に、テンプレートで、その設定オプションを参照できます。

{% if config.theme.show_sidebar %}
<div id="sidebar">...</div>
{% endif %}

そして、ユーザーはプロジェクトの `mkdocs.yml` 設定ファイルでデフォルトを上書きできます。

theme:
  name: themename
  show_sidebar: false

テーマによって定義された任意のオプションに加えて、MkDocs はその動作を変更するいくつかの特別なオプションを定義します。

ブロック

ロケール

このオプションは、同じ名前のテーマ設定オプションを反映しています。この値が mkdocs_theme.yml ファイルに定義されておらず、ユーザーが mkdocs.yml で設定していない場合、デフォルトで en(英語)になります。この値は、テーマによって提供されるテキスト(「次へ」や「前へ」のリンクなど)で使用される言語と一致する必要があり、<html> タグの lang 属性の値として使用される必要があります。詳細については、テーマのローカリゼーション/翻訳のサポートを参照してください。

設定の検証中に、提供された文字列は Locale オブジェクトに変換されることに注意してください。このオブジェクトには Locale.language 属性と Locale.territory 属性が含まれており、テンプレート内から文字列として解決されます。そのため、以下は正常に機能します。

<html lang="{ config.theme.locale }">

ロケールが fr_CA(カナダフランス語)に設定されている場合、上記のテンプレートは次のようにレンダリングされます。

<html lang="fr_CA">

地域属性を含めたくない場合は、language 属性を直接参照してください。

<html lang="{ config.theme.locale.language }">

これは次のようにレンダリングされます。

<html lang="fr">

static_templates

このオプションは、テーマ設定オプションと同じ名前のオプションを反映しており、テーマによっていくつかのデフォルトを設定できます。ユーザーはこのリストにテンプレートを追加できますが、テーマの設定に含まれるテンプレートを削除することはできません。

extends

このテーマが継承する親テーマを定義します。値は、親テーマの文字列名である必要があります。通常のJinja の継承ルールが適用されます。

プラグインは、テーマが期待するプラグインオプションのセットについてプラグインに通知できるいくつかのオプションも定義できます。テーマでサポートしたいプラグインのドキュメントを参照してください。

テーマの配布

上記の変更により、テーマはインストールできるようになります。これは、`setup.py` と同じディレクトリにいる場合は、pip install . を使用して pip で実行できます。

MkDocs を含むほとんどの Python パッケージは、PyPI で配布されています。これを行うには、次のコマンドを実行する必要があります。

python setup.py register

アカウントが設定されていない場合は、アカウントを作成するように求められます。

さらに詳しいガイドについては、プロジェクトのパッケージ化と配布に関する公式の Python パッケージ化ドキュメントを参照してください。

テーマのローカリゼーション/翻訳のサポート

組み込みテーマはテンプレートのローカリゼーション/翻訳をサポートしていますが、カスタムテーマやサードパーティのテーマはサポートしない場合があります。それにもかかわらず、theme 設定オプションのlocale設定は常に存在し、システムの他の部分で使用されます。そのため、すべてのサードパーティテーマで、翻訳に使用するシステムに関係なく、言語を指定するための同じ設定を使用することをお勧めします。このようにすることで、ユーザーは選択するテーマに関係なく、一貫した動作を体験できます。

翻訳の管理方法は、テーマの開発者に任されています。ただし、テーマ開発者が組み込みテーマで使用されているのと同じメカニズムを使用することを選択した場合、以下のセクションでは、MkDocs によって使用されるのと同じコマンドを有効にして使用する方法について説明します。

ローカリゼーション/翻訳コマンドの使用

警告

pybabel はデフォルトではインストールされておらず、ほとんどのユーザーは pybabel をインストールしていないため、テーマ開発者や翻訳者は、コマンドを使用できるように必要な依存関係(pip install 'mkdocs[i18n]' を使用)をインストールしていることを確認する必要があります。

翻訳コマンドは、テーマの作業ツリーのルートから呼び出す必要があります。

組み込みテーマを翻訳するために MkDocs が使用するワークフローの概要については、貢献ガイドの適切なセクション翻訳ガイドを参照してください。

カスタムテーマのローカリゼーション/翻訳ワークフローの例

注意

テーマが既に翻訳カタログを提供している既存のテーマを継承している場合、テーマの翻訳は、MkDocs のビルド中に親テーマの翻訳とマージされます。

つまり、追加された翻訳にのみ集中する必要があるということです。それでも、親テーマの翻訳の恩恵を受けることができます。同時に、親テーマの翻訳を上書きすることもできます。

mkdocs-basic-theme の独自のフォークに取り組んでいて、それに翻訳を追加したいとします。

HTML ソースのテキストを次のように {% trans %}{% endtrans %} で囲むことで、テンプレートを編集します。

--- a/basic_theme/base.html
+++ b/basic_theme/base.html
@@ -88,7 +88,7 @@

 <body>

-  <h1>This is an example theme for MkDocs.</h1>
+  <h1>{% trans %}This is an example theme for MkDocs.{% endtrans %}</h1>

   <p>
     It is designed to be read by looking at the theme HTML which is heavily

その後、通常どおり翻訳ガイドに従って翻訳を実行します。

テーマでの翻訳のパッケージ化

extract_messages コマンドによって作成された Portable Object Template(pot)ファイルと、init_catalog および update_catalog コマンドによって作成された Portable Object(po)ファイルは、翻訳の作成と編集に役立ちますが、MkDocs では直接使用されず、テーマのパッケージ化されたリリースに含める必要はありません。MkDocs が翻訳付きのサイトをビルドする際には、指定されたロケールのバイナリ mo ファイルのみを使用します。したがって、テーマのパッケージ化を行う際には、MANIFEST.in ファイルを使用するなどして、「ホイール」に含めるようにしてください。

次に、Python パッケージをビルドする前に、各ロケールのバイナリ mo ファイルが最新であることを確認するために、各ロケールに対して compile_catalog コマンドを実行する必要があります。MkDocs は、バイナリ mo ファイルが locales/<locale>/LC_MESSAGES/messages.mo にあることを期待しており、compile_catalog コマンドによって自動的に実行されます。詳細については、テーマの翻訳のテストを参照してください。

注意

翻訳ガイドで説明されているように、MkDocs プロジェクトでは、pot ファイルと po ファイルをコードリポジトリに含めることを選択していますが、mo ファイルは含めていません。これにより、翻訳に変更を加えたかどうかに関係なく、新しいリリースをパッケージ化する前に常に compile_catalog を実行する必要があります。ただし、テーマに対して別のワークフローを選択することもできます。最低限、各リリースで正しい場所に最新の mo ファイルが含まれていることを確認する必要があります。ただし、それらの mo ファイルの生成に別のプロセスを使用することもできます。