-
-
Notifications
You must be signed in to change notification settings - Fork 55
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
Template rework #144
Template rework #144
Conversation
ca270e4
to
82f817c
Compare
ablog/__init__.py
Outdated
|
||
return {"version": __version__} # identifies the version of our extension | ||
|
||
|
||
def config_inited(app, config): | ||
app.config.templates_path.append(get_html_templates_path()) | ||
app.config.templates_path = [get_html_templates_path()] + app.config.templates_path |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should prevent ablog being last on the list?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks... wrong. This puts ablog before the user-configured templates, which means even the user can't override these files. The paths from this configuration option are placed before theme templates, so as long as ablog's templates path is listed here, themes still won't be able to override the newly moved files.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, so I don't want to add ablog templates to this at all?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we do -- just not here. I've been procrastinating looking at this, but I'll take a closer look today.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, so here's my suggestions for what to change this to, to enable basically
everything we've discussed in #143 and #125:
-
Add a
ablog_skip_injecting_base_ablog_templates
configuration option, defaulting to False (rename to whatever) -
Change this handler to listen to
builder-inited
instead ofconfig-inited
. -
Change this line to be:
from sphinx.jinja2glue import SphinxFileSystemLoader if not app.config.ablog_skip_injecting_base_ablog_templates: if not isinstance(app.templates, BuiltinTemplateLoader): raise Exception( "Ablog does not know how to inject templates into with custom " "template bridges. You can use `ablog.get_html_templates_path()` to " "get the path to add in your custom template bridge and set " "`ablog_skip_injecting_base_ablog_templates = False` in your " "`conf.py` file." ) if get_html_templates_path() in app.config.templates_path: raise Exception( "Found the path from `ablog.get_html_templates_path()` in the " "`templates_path` variable from `conf.py`. Doing so interferes " "with Ablog's ability to stay compatible with Sphinx themes that " "support it out of the box. Please remove `get_html_templates_path` " "from `templates_path` in your `conf.py` to resolve this." ) theme = app.builder.theme loaders = app.templates.loaders templatepathlen = app.templates.templatepathlen if theme.get_config("ablog", "inject_templates_after_theme", False): # Inject *after* the user templates and the theme templates, # allowing themes to override the templates provided by this # extension while those templates still serve as a fallback. loaders.append(SphinxFileSystemLoader(get_html_templates_path()) else: # Inject *after* the user templates and *before* the theme # templates. This enables ablog to provide support for themes # that don't support it out-of-the-box, like alabaster. loaders.insert(templatepathlen, SphinxFileSystemLoader(get_html_templates_path())
This code has some fairly useful properties and behaviours:
-
All the attributes being used here are public, so Sphinx's backwards compatibility policy applies on them, giving us ample time to make changes if Sphinx changes things (deprecation warnings for 2 major versions before removal, which should be more than an year to adapt this code)
-
This puts the ablog templates after the theme templates, by default, with an escape hatch for users who don't want that. This does depend on them not setting
html_template_bridge
to something super custom -- that's a very small set of users AFAICT and the error message should give such users all the information that they need to act on it. -
This allows themes to change where ablog's template injection occurs, by setting a flag in their
theme.conf
file:[ablog] inject_templates_after_theme = true
This would enable themes like Furo to contain their own
ablog/catalog.html
for example. -
This prevents users from fiddling with the ordering of the templates, by not permitting them to inject the Ablog-provided templates manually.
In the spirit of transparency, I've not tested this code in any way -- and written most of this in a Markdown editor -- so no promises on whether this will work. That said, this will enable basically everything we discussed in #143 and #125 (as long as you move the templates, as has been done already). This should also be a drop-in replacement for users who don't set up custom templates or overrides on top of ablog itself. If they do, they might need to move those paths to match the namespace.
One template that you do not want to move is page.html
. That's the template that affects the actual Sphinx templating, since Sphinx renders for (almost) every HTML page and we want to override that for alabaster (the default theme).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for all of this, still trying to work out the kinks but your code was really useful!
I would have never got this working without it.
ablog/start.py
Outdated
@@ -216,7 +216,7 @@ def w(t, ls=80): | |||
] | |||
|
|||
# Add any paths that contain templates here, relative to this directory. | |||
templates_path = ["{dot}templates", ablog.get_html_templates_path()] | |||
templates_path = [ablog.get_html_templates_path(), "{dot}templates"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here, should be first.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Users shouldn't need to do this, given that the event handler adds this path already for them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, I will remove this from the setup script.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, we might want to add a check to reject configurations that do this. If users are doing this, they'll be able to break the way that the suggestion I've made for handling #143 and #125 works in a manner that's gonna be difficult for the user to diagnose (#144 (comment)).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To elaborate on what I mean:
- Furo adds support for Ablog and declares
inject_templates_after_theme = true
.- The theme's templates would take precedence over Ablog's templates
- This allows Furo to have a custom
page.html
andablog/catalog.html
, that are different from Ablog's.
- The above suggested code will make Ablog inject its own templates after the theme templates.
- If the user does nothing more, everything will work just fine.
If the user sets this in their conf.py
file, things will break.
- The Ablog templates will also be added before the theme templates (since user templates are injected before theme templates).
- Ablog's own templates would take precedence over the theme's templates.
- See the first bullet in the previous list -- that contradicts with this, and the user will see the wrong behaviour (i.e. the one noted in this list).
The most annoying part of this for the user is that the build won't fail, since the templates will still likely render correctly -- they'll be getting picked up from the wrong place and cause improper markup to be generated in the final rendered templates!
FWIW, one template that we do not want to move is |
04161d4
to
e9b552c
Compare
ab76901
to
ad23e98
Compare
ablog/__init__.py
Outdated
if not app.config.inject_templates_after_theme: | ||
if not isinstance(app.builder.templates, BuiltinTemplateLoader): | ||
raise Exception( | ||
"Ablog does not know how to inject templates into with custom " | ||
"template bridges. You can use `ablog.get_html_templates_path()` to " | ||
"get the path to add in your custom template bridge and set " | ||
"`inject_templates_after_theme = False` in your " | ||
"`conf.py` file." | ||
) | ||
if get_html_templates_path() in app.config.templates_path: | ||
raise Exception( | ||
"Found the path from `ablog.get_html_templates_path()` in the " | ||
"`templates_path` variable from `conf.py`. Doing so interferes " | ||
"with Ablog's ability to stay compatible with Sphinx themes that " | ||
"support it out of the box. Please remove `get_html_templates_path` " | ||
"from `templates_path` in your `conf.py` to resolve this." | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm... this option seems to be doing the wrong thing.
I'd suggest changing this to skip_injecting_base_ablog_templates
and changing the conf.py documentation related to this as well (I'll make a separate suggestion for that).
The goal isn't to skip doing any checks when that is set, but to avoid doing anything when that is set. This would basically be for users who are using a template bridge that does not work like Sphinx's own template bridge does. This logic is highly coupled with the way Sphinx's BuiltinTemplateLoader
works and we can't know if we'd present esoteric errors with alternatives -- and that's why we have the isinstance(..., BuiltinTemplateLoader)
check.
if not app.config.inject_templates_after_theme: | |
if not isinstance(app.builder.templates, BuiltinTemplateLoader): | |
raise Exception( | |
"Ablog does not know how to inject templates into with custom " | |
"template bridges. You can use `ablog.get_html_templates_path()` to " | |
"get the path to add in your custom template bridge and set " | |
"`inject_templates_after_theme = False` in your " | |
"`conf.py` file." | |
) | |
if get_html_templates_path() in app.config.templates_path: | |
raise Exception( | |
"Found the path from `ablog.get_html_templates_path()` in the " | |
"`templates_path` variable from `conf.py`. Doing so interferes " | |
"with Ablog's ability to stay compatible with Sphinx themes that " | |
"support it out of the box. Please remove `get_html_templates_path` " | |
"from `templates_path` in your `conf.py` to resolve this." | |
) | |
if app.config.skip_injecting_base_ablog_templates: | |
return | |
if not isinstance(app.builder.templates, BuiltinTemplateLoader): | |
raise Exception( | |
"Ablog does not know how to inject templates into with custom " | |
"template bridges. You can use `ablog.get_html_templates_path()` to " | |
"get the path to add in your custom template bridge and set " | |
"`skip_injecting_base_ablog_templates = False` in your " | |
"`conf.py` file." | |
) | |
if get_html_templates_path() in app.config.templates_path: | |
raise Exception( | |
"Found the path from `ablog.get_html_templates_path()` in the " | |
"`templates_path` variable from `conf.py`. Doing so interferes " | |
"with Ablog's ability to stay compatible with Sphinx themes that " | |
"support it out of the box. Please remove `get_html_templates_path` " | |
"from `templates_path` in your `conf.py` to resolve this." | |
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh wait, this can't be an early return since this function is also doing blog_post_pattern
stuff.
Well, the idea still stands, although the specific code suggestion here is wrong. We'd probably want to indent the lines that add the template instead, and only inject templates if the user hasn't explicitly configured a skip.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might make sense to make the two of them smaller functions, which would change this function to:
def builder_inited(app):
if not app.config.skip_injecting_base_ablog_templates:
_inject_base_templates(app)
_inject_matched_blog_posts(app)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I moved the blog_post_pattern
block back to a config-initted
function where it used to be. This should separate the two parts nicely.
So... I did some preliminary testing, starting with Everything with note 1: The On the first build with the new ablog, users will get the following error:
I really like this error message! It provides clear context on what went wrong, why that's a problem and what the user can do. We don't have control over the specific presentation out of Sphinx and that would be my only complaint about this. However, once I resolved that by following the instructions, you get the following error:
This is coming out of the note 2: We should write a "migrating from {old} ablog to {new} ablog", as a blog post. I'd be happy to write this. :) {{ warning("foo.html is an old template path, that is no longer used by ablog. Please use ablog/foo.html instead.") }} This would mean that users see a warning from Sphinx, that provides guidance, instead of the opaque error above. Changing the theme to Furo hits https://github.com/pradyunsg/furo/blob/main/src/furo/theme/furo/layout.html. After I added the following to Furo's [ablog]
inject_templates_after_theme = true This means that it is definitely possible now, to add first-class support for ABlog in Furo and other themes! Right now, quite a few things don't render correctly with Furo and the default templates from ABlog, but that's expected and something for future me to deal with. Right now, I'm very excited! :) |
Yes that part of
That would be incredible!
I will do that in this PR as well but I use the updated html files from this PR.
That is brilliant, I want to thank you for your help again on this PR. |
@nabobalis Anything I can do to help move this forward? |
I am not sure, I forgot about this and got the wrong import which is why the CI is broken. But I think in theory its complete. So maybe just a glance over the Python changes would be ideal to make sure its all sane. |
@@ -6,6 +6,9 @@ | |||
from glob import glob | |||
from pathlib import PurePath | |||
|
|||
from sphinx.builders.html import StandaloneHTMLBuilder |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is the correct HTMLBuilder.
Other than the need to fix the wrong setup for the dev build. I think everything is in place. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, based on a desk skim.
Thanks again. I will branch off main to keep a 0.10 branch around for a bit and then merge this. |
🎉 |
Hi, I still got the error for |
Hello, this patch never made it to a release version at the moment. My plan was to ship this in 0.11 but I got distracted and have not done a release of that. |
Oh i see.. Thanks! |
I am also seeing this on a new site / test setup I'm working on. I had ablog 0.10.30 installed and made sure it was updated to 0.10.33. It looks like there is no 0.11 release yet. |
Yes unfortunately that is the case. Real life has got in my way recently and that will not change for me until Christmas. |
Sorry it has taken me this long but I released ablog 0.11.0rc1. I did not want to release such a large change without at least a brief RC period. So if those who wanted to try this out for me, that would be great. I plan to test some of the projects I maintain that use ablog as well but its a very limited test. |
Nice - sounds good I will give it a shot and open issues |
Trying to fix the templates and tidy them up.
Fixes #143
Fixes #125
Fixes #108
TODO