Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix theme support for ablog #295

Merged
merged 6 commits into from
Nov 1, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
"Ahmet": ("Ahmet Bakan", "https://ahmetbakan.com"),
"Luc": ("Luc Saffre", "https://saffre-rumma.net/luc/"),
"Mehmet": ("Mehmet Gerçeker", "https://github.com/mehmetg"),
"Libor": ("Libor Jelínek", "https://liborjelinek.github.io/")
}
blog_feed_archives = True
blog_feed_fulltext = True
Expand Down
33 changes: 0 additions & 33 deletions docs/manual/ablog-configuration-options.rst
Original file line number Diff line number Diff line change
Expand Up @@ -265,39 +265,6 @@ Integration is provided by `sphinxnotes-isso`_ and the instructions there.

.. _sphinxnotes-isso: https://sphinx-notes.github.io/isso/

.. _sidebars:

Blog sidebars
-------------

There are seven Ablog sidebars you can include in your HTML output using Sphinx_ :confval:`html_sidebars` configuration option (in addition to your theme sidebars).

- ``alog/postcard.html`` provides information regarding the current post (when on a post page)
- ``alog/recentposts.html`` lists most recent five posts.
- ``alog/tagcloud.html`` provides a links to a archive pages generated for each tag
- ``alog/category.html``, ``alog/authors.html``, ``alog/languages.html``, and ``alog/locations.html`` sidebars generates list of link to respective archive pages with number of matching posts (e.g., "Manual 14)", "2023 (8)", "English (22")).

For example, sidebars that you see on this website on the left are:

.. code-block:: python

html_sidebars = {
"**": [
# Comes from Alabaster theme
"about.html",
"searchfield.html",
# Ablog sidebards
"ablog/postcard.html",
"ablog/recentposts.html",
"ablog/tagcloud.html",
"ablog/categories.html",
"ablog/archives.html",
"ablog/authors.html",
"ablog/languages.html",
"ablog/locations.html",
]
}

Command Options
---------------

Expand Down
97 changes: 97 additions & 0 deletions docs/manual/templates-themes.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
Templating and Themes Support
=============================

.. post:: Oct 26, 2024
:tags: themes
:category: Manual
:author: Libor

Ablog, as being Sphinx extensions, it has highly customizable HTML output. The generated HTML files are based `Sphinx templates`_. You, or Sphinx themes can partially or completely override these templates to customize the resulting HTML.
liborjelinek marked this conversation as resolved.
Show resolved Hide resolved

.. _Sphinx templates: https://www.sphinx-doc.org/en/master/development/html_themes/templating.html

.. versionchanged:: 0.11
The :doc:`Ablog 0.11 </release/ablog-v0.11-released>` has changed and improved the way how you can customize templates and themes. Please note that this document describes the new way of customizing templates and themes support.

.. _sidebars:

Blog sidebars
-------------

Sidebars are a common way to provide additional information to the reader. There are seven Ablog sidebars you can include in your HTML output using Sphinx_ :confval:`html_sidebars` configuration option (in addition to your theme sidebars).

- ``alog/postcard.html`` provides information regarding the current post (when on a post page)
- ``alog/recentposts.html`` lists most recent five posts.
- ``alog/tagcloud.html`` provides a links to a archive pages generated for each tag
- ``alog/category.html``, ``alog/authors.html``, ``alog/languages.html``, and ``alog/locations.html`` sidebars generates list of link to respective archive pages with number of matching posts (e.g., "Manual 14)", "2023 (8)", "English (22")).

For example, sidebars that you see on this website on the left are:

.. code-block:: python

html_sidebars = {
"**": [
# Comes from Alabaster theme
"about.html",
"searchfield.html",
# Ablog sidebards
"ablog/postcard.html",
"ablog/recentposts.html",
"ablog/tagcloud.html",
"ablog/categories.html",
"ablog/archives.html",
"ablog/authors.html",
"ablog/languages.html",
"ablog/locations.html",
]
}

Styling default Ablog sidebars
------------------------------

Ablog standard sidebars are wrapped in ``<div>`` with CSS classes like ``ablog-item ablog__{{ TEMPLATE-FILENAME }}`` making easier to style them. For example, the ``postcard.html`` template is wrapped in ``<div class="ablog-item ablog__postcard">``.

Buitin sidebars can be found in the ``ablog/`` folder in the `Ablog source code <https://github.com/sunpy/ablog/tree/main/src/ablog/templates/ablog>`_.

If styling is not enough, you can override the Ablog templates in your Sphinx project or in the Sphinx theme.

Partial or complete override of Ablog templates
-----------------------------------------------

To control whether Ablog injects its own templates into the Sphinx build, you can use the following ``conf.py`` configuration option:

.. confval:: skip_injecting_base_ablog_templates

If set to ``True``, Ablog will not inject its own templates into the Sphinx build. This is useful if you want to completely override Ablog templates in your Sphinx project or in the Sphinx theme. Default is ``False``.

Customizing templates in the project
------------------------------------

All Ablog templates are under ``ablog/`` folder space. For example, ``ablog/postcard.html``. You can override these templates by placing them in the ``ablog/`` folder in your project templates folder.

#. Add the :confval:`templates_path` option in your ``conf.py`` file:

.. code-block:: python

templates_path = ["_templates"]

