Angular Variables rendering undefined with Flask/Jinja - python

For seemingly no reason my angular $scope variable is not rendering in the browser. My whole project has been working just fine until I created this page today. All other pages still work as expected. I've deleted all my code down to just the variable itself with the following code and its still rendering as [undefined].
I'm using python/flask to serve up the application with the jinja templating engine and therefore have changed the interpolation characters for angular so they don't conflict with the same characters in jinja:
var zues = angular.module('zues', []);
zues.config(['$interpolateProvider', function($interpolateProvider) {
$interpolateProvider.startSymbol('{{[');
$interpolateProvider.endSymbol(']}}');
}]);
Controller:
zues.controller('test', ['$scope', '$http', function($scope, $http){
$scope.test123 = "testing123";
}]);
HTML:
<body ng-app="zues" ng-controller="test">
{{[ test123 ]}}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
<script src="/static/assets/js/zues.js"></script>
<script src="/static/assets/js/Controllers/test.js"></script>
python/flask route:
from flask import Flask, render_template
import flask
application = Flask(__name__)
#application.route("/test")
def test():
return render_template('test.html')
if __name__ == "__main__":
application.run(host='127.0.0.1', reloader_type='stat', debug=True)
This renders in the browser simply as:
[Undefined]
I would have expected it to render:
testing123
Anything simple that I'm just overlooking?

I figured it out. My interpolation characters that I picked for angular were too closely related to the characters that Jinja uses by default. Jinja was taking {{[ test123 ]}} and interpreting the square brackets as plain text and then trying to find a variable test123 within my python script that didn't exist.
This didn't seem to break on the rest of the project because the angular variables I used in my html templates in the rest of the project were always bound to something else and therefore being watched by the digest loop whereas in this scenario it would only have been interpolated once.
I changed the interpolation characters to be {[{ test123 }]} so that Jinja never catches it and only angular does.

A few quick changes should help.
1) Get rid of the interpolate provider. You won't need this code if you complete 2 & 3 below.
2) Remove the close bracket ] when you close the controller definition
Yours: }]);
Mine: });
3) Add {{ ' before the set of curly braces and after ' }}
example/ {{ '{{someVariable + "" + anotherVariable}}' }}

Related

In FLASK Is there a way to run a python function while the page is open?

I got the FLASK app in which one of the routes renders a Folium Map with specific parameters. The folium map is loaded into an iframe which is being refreshed every x minutes. The map generation is triggered by html form.
Flask portion:
#app.route('/hermesmap', methods=['GET','POST'])
def hermesMap():
if request.method == "POST":
userName = request.form['username']
password = request.form['password']
server = request.form['server']
server = server[8:-1]
ascii_pass = base64.urlsafe_b64encode(password.encode("ASCII"))
sshpass = str(ascii_pass)
sshpass = sshpass.replace("b","")
sshpass = sshpass.replace("\'","")
hermesMapGen.mapUpdate(userName,sshpass,server)
return render_template("hermesMap.html")
"hermesMapGen" is generating a folium map with inserted parameters and that is the function that needs to be called every five minutes, so the map will have the updated data.
This is the HTML:
<!DOCTYPE html>
<html>
{%block content%}
<div class="custom-height-map" style="position:relative;padding-top:42.25%;border-style:solid;border-width:6px;">
<iframe src="{{url_for('static',filename='sfMarketMap.html')}}" id='hermesmap' frameborder="0" allowfullscreen
style="position:absolute;top:0;left:0;width:100%;height:100%;"></iframe>
</div>
<script>
window.setInterval(function() {
reloadIFrame()
}, 300000);
function reloadIFrame() {
console.log('reloading..');
document.getElementById('hermesmap').contentWindow.location.reload();
}
</script>
{%endblock%}
</html>
Is there a way that I can run the function that generates the map while the map page is open in the browser?
Thanks beforehand
Update:
As of the moment I was able to find a workaround with javascript.
I put the following code in the initial form page forcing it to simulate a "click" even every x minutes, but i think there should be a better/correct way of doing this.
<script>
var btn = document.querySelector("[name='lookup']");
//console.log(btn);
setInterval(function(){
btn.click();
},200000);
//Handling of click event
btn.onclick=function(){
console.log('clicked');
}
</script>
You are in the right direction.
Keep on using setInterval but this time do a fetch call to the server and get latest data.
See here about fetch.

Flask host_matching and static files when using multiple top-level domains

