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

enable extensions to override default templates #1686

Closed
MJochim opened this issue Sep 23, 2023 · 1 comment
Closed

enable extensions to override default templates #1686

MJochim opened this issue Sep 23, 2023 · 1 comment
Labels
extension Features or enhancements that have Fava extensions or could be implemented as one.

Comments

@MJochim
Copy link
Contributor

MJochim commented Sep 23, 2023

This is more or less a follow-up to #1643 and #1658, both of which change how extensions’ templates are handled.

I would like to be able to override Fava’s default templates (e.g. _journal_table.html) in my extension. I currently achieve this as outlined in the next paragraph, making use of the before_request hook I have proposed in PR #1685. My proposal in this issue is to do that globally for all extensions, so that an extension author can simply drop a file templates/_journal_table.html in their extension without resorting to a hook.

PR #1643 used the create_app function to replace fava_app.jinja_loader with a ChoiceLoader that included both Fava’s default loader as well as an extension loader, but only in the extension report endpoint. My private plugin, on the other hand, uses the before_request hook to replace fava_app.jinja_loader with a similar type of ChoiceLoader, but for all endpoints. In #1643, Fava’s default loader took precedence over the extension loader, but in my private plugin, the extension loader takes precedence. The code of my private plugin currently looks like this:

def before_request(self):
    if not current_app.jinja_loader:
        raise ValueError("Expected Flask app to have jinja_loader.")
    ext_loader = jinja2.FileSystemLoader(self.extension_dir / "templates")
    loader = jinja2.ChoiceLoader([ext_loader, current_app.jinja_loader])
    current_app.jinja_loader = loader

It would be possible to do something like the following, e.g. in applicaton.py/_perform_global_filters():

if not current_app.jinja_loader:
    raise ValueError("Expected Flask app to have jinja_loader.")

all_loaders = [
    jinja2.FileSystemLoader(x.extension_dir / "templates")
    for x in ledger.extensions._exts # is there a non-private API to get the content of _exts?
]

all_loaders.append(current_app.jinja_loader)

current_app.jinja_loader = jinja2.ChoiceLoader(all_loaders)

This would not interfere with the changes in #1658. It would be a little strange in the extension report endpoint, though: That endpoint prepends the respective extension’s FileSystemLoader again, making it appear twice in the list; but usefully also making sure that it takes precedence over the others.

If you like this proposal, I would prepare a pull request.

@yagebu yagebu added the extension Features or enhancements that have Fava extensions or could be implemented as one. label Jan 6, 2024
@yagebu
Copy link
Member

yagebu commented Jan 6, 2024

Mhh, this would be too intrusive for my taste, as it basically the "allow extension to override any function" equivalent in HTML templates. I do not want to maintain compatibility for these templates and in particular not in this direction. So an extension such functionality could/would break very easily and I do not want to provide an easy way to do this.

@yagebu yagebu closed this as completed Feb 4, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
extension Features or enhancements that have Fava extensions or could be implemented as one.
Projects
None yet
Development

No branches or pull requests

2 participants