1

I'm rendering a template which can't find the base file to extend from.

Relevant Flask app structure:

project\
    content\
        templates\
            content\
                selection.html
        content.py
        __init__.py
    general\
        templates\
            general\
                base.html
        general.py
        __init__.py
    __init__.py

init files in content and general are blank. The app is run from the init file in project.

content.py (all works- provided for reverence):

content = Blueprint("content", __name__, template_folder="templates")

@content.route("/options")
def options():
    show_id = request.args.get("selection", "")
    removal_id = request.args.get("chosen", "")
    clear = request.args.get("reset", "")
    if "selected_shows" not in session:
        session["selected_shows"] = []
    if show_id:
        for show in library:
            if show["id"] == show_id and show not in session["selected_shows"]:
                session["selected_shows"].append({"id": show["id"], "defaultTitle": show["defaultTitle"]})
                session.modified = True
    if removal_id:
        for show in session["selected_shows"]:
            if show["id"] == removal_id:
                session["selected_shows"].remove(show)
                session.modified = True
    if clear:
        session["selected_shows"].clear()
        session.modified = True

    return render_template("content/selection.html", library=library, chosen=session["selected_shows"])

selection.html begins with this line:

{% extends "project\\general\\templates\\general\\base.html" %}

...which, in turn, raises the error:

jinja2.exceptions.TemplateNotFound: project\general\templates\general\base.html

So, here's what I know: it CAN find selection.html, but CAN'T find base.html. (Previously, I had every html file in a single templates folder in project, and it worked then, so I know it isn't an error with the way I have base.html set up- it's something about the way I'm reorganizing it to work with blueprints.)
I have tried...

  • Swapping between forward and back slashes
  • Changing how specific the file path is (as suggested in this answer), up to and including a complete path directly from my C drive
  • Moving my base.html file directly into the project folder (and changing the path accordingly)
  • Creating a new templates folder inside the projects folder and moving base.html into there (and changing the path accordingly)
  • "url_for('base.html')"

...and various combinations of the above.

Other places I've looked for answers:
This answer seems like it should work, but I've tried it and it hasn't helped.
This user has a similar file structure to mine, but the issue there is that is won't render the initial template, which mine does.
This question is very popular as a redirect, but revolves around render_template() looking for a templates folder. But render_template() doesn't seem to be what's causing me trouble here.
I have also looked at other questions here, here, here, here, here, here, here... And others.
As well as documentation here and here.

I have not ruled out the possibility that I am very stupid and have simply missed something obvious that should have already answered my question. But I have been working on this for several hours now (plus a 15 minute break), so I really hope that's not it.

Superstars111
  • 25
  • 1
  • 5

1 Answers1

0

One workaround to getting it to recognise both templates would be setting your template_folder to the base directory (in your case, 'project'):

content = Blueprint("content", __name__, template_folder="../../project")

You could then go into the desired folders from there and get your template(s).
Rendering a template would look something like this:

return render_template("content/templates/content/selection.html")

And including the base template should work with this:

{% extends "general/templates/general/base.html" %}

The reason this works as it does, is because setting template_folder applies to all the templates in that blueprint. So if you render a template from that blueprint, this template_folder will also apply to that template.

Patrick Yoder
  • 1,065
  • 4
  • 14
  • 19
  • Interesting- this works, but why? Is it that when rendering a template, all templates used by the initial one also have to be within the templates folder, and not just the one called by render_template? And are there any downsides or detriments to setting the entire project as the templates folder? – Superstars111 Apr 14 '22 at 18:33
  • Good point, I've updated my answer to include this. As for your second thought, I'm not experienced enough to give you a definite answer, but I personally wouldn't have a problem doing it, (except for the fact that we need to specify a bit more on the exact file path every time we want to render a template). I would probably try to rearrange my files to avoid this, but in your case it might be necessary to have templates in such different places. – Patrick Yoder Apr 14 '22 at 21:32