shibuyaテーマとablogのpage_layout競合を解消した

このサイトは Sphinx + shibuya テーマ + ablog という構成で動いています。 conf.py"page_layout": "compact"を指定しているのに、ブログ記事のページだけレイアウトが変わらない、という問題が気になっていたので調べて直しました。

原因

テンプレートローダーの検索順序が問題でした。

Sphinxがページをレンダリングするとき、page.htmlというテンプレートを探します。 このとき、テンプレートローダーは次の順番で検索します。

  1. docs/_templates/(ユーザー定義)

  2. ablogのテンプレートディレクトリ ← ablogがbuilder_initedで割り込む

  3. shibuyaのテーマディレクトリ

ablogは初期化時に自分のテンプレートをローダーの2番目に差し込みます。 その結果、ablog/templates/page.htmlが見つかった時点で検索が止まり、shibuyaのpage.htmlには到達しません。

shibuyaのpage.htmlはこうなっています。

{%- if meta and meta.layout -%}
  {%- extends 'layout/' + meta.layout + '.html' -%}
{%- else -%}
  {%- extends 'layout/' + theme_page_layout + '.html' -%}
{%- endif -%}

theme_page_layout(= compact)を参照して適切なレイアウトを選ぶ処理がここにあります。 しかし ablogのpage.htmlはこれを持たず、Sphinx標準のlayout.htmlを直接extendsします。 そのためpage_layoutがまるごと無視されていました。

解決方法

docs/_templates/page.htmlを作成して、無理やり解決しました。

ユーザー定義テンプレートはローダーの最優先で選ばれます。 shibuyaのpage_layout処理とablogのナビゲーション・コメント機能を両立したpage.htmldocs/_templates/に置くだけで解決できました。

{%- if meta and meta.layout -%}
  {%- extends 'layout/' + meta.layout + '.html' -%}
{%- else -%}
  {%- extends 'layout/' + theme_page_layout + '.html' -%}
{%- endif -%}

{%- set fa = ablog.fontawesome %}

{%- block extrahead %}
{{ super() }}
{% if feed_path %}
<link rel="alternate" type="application/atom+xml"
  href="{{ pathto(feed_path, 1) }}/atom.xml" title="{{ feed_title }}" />
{% endif %}
{%- endblock extrahead %}

{% block content %}
{{ body }}
<div class="section ablog__blog_comments">
  {% if pagename in ablog %}
    {% include "ablog/postnavy.html" %}
  {% endif %}
</div>
{% endblock content %}

block contentをオーバーライドしているので<article>の中にablogナビが入り、shibuyaのスタイルもきちんと当たるようになりました。