How do I get Flask to serve my .js files? - javascript

I am doing some coding with Python, Flask and .js files all with some HTML and CSS linked in as well. My problem is that I have a dropdown menu and a button that can hide and unhide password text but when running in Flask, this side of things is not working and I believe that it has something to do with the javascript. This function works perfectly when I am running the HTML file locally and not through flask, but I am completely lost as to where to go from here?
In terms of what I have done already is to ensure that my file structure is correct and that these .js files are within the static folder (where CSS stylesheets are being pulled from perfectly fine). My script tags where I link the .js files are all at the end of the body tag and do not sit within the head tag.
<script src="../static/js/vendor/jquery.js"></script>
<script src="../static/js/app.js"></script>
<script src="../static/js/vendor/foundation.js"></script>
<script src="../static/js/vendor/what-input.js"></script>
This is the app file that I am using for Flask and the simple code used to run this if it helps?
from flask import Flask
from flask import render_template
app = Flask(__name__)
#app.route("/")
def render_static():
return render_template('splash_page.html')
#app.route("/account")
def account_page():
return render_template('account.html')
if __name__ == '__main__':
app.run(debug = True)
Below you will find my HTML code used as a template in Flask, this is it before the changes suggested below -
<!doctype html>
<html class="no-js" lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Home Page</title>
<link href="../static/css/app.css" rel="stylesheet" type="text/css">
<link href="../static/css/foundation.css" rel="stylesheet" type="text/css">
</head>
<body>
<div class="top-bar">
<div class="top-bar-left">
<ul class="dropdown menu" data-dropdown-menu>
<li class="menu-text">Premier League Pro</li>
<li>
Account
<ul class="menu vertical">
<li>My Account</li>
<li>Settings</li>
<li>Log Out</li>
</ul>
</li>
<li>Predictor</li>
<li>Odds Calculator</li>
</ul>
</div>
<div class="top-bar-right">
<ul class="menu">
<li><input type="search" placeholder="Search"></li>
<li><button type="button" class="button">Search</button></li>
</ul>
</div>
</div>
<div class="row">
<div class="columns large-3"></div>
<div class="columns large-6">
<br>
<br>
<form class="show-password">
<label for="username">Your login</label>
<input type="text" value="" placeholder="Enter Username" id="username">
<div class="password-wrapper">
<label for="password">Your password</label>
<input type="password" value="" placeholder="Enter Password" id="password" class="password">
<button class="unmask" type="button" title="Mask/Unmask password to check content">Unmask</button>
</div>
</form>
</div>
<a class="button small" href="#">Sign In</a>
<div class="columns large-3"></div>
</div>
<script src="../static/js/app.js"></script>
<script src="../static/js/vendor/foundation.js"></script>
<script src="../static/js/vendor/what-input.js"></script>
<script src="../static/js/vendor/jquery.js"></script>
</body>
</html>
If it helps to mention I am using Foundation as a CSS to help edit and make my webpages look nice.
When using the methods suggested below in terms of changing the script tags I get an error in the browser as follows -
jinja2.exceptions.TemplateSyntaxError: expected token ',', got 'static'

you should link your js files using this:
<script src="{{ url_for('static', filename='js/vendor/jquery.js') }}"></script>
do this for all js files.
Hope that helps. If you still have any problem, please let me know.
for further investigation enable flask debug mode
To enable debug mode you can export the FLASK_DEBUG environment variable before running the server:
$ export FLASK_DEBUG=1
$ flask run
this will show you more detailed errors and stack traces in the browser.

Jinja2 is a modern and designer-friendly templating language for Python. https://jinja2docs.readthedocs.io/en/stable/
https://jinja.palletsprojects.com/en/2.11.x/templates/
Try surrounding the script tag in your template with these two Jinja2 syntactic structures below:
{% block javascript %}
<script src="{{ url_for('static', filename='js/vendor/jquery.js') }}"></script>
{% endblock %}
I vaguely recall Flask serving Javascript without this block once, but that was with Python 2.7. Maybe it's a bug.
It's probably a security feature to prevent XSS.

Related

JQuery - HTTP 404 NOT FOUND - The server has not found anything matching the requested URI