So I have two domains:
MAIN_DOMAIN = www.example.com
DUTCH_DOMAIN = www.voorbeeld.com
I want to use the dutch domain with Flask-Babel for i18n support.
To make this possible I'm using host_matching like this:
def create_app(config_class=Config):
app = Flask(__name__, host_matching=True,
static_host=MAIN_DOMAIN)
Finally, routing:
#bp.route('/', host=MAIN_DOMAIN)
#bp.route('/', host=DUTCH_DOMAIN)
def index():
return render_template('index.html')
I might want to change the routing part in the future. But for now this works fine.
Now for the problem, when I navigate to the dutch domain everything works, except that I get many 404 error messages because it can't find the static files. If I change the url of the static files to the MAIN_DOMAIN it works fine. Which makes sense since static_host is set to MAIN_DOMAIN.
So I just can't seem to find a solution for this problem. Is there a way to make both domains for static files work? Or how would you solve this?
Ok. So I've figured it out and actually noticed some interesting behaviour.
So when I go to the main domain. url_for works as expected, so if you would do something like this in your templates:
<script src="{{ url_for('static', filename='jquery/dist/jquery.min.js') }}"></script>
The result would be this:
<script src="/static/jquery/dist/jquery.min.js"></script>
However, when I go to the DUTCH_DOMAIN route I get:
<script src="http://www.example.com/static/jquery/dist/jquery.min.js"></script>
So you don't have to manually add _external=True to url_for for you other domains but it all happens automagically. The reason it didn't work before is because of CORS since from the browser point of view you're loading assets from a different domain instead of from the "local" website.
Hope this helps.

Python - 404 error while rendering template using flask

I am new to flask and python and I was trying to use the render template function open an URL. the 404 error keeps showing instead of the HTML that is in the templates folder.
My folder structure is as follows:
coding folder/
main.py
templates/
----profile.html
The code in my main.py file is as follows:
from flask import Flask, render_template
app = Flask(__name__)
#app.route("/profile/<name>")
def profile(name):
return render_template("profile.html", name=name)
if __name__ == "__main__":
app.run()
my profile.html file contains the following code:
<!doctype html>
<title>sambit's page</title>
<h3>Wassup {{ name }} </h3>
I have been scratching my head over this for more than 4 hours. Please Help!!!!
Are you trying to access using /profile/myname/ or /profile/myname ?
Since your route definition doesn't have a trailing slash, Flask will throw a 404 if you access that route with a trailing slash in your browser. Read more here: Doc
Though they look rather similar, they differ in their use of the trailing slash in the URL definition. In the first case, the canonical URL for the projects endpoint has a trailing slash. In that sense, it is similar to a folder on a filesystem. Accessing it without a trailing slash will cause Flask to redirect to the canonical URL with the trailing slash.
In the second case, however, the URL is defined without a trailing slash, rather like the pathname of a file on UNIX-like systems. Accessing the URL with a trailing slash will produce a 404 “Not Found” error.

Using Python CGI for a big HTML file

I have a big html file named exercise.html, I need generate to one som stuff by Python CGI.
I want to ask you what is the best way to print this HTML.
I know that it is possible by print method with using format methods %s, %i etc.:
print '''<html>
<head><title>My first Python CGI app</title></head>
<body>
<p>Hello, 'world'!</p>
.
.
<div>%s</div>
.
.
</body>
</html>''' % generated_text
But this HTML is really big,so is this only one solution?
You should consider using a templating language like Jinja2.
Here is a simple example straight from the link above:
>>> from jinja2 import Template
>>> template = Template('Hello {{ name }}!')
>>> template.render(name='John Doe')
Generally, though you save templates in a file, and then load / process them:
from jinja2 import Environment, PackageLoader
# The env object below finds templates that are lcated in the `templates`
# directory of your `yourapplication` package.
env = Environment(loader=PackageLoader('yourapplication', 'templates'))
template = env.get_template('mytemplate.html')
print template.render(the='variables', go='here')
As demonstrated above, templates let you put variables into the template. Placing text inside {{ }} makes it a template variable. When you render the template, pass in the variable value with a keyword argument. For instance, the template below has a name variable that we pass via template.render
This is my {{name}}.
template.render(name='Jaime')
Also consider Python Bottle (SimpleTemplate Engine). It is worth noting that bottle.py supports mako, jinja2 and cheetah templates.
The % indicates python code and the {{var}} are the substitution variables
HTML:
<ul>
% for item in basket:
<li>{{item}}</li>
% end
</ul>
Python:
with open('index.html', 'r') as htmlFile:
return bottle.template(htmlFile.read(), basket=['item1', 'item2'])

How to run a Python script in a web page