#. Create a folder ``_templates/`` next to your ``conf.py`` file. It will hold your custom templates.
#. Create a folder ``ablog/`` inside the ``_templates/`` folder.
#. Create here a file with the same name as the template you want to override. For example, ``postcard.html``. This file will be used as a custom template for the sidebar. You can copy the content of the original template from the Ablog source code and modify it as you need.
#. Optionall: if you want to complete override all Ablog templates, set the :confval:`skip_injecting_base_ablog_templates` option to ``True``, copy all Ablog templates here and customize them as you need.

Customizing templates in the theme
----------------------------------

If you are a Sphinx theme author, you can ship customized Ablog templates in your theme. You can override Ablog templates by placing them in the ``ablog/`` folder in your theme templates, e.g., ``ablog/postcard.html``.

#. In theme root (where is the ``theme.conf`` file), create a folder ``ablog/``.
liborjelinek marked this conversation as resolved.
Show resolved Hide resolved
#. Create here a file with the same name as the template you want to override. For example, ``postcard.html``.
#. This file will be used as a custom template for the sidebar. You can copy the content of the original template from the Ablog source code and modify it as you need.
#. In your ``theme.conf`` file, add the following (under the ``[options]`` section):
liborjelinek marked this conversation as resolved.
Show resolved Hide resolved

.. code-block:: ini
liborjelinek marked this conversation as resolved.
Show resolved Hide resolved

ablog_inject_templates_after_theme = true

This will make sure that Ablog templates are injected *after* the theme templates, so you can override them while still using the Ablog templates as a fallback.
7 changes: 7 additions & 0 deletions docs/release/ablog-v0.11-released.rst
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,13 @@ Pull Requests merged in:

`Add external links for posts <https://github.com/sunpy/ablog/pull/112>`__ from `Chris Holdgraf <https://github.com/choldgraf>`__.

Unreleased
----------

Pull Requests merged in:

`Fix theme support for Ablog <https://github.com/sunpy/ablog/pull/XXX>`__ from `Libor Jelínek <https://github.com/liborjelinek/>`__.
liborjelinek marked this conversation as resolved.
Show resolved Hide resolved

ABlog v0.11.1 released
----------------------

Expand Down
1 change: 1 addition & 0 deletions roots/test-templates/_templates/ablog/postcard.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
custom postcard.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
custom postcard.html from theme
5 changes: 5 additions & 0 deletions roots/test-templates/_themes/test_theme/theme.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[theme]
inherit = "basic"

[options]
ablog_inject_templates_after_theme = true
2 changes: 2 additions & 0 deletions roots/test-templates/conf.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
extensions = ["ablog"]

7 changes: 7 additions & 0 deletions roots/test-templates/index.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
test-postlist
===============

.. toctree::
:maxdepth: 1

postlist
4 changes: 4 additions & 0 deletions roots/test-templates/post.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.. post:: 2020-12-01

post
=======
4 changes: 4 additions & 0 deletions roots/test-templates/postlist.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
postlist
==========

.. postlist::
2 changes: 1 addition & 1 deletion src/ablog/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ def builder_inited(app):
try:
# Modern Sphinx now errors instead of returning the default if there is not a value
# in any of the config files.
after_theme = theme.get_config("ablog", "inject_templates_after_theme", False)
after_theme = theme.get_config("options", "ablog_inject_templates_after_theme", False)
except ThemeError:
after_theme = False
if after_theme:
Expand Down
65 changes: 65 additions & 0 deletions src/ablog/tests/test_templates.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
from pathlib import Path
import pytest
from sphinx.application import Sphinx
from sphinx.errors import ThemeError


def read_text(path):
liborjelinek marked this conversation as resolved.
Show resolved Hide resolved
"""
Support function to give backward compatibility with older sphinx (v2).
"""
if hasattr(path, "read_text"):
return path.read_text()
return path.text()


@pytest.mark.sphinx("html", testroot="templates", confoverrides={"skip_injecting_base_ablog_templates": True})
def test_skip_ablog_templates_but_missing_templates(app: Sphinx):
"""Completely override the templates used by ablog, but not provide them."""
with pytest.raises(
ThemeError,
match=r"An error happened in rendering the page blog/archive\.\nReason: TemplateNotFound\(\"'ablog/catalog.html' not found in *.",
):
app.build()


@pytest.mark.sphinx(
"html",
testroot="templates",
confoverrides={
"templates_path": ["_templates"],
"skip_injecting_base_ablog_templates": False, # default value
"html_sidebars": {"**": ["ablog/postcard.html"]},
},
)
def test_override_template_but_fallback_missing(app: Sphinx, rootdir: Path):
"""Partically override the only some Ablog templates, but use the Ablog ones for missing as fallback."""
app.build()

# read the content of custom postcard template
expected = (rootdir / "test-templates" / "_templates" / "ablog" / "postcard.html").read_text()

# is it in the output?
source = (app.outdir / "post.html").read_text()
assert expected in source


@pytest.mark.sphinx(
"html",
testroot="templates",
confoverrides={
"html_sidebars": {"**": ["ablog/postcard.html"]},
"html_theme_path": "_themes",
"html_theme": "test_theme",
},
)
def test_themes_templates_come_first(app: Sphinx, rootdir: Path):
"""Ensures that if theme supplies own Ablog template, it is used over the builtin one."""
app.build()

# read the content of custom postcard template
expected = (rootdir / "test-templates" / "_themes" / "test_theme" / "ablog" / "postcard.html").read_text()

# is it in the output?
source = (app.outdir / "post.html").read_text()
assert expected in source
Loading