2

Maybe there's a better way to do this, but I'm trying to organize my Flask application so that both static Javascript and HTML templates sit in the same folder (similar to components)

This is just for organization purposes, I won't be rendering the statics in jinja2

So, instead of this :

├── templates/ │ ├── login.html ├── static/ │ ├── login.js 

I'm looking for this (just an idea):

├── components/ │ ├── login/ │ │ ├── login.html │ │ └── login.js 

Or maybe this, so I can make a wrapper that renders a component just by its folder name, ex: return render_component('login')

├── components/ │ ├── login/ │ │ ├── template.html │ │ └── login.js 

The concept is that inside login.html template it adds a script tag with url_for to login.js

I'm also open to different ideas/ways to achieve this component structure

2
  • 1
    then your templates will also be accessible as static files, why not have a startup script which copies static files from your templates folder to static folder. Commented Jun 28, 2019 at 14:26
  • Acessible by who? The developer? That's okay to me Commented Jun 28, 2019 at 17:52

2 Answers 2

1

I'm sure there are other ways to achieve this but one way is to use blueprint structure and contain all static files for that specific blueprint inside the blueprint folder.

app |- collections | - blueprint_one | - configs | - static | - css | - js | js_file_one.js | - templates | - blueprint_one | html_file_one.html | blue_print_one_view_file_one.py | __init__.py | - blueprint_two | - blueprint_three |- static | - js | - css |- templates __init__.py 

Above folder structure allows you to separate out not only the static files but also the Flask view files.

Below are examples of activating/importing files:

1) app/init.py

app = Flask(__name__, static_folder='static') app.config.from_pyfile('app_config.py') # Do all your db set up and etcs.. # Import blueprints below set ups to prevent circular import app.collections.blueprint_one import blueprint_one app.collections.blueprint_two import blueprint_two # Now register blueprints that you've imported app.register_blueprint(blueprint_one, url_prefix='/blueprint_one') app.register_blueprint(blueprint_two, url_prefix='/blueprint_two') 

2) blueprint_one/init.py

# Create a blueprint from flask import Blueprint blueprint_one = Blueprint('blueprint_one_name', __name__, template_folder='templates', static_folder='static') # Import required views to use from . import blue_print_one_view_file_one.py 

3) blueprint_one/blue_print_one_view_file_one.py

# Import blueprint from app.collections.blueprint_one import blueprint_one # Any view functions using above blueprint @blueprint_one.route('/login/, methods=['GET']) def login(): return render_template('blueprint_one/html_file_one.html') 

4) blueprint_one/templates/blueprint_one/html_file_one.html

// Note: instead of .static, you can use blueprint_one.static. <script type="text/javascript" src="{{ url_for('.static', filename = 'js/js_file_one.js') }}"></script> 

5) app/static and app/templates still can be used as you are using it currently.

This solution doesn't solve the problem of putting js and html into same folder but at least you can divide each feature into component like blueprint for more modularized project structure.

Sign up to request clarification or add additional context in comments.

Comments

1

There isn't a best way to do this so I like to suggest that you review the way flask projects are supposed to be set up.

http://flask.pocoo.org/docs/1.0/tutorial/layout/

Also I think this question may have an answer that solves your problem here.

Flask url_for URLs in Javascript

Now here's a few thoughts. To me it sounds like you want to use Templating in files that are in your static folder. This is not what the static folder is intended for. Static means unchanging, so the files in your static folder should not change. Templates are intended to be dynamic which usually means that they change. If you plan to render templates from files in your static directory you will encounter numerous issues and possibly even not be able to do it. One of the most prominent issues I can see you possibly encountering is that browsers will not want to grab the new javascript files if it thinks they're in your static directory. Browsers may assume they haven't changed. Also Flask does some magic behind the scenes. When a url for a file in your static directory is processed from a client who has already requested the file flask returns HTTP CODE 304 which essentially means "File hasn't changed".

I could go on and on about why you shouldn't do this. Instead, if none of information above solves your question, I would like to suggest that you put your javascript templates in a sub-directory of your template directory. Then use the following code to return them.

@app.route('/js/<file_name>',methods=['GET']) def get_js_templates(file_name): return render_template('js/'+file_name) 

I am by no means an expert in any capacity but I have done full stack development using the flask web framework. If you have more questions leave a comment on this post.

2 Comments

I am not trying to render my statics, all I want is for them to sit in the same folder as the html just for organization really, in the end its all the same.
then I have no idea what you're asking. Anything you put in your static directory can be accessed with url_for('static','sub_directory/file_name.file_extension') which generates a url similar to the following current_domain/static/sub_domain/file_name.file_extension and returns the raw file if it has changed since the last time it was requested by the requestor.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.