I'm very new to Python. I just know what Python is.
I have created the below code (in Python IDLE):
print "Hi Welcome to Python test page\n";
print "Now it will show a calculation";
print "30+2=";
print 30+2;
Then I saved this page in my localhost as index.py
I run the script using
http://localhost/index.py
But it does not show the executed Python script. Instead, it showed the above code as HTML. Where is the problem? How can I run a Python file in a web page?
In order for your code to show, you need several things:
Firstly, there needs to be a server that handles HTTP requests. At the moment you are just opening a file with Firefox on your local hard drive. A server like Apache or something similar is required.
Secondly, presuming that you now have a server that serves the files, you will also need something that interprets the code as Python code for the server. For Python users the go to solution is nowadays mod_wsgi. But for simpler cases you could stick with CGI (more info here), but if you want to produce web pages easily, you should go with a existing Python web framework like Django.
Setting this up can be quite the hassle, so be prepared.
As others have pointed out, there are many web frameworks for Python.
But, seeing as you are just getting started with Python, a simple CGI script might be more appropriate:
Rename your script to index.cgi. You also need to execute chmod +x index.cgi to give it execution privileges.
Add these 2 lines in the beginning of the file:
#!/usr/bin/python
print('Content-type: text/html\r\n\r')
After this the Python code should run just like in terminal, except the output goes to the browser. When you get that working, you can use the cgi module to get data back from the browser.
Note: this assumes that your webserver is running Linux. For Windows, #!/Python26/python might work instead.
Using the Flask library in Python, you can achieve that.
Remember to store your HTML page to a folder named "templates" inside where you are running your Python script.
So your folder would look like
templates (folder which would contain your HTML file)
your Python script
This is a small example of your Python script. This simply checks for plagiarism.
from flask import Flask
from flask import request
from flask import render_template
import stringComparison
app = Flask(__name__)
#app.route('/')
def my_form():
return render_template("my-form.html") # This should be the name of your HTML file
#app.route('/', methods=['POST'])
def my_form_post():
text1 = request.form['text1']
text2 = request.form['text2']
plagiarismPercent = stringComparison.extremelySimplePlagiarismChecker(text1,text2)
if plagiarismPercent > 50 :
return "<h1>Plagiarism Detected !</h1>"
else :
return "<h1>No Plagiarism Detected !</h1>"
if __name__ == '__main__':
app.run()
This a small template of HTML file that is used:
<!DOCTYPE html>
<html lang="en">
<body>
<h1>Enter the texts to be compared</h1>
<form action="." method="POST">
<input type="text" name="text1">
<input type="text" name="text2">
<input type="submit" name="my-form" value="Check !">
</form>
</body>
</html>
This is a small little way through which you can achieve a simple task of comparing two strings and which can be easily changed to suit your requirements.
If you are using your own computer, install a software called XAMPP (or WAMP either works). This is basically a website server that only runs on your computer. Then, once it is installed, go to the xampp folder and double click the htdocs folder. Now you
need to create an HTML file (I'm going to call it runpython.html). (Remember to move the Python file to htdocs as well.)
Add in this to your HTML body (and inputs as necessary).
<form action = "file_name.py" method = "POST">
<input type = "submit" value = "Run the Program!!!">
</form>
Now, in the Python file, we are basically going to be printing out HTML code.
# We will need a comment here depending on your server. It is basically telling the server where your python.exe is in order to interpret the language. The server is too lazy to do it itself.
import cgitb
import cgi
cgitb.enable() # This will show any errors on your webpage
inputs = cgi.FieldStorage() # REMEMBER: We do not have inputs, simply a button to run the program. In order to get inputs, give each one a name and call it by inputs['insert_name']
print "Content-type: text/html" # We are using HTML, so we need to tell the server
print # Just do it because it is in the tutorial :P
print "<title> MyPythonWebpage </title>"
print "Whatever you would like to print goes here, preferably in between tags to make it look nice"
Well, the OP didn't say server or client side, so I will just leave this here in case someone like me is looking for client side:
Skulpt is a implementation of Python to run at client side. Very interesting, no plugin required, just simple JavaScript code.
With your current requirement, this would work:
def start_html():
return '<html>'
def end_html():
return '</html>'
def print_html(text):
text = str(text)
text = text.replace('\n', '<br>')
return '<p>' + str(text) + '</p>'
if __name__ == '__main__':
webpage_data = start_html()
webpage_data += print_html("Hi Welcome to Python test page\n")
webpage_data += fd.write(print_html("Now it will show a calculation"))
webpage_data += print_html("30+2=")
webpage_data += print_html(30+2)
webpage_data += end_html()
with open('index.html', 'w') as fd: fd.write(webpage_data)
Open the index.html file, and you will see what you want.

Categories

Resources