简体   繁体   中英

Structuring Flask App with Javascript

So I'm having trouble with deciding on where to place my javascript in my Flask app. I currently have my scripts on each of my templates, but was planning to put it in the static folder, however, values don't get assigned through the flask app. What I'm asking is how would I want to structure my app in terms of wanting to alter variables in my javascript. An example of how I'm currently changing variables is below in the HTML script.

File structure:

static/
    css
templates/
    example.html
app.py
main.py

Flask:

@app.route('/')
def index():
    a = 10
    return render_template("index.html", a=a)

HTML:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title> Example </title>
</head>
<body>
    <!-- Javascript files -->
    <!-- Contents -->
    <script>
    var a = {{ a }};
        alert(a);
    </script>
</body>
</html>

It's always a good idea to keep your javascript files separated from html templates. However, sometimes you need to pass some data from python directly to javascript. The best approach at the moment, in my opinion, would be to pass the desired data as a JSON response from your FLASK app and catch that data using AJAX or Jquery, etc.

In case you want to just keep it simple, you should separate javascript code that somehow interacts with your python code from code that does not. The latter should be in a static folder, while dynamic code can be placed into special block.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title> Example </title>
</head>
<body>
    <!-- Javascript files -->
    <!-- Contents -->
    {% block extra_js %}
    <script>
    var a = {{ a }};
        alert(a);
    </script>
    {% endblock %}
</body>
</html>

Here you have a nice {% extra_js %} block inside the main template that will allow adding some javascript code in child templates easy enough.

It kind of depends. I personally save javascript files like bootstrap.js and jquery.js in static/ , but javascript files which need access to my routes and/or variables returned from python I often also store within the html template. You could bypass this by sending ajax requests to an api route, but that's not ideal either in a lot of cases, and add a lot of extra overhead.

Here is another way to dynamically render js, but still keep it in its own files.

test.py

from flask import Flask, render_template_string, render_template
app = Flask(__name__)


@app.route('/')
def hello_world():
    js = render_js('static/test.js', a="wow")
    return render_template('test.html', js=js)


def render_js(fname, **kwargs):
    with open(fname) as fin:
        script = fin.read()
        rendered_script = render_template_string(script, **kwargs)
        return rendered_script

static/test.js

var a = "{{ a }}";
    alert(a);

templates/test.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title> Example </title>
</head>
<body>
    <h2>nice</h2>
<script>
{{js|safe}}
</script>
</body>
</html>

I don't prefer it over just rendering the js in the html directly, but it's a possibility.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM