level12 / keg

Keg: more than Flask
Other
12 stars 9 forks source link

Components: adjust template loading priority to prefer components? #175

Open rsyring opened 3 years ago

rsyring commented 3 years ago

I dislike that in components, which use blueprints, we have to put the templates in a subfolder:

# current
myproject/components/foo/templates/foo/index.html

# IMO preferred
myproject/components/foo/templates/index.html

This is easily accomplished by setting the blueprint's template_folder:

# assuming we are in ...foo/views/some-view.py
Blueprint(..., template_folder='../templates')

However, that creates problems b/c the default hierarchy for Flask template loading is that the app templates can override blueprint templates. This makes sense in a world where blueprints are used for things like plugins from external packages. But it doesn't make sense in a component based application where the source code of the blueprint belongs to the app. Any required changes are just going to be made directly in the component.

Does it make sense to try and customize Flask's template loading logic to account for component templates? It wouldn't be enough to just put them at the top of the template loading hierarchy b/c then the app or other templates would pull the component's templates first (e.g. if the component had "base-page.html"). We'd almost have to have a two step lookup where, if finding a template for a component, look in that component's folder first, then bump back out to the standard flask logic.

guruofgentoo commented 3 years ago

There's an additional wrinkle here in that templates are cached by path as they're used. So having index.html in one component will cache that template and the next time another component's index.html is called for, the first template wins. I think that played into the current arrangement being what it is.

IIRC, there wasn't a great clean way to change how flask loads the templates. It's nice that we can set the template folder, but I think that just adds the folder to the flask app's templates set - I don't think the blueprint tracks, looks up, or otherwise deals with its "own" templates. When the rendering happens with flask.render_template and just takes a path and args, it becomes more difficult to override at the component or blueprint level.