I am building a Python/Flask based web app. The python script produces a dictionary of words and their corresponding weights. I have a javascript file (let's call it custom.js
), which I call from the output.html. The way this javascript works is that it takes this dictionary and then uses d3.v3.min.js
and d3.layout.cloud.js
to create a wordcloud. When the dictionary is hard-coded into custom.js
, the output file shows the wordcloud. However, the dictionary values will change depending on other parameters in the python script. Therefore, I would like to pass this dictionary from Python to custom.js
. I am not sure how to do that.
I know that the parameters could be passed to HTML using {{ params |safe }}
, but I am trying to figure out how to do that so that custom.js
will receive the parameters (dictionary of words and weights, in this case) and word clouds can be rendered dynamically.
Thank you in advance!
I am building a Python/Flask based web app. The python script produces a dictionary of words and their corresponding weights. I have a javascript file (let's call it custom.js
), which I call from the output.html. The way this javascript works is that it takes this dictionary and then uses d3.v3.min.js
and d3.layout.cloud.js
to create a wordcloud. When the dictionary is hard-coded into custom.js
, the output file shows the wordcloud. However, the dictionary values will change depending on other parameters in the python script. Therefore, I would like to pass this dictionary from Python to custom.js
. I am not sure how to do that.
I know that the parameters could be passed to HTML using {{ params |safe }}
, but I am trying to figure out how to do that so that custom.js
will receive the parameters (dictionary of words and weights, in this case) and word clouds can be rendered dynamically.
Thank you in advance!
Share Improve this question asked Jun 19, 2017 at 1:19 bluetoothbluetooth 55910 silver badges23 bronze badges 2-
Based on @Nurzhan's suggested link, I modified the app.py code as:
tps = [ {'text': 'even', 'size': 180}, {'text': 'great', 'size': 49}] return render_template('results3.html',tps=tps)
. Added a function to mycustom.js
asfunction myFunc(tps) {return tps;} d3.layout.cloud().size([300, 300]) .words(tps) .rotate(0).....
and the script section of my HTML as ``` <script type="text/javascript" src="./static/custom.js"></script> <script type="text/javascript"> tps = myFunc({{tps|safe}}); </script> ```. What am I doing wrong? – bluetooth Commented Jun 19, 2017 at 21:04 -
tps should be a dictionary {...}, not a list [...]. In
{{ tps | safe }}
changesafe
totojson
. – Nurjan Commented Jun 20, 2017 at 1:15
3 Answers
Reset to default 2If I understood you correctly you need to create a view function (a route) in the flask backend with url like this /get_dictionary
. This function can look like this:
from flask import request, jsonify ...
@app.route('/get_dictionary'):
def get_dictionary():
...
your_dictionary = []
# Fill in your_dictionary with data
...
render_template('your_template.html', your_dictionary=your_dictionary)
EDIT:
You can pass the data from flask to script section of the html template using standard jinja2 notation:
<html>
<head>
<script>
your_dictionary = {{ your_dictionary | tojson }}
<!-- Do what you need with your_dictionary -->
</script>
...
</head>
...
you can try define a var in your template html, like this:
<script>
var your_var = '{{ value }}'
</script>
then use "your_var" in external js file. But please make sure above definition is at ahead of your js file refer.
So Flask does have a way to do this, but it's kind of hacky and took forever for me to finally find and figure out the solution- I was having this problem too.
There's 3 parts to this:
- Get the dictionary information in Python
- Embed the data into your webpage
- Access that data from your JavaScript/TypeScript code
Step 1
Setup the Python dictionary for external use
Somewhere in your Flask code in either the __init__.py
file, the routes.py
file, or some other similarly accessible file, have the following setup:
all = {"some":"random data"}
@server.context_processor
def inject_data() -> dict:
# .context_processor information: https://stackoverflow./a/43336023/8705841
flask_data = {'all',
'the',
'python',
'variables',
'you',
'want',
'in',
'your',
'js_or_ts'}
# Create a dictionary from a list of variables: https://stackoverflow./a/9496018/8705841
return {'flask_data': dict(((k, eval(k)) for k in flask_data))}
The @server
part should match the name of your Flask app variable (instantiated with server = Flask(__name__)
) and does not particularly matter (usually it's called app
). The flask_data
dict/list should have all the Python variables you want ported over to the front end, but with quotes around them- the eval
part of the return will grab the Python variable that matches the input string k
.
Step 2
Make the data available on the webpage
In your index.html
page, inside the <head>
tag (next to your other <script>
tags, have this tag as well:
<head>
<!-- a whole bunch of stuff -->
<!-- get all the Flask variables from Python -> TypeScript -->
<script id=flask_data type="text/json">{{ flask_data|tojson }}</script>
<!-- possibly a whole bunch more stuff -->
</head>
Basically every single StackOverflow post even mentioning Flask has the above copy-pasted.
Step 3
Access the data from any of your JavaScript files
This is the part that no one else talked about- actually using your data from within your JavaScript (or TypeScript) code, regardless of your directory setup. It's a little hacky, but basically you access the HTML element that has your embedded data and then parse it for use in your program however you want. This is technically TypeScript code, but should work for both JavaScript and TypeScript (it took a ton of trial and error to finally get it to work on my TypeScript build).
foo() {
const flask_data = JSON.parse((document.querySelector('#flask_data') as HTMLElement).textContent || "");
this.version = flask_data.version
const my_flask_var = flask_data.my_flask_var;
console.log("Data: " + flask_data);
console.log("Variable: " + my_flask_var);
console.log("Running verison '" + this.version + "'");
if (my_flask_var === "some value") {
do_something();
else {
do_something_else();
return my_flask_var;
}
}
// the rest of your program, using any part of the flask_data dictionary however you need
// .
// .
// .
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745492850a4630063.html
评论列表(0条)