Flask Blogging Using External Files

Storing html, image, etc., not in static or templates folder

 

 

My typical production server folder structure looks like this

 

Graphical user interface, text

Description automatically generated

 

In the image above, applications  gets repo’ed in github. Posts will be updated only on the production machine. My code gets updated on my home machine. Therefore when I push an update the contents of applications/personalWebsite will be updated with the repo and all the posts since the last update will be erased/lost/whathaveyou by the git refresh. By having all my production data (i.e. database, posts templates, images) in the database/personalWebsite folder, I can now refresh to my hearts desire and the production data is wholly unaffected.

 

The reason for this mixup I the post templates data. I’m not sure most people store their blogposts in html templates, but using word to convert to html has been a great way to do it and here is an article where I go into the framework.

 

Using External templates

 

 

Here is sample code to explain what I am doing.

 

Imports

import jinja2

 

Route to reach the template

@blog.route("/<post_id_name_string>")

def blog_article(post_id_name_string):

 

    templates_path_lists = [

        os.path.join(current_app.config.root_path,"templates"),

        os.path.join(current_app.config.get('DB_ROOT'),"posts", post_id_name_string)

    ]

 

    templateLoader = jinja2.FileSystemLoader(searchpath=templates_path_lists)

 

    templateEnv = jinja2.Environment(loader=templateLoader)

    template = templateEnv.get_template("blog/view_post.html")

    template_layout = templateEnv.get_template("_layout.html")

    template_post_index = templateEnv.get_template("index.html")

    template_post_table = templateEnv.get_template("closuresInSwift.html")

    # template_post_image = templateEnv.get_template("handwaveEmoji.png")

 

    image_file = os.path.join(current_app.config.get('DB_ROOT'),"posts", post_id_name_string, "handwaveEmoji.png")

 

 

    return template.render(template_layout=template_layout, template_post_index=template_post_index, \

        template_post_table=template_post_table,  \

        url_for=url_for, get_flashed_messages=get_flashed_messages)

 

 

Step 1: get list of all directories I plan to pull html templates from

Step 2: create jinja2.FileSystemLoader object that takes the list of “templates” folders

Step 3: create template objects that use the jinja2.FileSystemLoader object and take in the path to the html template relative to any of the “templates” paths I entered in the list

 

Then to render the template form the route I use

Templates.render()

 

Inside the render parentheses I can pass jinja arguments just like I would with render_template. I can even pass in other template objects and have them rendered within the routes parent template (“template” in code above).

 

External Static folders

To get images from a directory outside of the static folder I create a route that I can call from the template. The route uses send_from_directory() and the arguments I pass are the direcetory and file name. IN this case I have a directory where I am keeping all my posts. Inside each post there is directory for the posts themselves. There I’ll keep an html file that is called index and whatever else belongs to the post.

 

 

# Custom static data

@blog.route('/<post_id_name_string>/<filename>')

def custom_static(post_id_name_string,filename):

    return send_from_directory(os.path.join(current_app.config.get('DB_ROOT'),"posts", post_id_name_string), filename)

 

 

From inside the jinja template /html file (or index.html, if we’re continuing with the example from above), I call an image like this with url_for() the route method and the arguments for the specific blogpost directory and file name I am using

 

Text

Description automatically generated

 

One issue, I have not resolved yet, is I cannot put jinja syntax (i.e. double curly braces) anywhere in my posts, unless they are images. Hence image for code above.

 

 

 

 

Source:

https://stackoverflow.com/a/9519004/11925053

 

Why?

The reason to do this is so that I can just move update the application without deleting the blog posts. I was keeping everything in the templates and static directories and then making sub directories for each post. But each time I push an update I’d either have to keep all the posts in the application repository or manually move things in and make sure the database matches. Now, I can keep the database and all the blogpost files together and independently make changes to the website.