ablog icon indicating copy to clipboard operation
ablog copied to clipboard

Make it possible for Sphinx themes, to provide their own templates for ablog to use!

Open pradyunsg opened this issue 2 years ago • 12 comments

Currently, ablog unconditionally injects its own templates at the end of templates_path:

https://github.com/sunpy/ablog/blob/cbec004743212c565516df5bc3a4eb9f082b8605/ablog/init.py#L102

These templates are injected by Sphinx before the theme-provided templates:

https://github.com/sphinx-doc/sphinx/blob/v4.4.0/sphinx/jinja2glue.py#L168


This means, there is no easy way for theme authors to provide explicit support for ablog in their theme, if they don't follow the assumptions that ablog makes in its own templates (see #108).

/cc @choldgraf, since he contributed the unconditional addition + has his own blog using ablog as well. :)

pradyunsg avatar Jan 21 '22 08:01 pradyunsg

Ways I can think of addressing this:

  • Changing the unconditional append, to a conditional one, that is conditional on a flag/marker provided by the theme to indicate ablog support (ideally, in theme.conf and NOT [options] within that).
  • Providing a custom TemplateBridge, that has the relevant logic for conditional exclusion, based on the theme provided to it during loading.

One thing that would genuinely be great for this functionality in general, would be namespacing ablog's templates -- moving them into an ablog/ directory within templates/. That would make it much easier for themes to actually author and maintain support for ablog inline.

It should likely also be possible for users to override ablog's behavior in this regard, via a configuration option to force ablog to include (or not include) its custom templates.

pradyunsg avatar Jan 21 '22 09:01 pradyunsg

That all sounds good to me - so if the ablog templates were in templates/ablog/foo.html, then other could easily over-ride them on their own? I am not super familiar with how templates work in general in Sphinx...

choldgraf avatar Jan 22 '22 02:01 choldgraf

If this is something that can be done easily and without breaking anything, I am all for it.

nabobalis avatar Jan 22 '22 02:01 nabobalis

I don't think there's any way to be sure that things won't break -- at this point, with ABlog, Hyrum's Law applies. Any change around template handling will be a breaking change for somebody.

This would affect users with custom templates; who I'd guess are also be capable of figuring out how to pin to an older version or adapting their templates -- I think the breakage will be worth the improvements.

I don't know how "easy" it would be to do this -- I don't know the codebase at all! :)

pradyunsg avatar Jan 22 '22 06:01 pradyunsg

so if the ablog templates were in templates/ablog/foo.html, then other could easily over-ride them on their own?

Merely moving them doesn't address the underlying issue, but it will make it much cleaner to implement support for this + make it clearer for everyone what the template is for. :)

I am not super familiar with how templates work in general in Sphinx...

The relevant logic in Sphinx is https://github.com/sphinx-doc/sphinx/blob/v4.4.0/sphinx/jinja2glue.py#L152-L178 and https://github.com/sphinx-doc/sphinx/blob/v4.4.0/sphinx/jinja2glue.py#L206. It uses Jinja2, and here's the relevant documentation section: https://jinja2docs.readthedocs.io/en/stable/api.html#loaders.

Basically, Sphinx handles template paths as follows:

  • It has a list of Jinja2 loaders internally, where each loader corresponds to a filesystem path.
  • When you look for a template named foo.html, it will use the first directory in the list that has this template. Thus, the directories that show up earlier in the list are highest priority.
  • Sphinx has two ways to get template directories -- user-specified templates_path in conf.py and theme directories.
  • The theme directories are ordered such that the base directories are after the theme directories. For Sphinx Book Theme, the order of the directories will be sphinx_book_theme's dir, pydata_sphinx_theme's dir, basic's dir.
  • User-specified templates_path values are added before the theme directories. Thus, they'll override any templates provided by the theme.
  • ABlog injects its directory at the end of templates_path. Thus, for your website, which uses sphinx_book_theme and ablog, your templates order will be: any _templates directory next to your conf.py, ablog's dir, sphinx_book_theme's dir, pydata_sphinx_theme's dir, basic's dir.

As I mentioned in OP, there's no way to define a template in sphinx_book_theme that would override what ablog provides -- that's because ablog injects its path before all the theme paths. Now, this is necessary for alabaster or sphinx_book_theme since those don't have dedicated support for ablog and, thus, overriding their templates is required to make things work.

pradyunsg avatar Jan 22 '22 07:01 pradyunsg

So... I think this is achievable; albeit at the cost of breaking users who are setting up custom templates in their own documentation.

I'd argue it is worthwhile -- it's a much healthier place to be, having a blog-related templates be something that Sphinx themes can provide from their end, letting themes handle the presentation and markup; given the relevant context. I think this is basically a blocker for making it easier to build something like python-poetry.org or pradyunsg.me with just Sphinx and a custom theme currently.

pradyunsg avatar Feb 25 '22 08:02 pradyunsg

Beyond that, I'd argue that ablog should move away from zero-based versioning given that one of the two concerns raised by @nabobalis here is backwards compatibility. :)

(the other being implementation complexity)

pradyunsg avatar Feb 25 '22 08:02 pradyunsg

I can bump the major version.

nabobalis avatar Feb 25 '22 15:02 nabobalis

Suggested path forward

How about ablog does the following things:

  1. Puts all of its templates in an ablog/ folder (so that if people manually wish to add the ablog template, they use html_sidebars = ["ablog/templatename.html"].
  2. Keeps the current templates, and each one of them simply does an include that points to the ablog/ version of that template.
  3. Adds a check in its Python code that raises a deprecation warning if the non-ablog/ template is used.
  4. Inserts its templates at the beginning of the templates_path rather than at the end, so other themes can over-ride the templates by defining things in their own ablog/ templates folder.

choldgraf avatar Jul 12 '22 06:07 choldgraf

The issue is that would not work with alabaster, for which support relies on overriding the templates provided by the theme.

pradyunsg avatar Jul 12 '22 07:07 pradyunsg

hmmm ok - well then I'd still be in favor of 1-3, as an iterative improvement, along with:

  • https://github.com/sunpy/ablog/issues/143

choldgraf avatar Jul 12 '22 09:07 choldgraf

Ok I started having a go at this in https://github.com/sunpy/ablog/pull/144 It also contains work for another issue.

I don't plan to do a depreciation period or any checks, I just plan to bump to the next version and include breaking changes in the changelog (when I finish the PR).

I think as far as I can understand, I moved the templates to a ablog subfolder, I also changed any code in ablog to append itself to the start of the templates path.

nabobalis avatar Jul 19 '22 23:07 nabobalis