I'm working on teaching myself front-end dev, and ran into an issue with getting jquery to work. I have all my site posted here: http://mike.shea.sdf.org
What should happen is between the header and the nav buttons, there should be blog postings. The entries are hand coded into the postBuilder.js file which (along with helper.js and the jquery lib) should generate the HTML to display the posts.
It has the following structure:
html
index.html
blog.css
js
jquery-2.2.1.min.js
helper.js
postBuilder.js
I have read/exe rights on everything.
All is fine when tested locally on my own machine, but when posted up to the server I get this on the console:
HTTP404: NOT FOUND - The server has not found anything matching the requested URI (Uniform Resource Identifier).
GET - http://mike.shea.sdf.org/js/jQuery-2.2.1.min.js
If I put everything under the root html folder, it works. I'm reasonably sure that i have the relative paths typed in correctly. Again, locally the files have the same structure and they work. If you look at the source, you'll see that I tried more than one jQuery lib file and tried putting it in the root html folder as well. I'm really not sure what to look at next. Here is the html file:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
<meta name="description" content="">
<meta name="author" content="">
<title>Contemplating Tech</title>
<!-- Bootstrap core CSS -->
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet">
<!-- Custom styles-->
<link href="blog.css" rel="stylesheet">
<script src="/js/jQuery-2.2.1.min.js"></script>
<!-- <script src="./jQuery-2.2.1.min.js"></script> -->
<!-- <script src="https://code.jquery.com/jquery-2.2.1.js></script> -->
<script src="/js/helper.js"></script>
</head>
<body>
<div class="blog-masthead">
<div class="container">
<nav class="blog-nav">
<a class="blog-nav-item active" href="#">Home</a>
<a class="blog-nav-item" href="#">New features</a>
<a class="blog-nav-item" href="#">About</a>
</nav>
</div>
</div>
<div class="container">
<div class="blog-header">
<h1 class="blog-title">Contemplating Tech</h1>
<p class="lead blog-description">Personal musings about technology, web development and whatever else I come across.</p>
</div>
<div class="row">
<div id="posts" class="col-sm-8 blog-main">
<script src="/js/postBuilder.js"></script>
<nav>
<ul class="pager">
<li>Previous</li>
<li>Next</li>
</ul>
</nav>
</div><!-- /.blog-main -->
<div class="col-sm-3 col-sm-offset-1 blog-sidebar">
<div class="sidebar-module sidebar-module-inset">
<h4>About</h4>
<p>Mike has been involved with desktop support in one manner or another for 20+ years. This will be both a personal blog and a sandbox as he works on improving his front end web development skill set.</p>
</div>
<div class="sidebar-module">
<h4>Archives</h4>
<p>When I get a little better at getting posts in here and finding how to create an archive, I'll populate a list here.</p>
<!--<ol class="list-unstyled">
<li>March 2014</li>
<li>February 2014</li>
<li>January 2014</li>
<li>December 2013</li>
<li>November 2013</li>
<li>October 2013</li>
<li>September 2013</li>
<li>August 2013</li>
<li>July 2013</li>
<li>June 2013</li>
<li>May 2013</li>
<li>April 2013</li>
</ol>-->
</div>
<div class="sidebar-module">
</div>
<div class="sidebar-module">
<h4>Elsewhere</h4>
<ol class="list-unstyled">
<li>GitHub</li>
<li>Twitter</li>
</ol>
</div>
</div><!-- /.blog-sidebar -->
</div><!-- /.row -->
</div><!-- /.container -->
<footer class="blog-footer">
<p>Blog template built for Bootstrap by #mdo.</p>
<p>
Back to top
</p>
</footer>
<!-- Bootstrap core JavaScript
================================================== -->
<!-- Placed at the end of the document so the pages load faster -->
<!-- <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script> -->
<!-- <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script> -->
</body>
</html>
Any and all help or suggestions are appreciated!
When I look at your page and navigate to the location specified in your source code (http://mike.shea.sdf.org/js/jQuery-2.2.1.min.js), I too get the 404 error.
Now, I can navigate to your helper.js file, which seems to have the same path, so you need to triple check the naming of the jQuery file.
Also, (as an aside) and as I mentioned in my comment, you have a leading forward-slash in your link (/) to the jQuery file. This means that the js folder is a sub-folder of the root of your server, which may not be the same as a sub-folder of your HTML folder that you talk about. Remove the forward-slash from the link and make sure that the js folder is a child of the folder where the HTML file is.

Django: return HTML file including script

I am working on a single page application called 'bookMarks' using HTML+CSS+jQuery as the front end and Django as my back end. I created a Django project and put my app.html+app.js+app.css+jquery.js in /static.
My question is: I would like my view to return the app.html as it should be without using Django template. I have tried this:
#app/views.py
from django.shortcuts import render_to_response, HttpResponse
import urllib
def index(request):
index = urllib.urlopen('static/app.html').read()
return HttpResponse(index)
#static/app.html
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<title>My Bookmarks</title>
<link type="text/css" rel="stylesheet" href="app.css">
<script src="jquery.js"></script>
<script type='text/javascript' src="app.js">
jQuery.noConflict();
</script>
</head>
<body>
<div id="title">
Easy-Save Bookmarks
</div>
<div class="left">
<h3 class="tag">News</h3>
<div>
<p> A book mark here!</p>
</div>
<h3 class="tag">Reading</h3>
<div>
<p> A book mark here!</p>
</div>
<div id="newTag"></div>
<div>
<form name="addTagForm">
<input type="text" name="newTag">
<input id="addTag" type="button" value="Add a new tag">
</form>
</div>
</div>
<div class="right">
</div>
</body>
</html>
But it seems that all JS and CSS effects are ignored.
Could someone help me to fix this?
Finally I found that's because I didn't include my js+css files in the absolute way.
Now when I put my HTML+JS+CSS files in my_app/static/, and include absolute
The view will return my html correctly.

MVC4 $ is undefined

In Visual Studio 2013 I made a new project based on the default MVC4 Intranet template.
In the _Layout.cshtml I added some custom code to add a test link in a div container.
<!DOCTYPE html>
<html lang="en">
<head>
#Scripts.Render("~/bundles/jquery","~/bundles/modernizr")
<meta charset="utf-8" />
<title>#ViewBag.Title - My ASP.NET MVC Application</title>
<link href="~/favicon.ico" rel="shortcut icon" type="image/x-icon" />
<meta name="viewport" content="width=device-width" />
#Styles.Render("~/Content/css")
</head>
<body>
<header>
<div class="content-wrapper">
<div class="float-left">
<p class="site-title">#Html.ActionLink("your logo here", "Index", "Home")</p>
</div>
<div class="float-right">
<section id="login">
Hello, <span class="username">#User.Identity.Name</span>!
</section>
<nav>
<ul id="menu">
<li>#Html.ActionLink("Home", "Index", "Home")</li>
<li>#Html.ActionLink("About", "About", "Home")</li>
<li>#Html.ActionLink("Contact", "Contact", "Home")</li>
</ul>
</nav>
</div>
</div>
</header>
<div id="body">
#RenderSection("featured", required: false)
<section class="content-wrapper main-content clear-fix">
#RenderBody()
</section>
<div id="test"></div>
</div>
<footer>
<div class="content-wrapper">
<div class="float-left">
<p>© #DateTime.Now.Year - My ASP.NET MVC Application</p>
</div>
</div>
</footer>
#RenderSection("scripts", required: false)
<script type="text/javascript">
$(function () {
$("#test").append("<a href='#'>test linkje</a>");
});
</script>
</body>
</html>
When I press F5 and go into Internet Explorer 10 everything is working fine. The problem starts occuring when a HTML Actionlink is clicked. Then Visual Studio comes in between with the error message:
0x800a1391 - JavaScript runtime error: '$' is undefined
After pressing continue and hitting F5 in the browser its working again.
I dont have this problem when running it in Firefox or Chrome. Even when im running it in Chrome or Firefox and I am pasting the url in IE 10 its working fine.
Seems to me running it under IE10 directly messing things up.
Hopefully someone has a solution for this strange error, since all the code is just fine.
Thanks in advance.
It means that a jQuery function is triggered before jQuery is loaded. Are you sure that all the required scripts are in the bundles you load at the start of the page? Also it's best practice to load your scripts at the end of the page (better performance).
<html>
<head> ... </head>
<body>
...
#Scripts.Render("~/bundles/jquery","~/bundles/modernizr")
#RenderSection("scripts", required: false)
<script type="text/javascript">
$(function () {
$("#test").append("<a href='#'>test linkje</a>");
});
</script>
</body>
</html>

jquery mobile app does not show styled text on iPhone

I am trying to build my first project for iOS using PhoneGap. I have picked up an example from this page:
http://www.codeproject.com/Articles/579532/Building-an-iPhone-App-using-jQuery-Mobile
And my code looks like this after changing reference to 1.4.1 ans 1.9:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" name="viewport" content="width=device-width, initial-scale=1">
<title>Task Timer</title>
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.4.1/jquery.mobile-1.4.1.min.css" />
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script src="http://code.jquery.com/mobile/1.4.1/jquery.mobile-1.4.1.min.js"></script>
</head>
<body>
<div id="tasksPage" data-role="page">
<div data-role="header" data-position="fixed">
Edit
<h1>Task Timer-1</h1>
Add
</div>
<div data-role="content">
<ul id="taskList" data-role="listview">
<li onclick="alert(1)">Task 1</li>
<li onclick="alert(2)">Task 2</li>
</ul>
</div>
<div data-role="footer" data-position="fixed">
About
</div>
</div>
</body>
</html>
This page, if you copy to an html file will display formatted text. However when I copy the App to iPhone it displays simple text.
Can someone please tell me what I am doing wrong?
I think I have just solved the issue.
I made a reference to cordova.js in main html file. And as a precaution copied cordova.js to www folder. And the text started appearing formatted the JQM way.

deviceTheme.js and dojo.js can not be loaded in Chrome

I am following dojo mobile tutorial for Part 2 - Developing a Dojo Mobile Application: FlickrView.
But when I tried examples in that tutorial, I found that //ajax.googleapis.com/ajax/libs/dojo/1.9.2/dojox/mobile/deviceTheme.js and //ajax.googleapis.com/ajax/libs/dojo/1.9.2/dojo/dojo.js can not be loaded in my test html below, these two js file loaded successfully in demo page
Am I do something wrong?
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
<meta name="apple-mobile-web-app-capable" content="yes"/>
<!-- prevent cache -->
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="pragma" content="no-cache">
<title>Dojo Mobile tutorial | Flickrview | Part II | HTML Structure</title>
<!-- application stylesheet -->
<link rel="stylesheet" type="text/css" href="css/flickrview.css">
<!-- dynamically apply native visual theme according to the browser user agent -->
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/dojo/1.9.2/dojox/mobile/deviceTheme.js"></script>
<!-- dojo configuration options -->
<script type="text/javascript">
dojoConfig = {
async : true,
baseUrl : './',
parseOnLoad : false,
mblHideAddressBar : true,
packages : [{
name : "flickrview",
location : "js"
}]
};
</script>
<!-- dojo bootstrap -->
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/dojo/1.9.2/dojo/dojo.js"></script>
<!-- dojo application code -->
<script>
// Load the widget parser and mobile base
require(["dojox/mobile/parser", "dojox/mobile/compat", "dojo/domReady!"], function(parser) {
// Parse the page for widgets
parser.parse();
});
</script>
</head>
<body>
<!-- Feed view -->
<div id="feed" data-dojo-type="dojox/mobile/ScrollableView" data-dojo-props="selected: true">
<div id="feedHeading"
data-dojo-type="dojox/mobile/Heading"
data-dojo-props="fixed: 'top', label: 'Feeds'">
<span data-dojo-type="dojox/mobile/ToolBarButton"
data-dojo-props="icon: 'images/settings.png', moveTo:'settings', transitionDir:'-1', transition:'none'"
style="float:left;"></span>
<span id="refreshButton" data-dojo-type="dojox/mobile/ToolBarButton"
data-dojo-props="icon: 'images/refresh.png'"
style="float:right;"></span>
</div>
<div id="feedList" data-dojo-type="dojox/mobile/EdgeToEdgeList">
<div data-dojo-type="dojox/mobile/ListItem"
data-dojo-props="moveTo:'details', transition:'slide'" class="photoListItem">
<img src="images/photo1.png" width="80px" height="80px" alt="Title" style="float:left;"/>
<div class="photoSummary">
<div class="photoTitle">
Photo title here
</div>
<div class="publishedTime" data-dojo-time="2013-12-13">
published date here
</div>
<div class="author">
author here
</div>
</div>
<div class="summaryClear"></div>
</div>
<div data-dojo-type="dojox/mobile/ListItem"
data-dojo-props="moveTo:'details', transition:'slide'" class="photoListItem">
<img src="images/photo2.png" width="80px" height="80px" alt="Title" style="float:left;"/>
<div class="photoSummary">
<div class="photoTitle">
Another photo title here
</div>
<div class="publishedTime" data-dojo-time="2013-12-13">
published date here
</div>
<div class="author">
author here
</div>
</div>
<div class="summaryClear"></div>
</div>
</div>
</div>
</body>
</html>
Here's error message in Chrome.
To use the protocol-less version of the url (like //ajax.googleapis.com) you have to host your project somewhere (either on a local or a remote webserver).
You can not just open the file (using the file:// prefixed URL), because then it won't be able to find the specified libraries. What actually happens if you load such a URL is that the same protocol-prefix is used to load these pages. If you load a page just by opening the file, it will have a file:// prefix and not http:// or https://.
This is also the reason why it is working on the demo page (because it is hosted) and why you get these GET errors, it's trying to find ajax.googleapis.com on your local machine (due to the file:// protocol), which it obviously can't find.
To fix it you just use the full URL, for example:
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/dojo/1.9.2/dojo/dojo.js"></script>
Or a better solution is to put your project on a webserver (nginx, apache2, ...), because I don't think you will be able to load asynchronous modules either.

Categories