Flask and Dynamic Template Load

Osiyo. Dohiju? Hey, welcome back.

While working on Serinda I have developed a plugin style way of adding more functionality with minimal work inside the main code. What this means is I have a plugin directory and in that directory are all of the directories containing my plugins (each plugin has it’s own directory) which includes some Python code, Javascript file, template.html, and commands.yml. I’ll cover these in more detail in another post I’m almost done with.

What I wanted to do was loop through the plugin directory and find the path to all of the template.html files and include them in a list that’s passed to the index page. In turn, each of those files are included in the rendering of the page.

Directory structure:

root
   templates
      index.html
   serinda
       plugin
           TestPlugin
               commands.yml
               template.html
               javascript.js
               TestPlugin.py

In my app.py

import jinja2

# to include multiple template paths
# https://buxty.com/b/2012/05/custom-template-folders-with-flask/
my_loader = jinja2.ChoiceLoader([app.jinja_loader, jinja2.FileSystemLoader('./')])
app.jinja_loader = my_loader

# look in the plugin directory for template files
pathlist = Path("./serinda/plugin").glob('**/template.html')

pluginTemplatePaths = []
# add the template files to the plugin path so it can be included on the page
for path in pathlist:
    pluginTemplatePaths.append(str(path))

@app.route('/')
def index():
    return render_template('index.html', pathList=pluginTemplatePaths)

If you go here they offer a way to add the current template directory AND another directory (or more) to the template path. This gives me the ability to leave the index.html file in the templates directory and work with the templating there. As you can read in the code I then loop through the plugin directory and get all of the template.html files and add them to a list as strings (there could be a better way to do this, idk). Then I pass that list to the index page.

{% for item in pathList %}
    {% include item %}
{% endfor %}

Then on the page I simply iterate over that list and include the files on the page.

As it stands there are a couple of drawbacks. Mostly, the drawbacks are around including multiple templates for one plugin. For example, if I need several html files to break out my plugin’s functionality. This could be fixed with something like switching over to React, but that’s a far future thing I need to do. For now, I’ll have to include all html and css in the one template.html file. This isn’t a huge deal, IMO, since each plugin shouldn’t have a lot of functionality to work with. They should be the equivalent of code fragments really.

I’ll have to do something similar with the javascript files. I can load the javascript files the same way and then include them at the bottom of the page. Or I can merge all of the javascript files together. I think it’s probably easier to just load and include.

That’s all for this post. Hopefully it made sense. If you have any questions please let me know.

Until next time. Dodadagohvi.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.