I'm working on an html form page using a template which can be found here. The template works as expected, however when I include a URL parameter, the page loses its CSS.
Works:
#app.route('/add', methods=['GET', 'POST'])
def add_form():
return render_template('form.html')
Doesn't work:
#app.route('/add/<param>', methods=['GET', 'POST'])
def add_form(param):
return render_template('form.html')
I've worked with URL parameters in the past and never had this problem, what could be causing this behaviour?
Check if your CSS files are included with relative path f.e.
<link rel="stylesheet" type="text/css" href="css/main.css">
If there is no lead slash then files are relative to the given path.
In the first case, it will be relative to / (last part omitted)
in the second case, it will be relative to /add/.
Try change path from above to
<link rel="stylesheet" type="text/css" href="/css/main.css">
with a leading slash.
Related
I'm trying to keep things minimal, so I don't want to create templates, directory structures, etc. I have a simple CSS file available on the web (via RawGit) and I want to use it to style the page generated by a view. How can I render a page without templates?
from flask import Flask
application = Flask(__name__)
# <insert magic here>
# application.get_and_use_my_super_cool_CSS_file(URL)
# <insert magic here>
#application.route("/")
def hello():
return "hello world"
if __name__ == "__main__":
application.run(host = "0.0.0.0")
If you don't want to write templates as separate files, you can use render_template_string instead. This is typically not a very useful feature, as it becomes difficult to maintain large templates written as Python strings. Flask's Jinja env also provides some extra help when rendering files it recognizes, such as turning on autoescape for HTML files, so you need to be more careful when rendering from strings directly.
return render_template_string('''<!doctype html>
<html>
<head>
<link rel="stylesheet" href="css url"/>
</head>
<body>
<p>Hello, World!</p>
</body>
</html>
'''
My bottle web application is not serving my main.css file despite the fact I am using the static_file method.
app.py
from bottle import *
from xml.dom import minidom
#route('/')
def index():
return template("index")
#route('/glossaryXML')
def glossary():
doc_def = minidom.parse("table_definitions.xml")
terms = doc_def.getElementsByTagName("str_term")
defins = doc_def.getElementsByTagName("str_definition")
return template("list", terms=terms, defins=defins)
#route('<filename>.css')
def stylesheets(filename):
return static_file(filename, root='static')
#error(404)
def fourofour(error):
return "Error"
run(host='localhost', port=8080, debug=True)
The page I am trying to access is the index page, in which index.tpl looks like
<!DOCTYPE HTML>
<html>
<head>
<title>ICT Applications Glossary</title>
<link type="text/css" href="main.css" rel="stylesheet">
</head>
<body>
It works
</body>
</html>
My CSS file is located in a folder named "static" which is in my root folder
Instead specify your static route like this
#route('/<filename:path>')
def send_static(filename):
return static_file(filename, root='static/')
This will serve any file in your static directory though not just css.
To make it stylesheet specific
#get('/<filename:re:.*\.css>')
def stylesheets(filename):
return static_file(filename, root='static/')
Note: for the latter option you could put stylesheets in their own directory 'static/css' or just 'css' and keep them separate from other static resources (scripts, images etc.) to do this just specify the root parameter to be that directory e.g. `root='static/css'.
There are 2 problems that I can see:
The route for the CSS files should begin with a slash, ie.
#route('/<filename>.css')
Only the matching part of the pattern is passed to stylesheets() in
the filename argument, e.g. instead of main.css, it will be
main. Change the code to this:
#route('/<filename>.css')
def stylesheets(filename):
return static_file('{}.css'.format(filename), root='static')
Alternatively... rename your main.css file to main.tpl, bookend with <style> and </style>, move it into the /views directory along with your other templates, then simply add to the beginning of your return line:
return (template ("main"), template ("list", terms=terms, defins=defins))
In order to avoid mixing non-SSL and SSL content, I want to use a relative path for my Javascript file. In settings.py, I have defined JS_ROOT = "/path/js/".
In my html file, the following line results in no mixed content warning:
<script src="/path/js/Foo.js" type="text/javascript"></script>
This line gives a mixed content warning:
<script src="{{ JS_ROOT }}Foo.js" type="text/javascript"></script>
Any explanation?
I discovered that my problem was that I was not returning JS_ROOT correctly as part of my request context. Now that I include it in my context_processors.py and have the context_instance as part of my response, it works.
I have this master html template:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Start Bootstrap - SB Admin Version 2.0 Demo</title>
<!-- Core CSS - Include with every page -->
<link href="css/bootstrap.min.css" rel="stylesheet">
<link href="font-awesome/css/font-awesome.css" rel="stylesheet">
<!-- SB Admin CSS - Include with every page -->
<link href="css/sb-admin.css" rel="stylesheet">
<!-- Core Scripts - Include with every page -->
<script src="js/jquery-1.10.2.js"></script>
<script src="js/bootstrap.min.js"></script>
<script src="js/plugins/metisMenu/jquery.metisMenu.js"></script>
<!-- SB Admin Scripts - Include with every page -->
<script src="js/sb-admin.js"></script>
</head>
this is the test.py file:
from wheezy.template.engine import Engine
from wheezy.template.ext.core import CoreExtension
from wheezy.template.loader import FileLoader
T = ['where/project/folderbase/is']
engine = Engine(
loader=FileLoader(T),
extensions=[CoreExtension()]
)
master_template = engine.get_template(r'master.htm')
#route('/test')
def login_name():
return master_template.render({})
I'm a complete n00b at templating and web design.
lets say i run this via any of python web server like flask on localhost:port/test
Nothing shows up.
Why?
And what is this #path_for in wheezy.template?
Do I need to include #require(path_for) or anything else?
is that necessary to server static files in the html file to define all the files in a specific folder-> 'static'
or can they be accessed from where they are now, as in the code above?
You had lots of questions. I'll answer even though you may not care anymore...
If you have correctly configured Flask, and served that template on the route/url 'test', then nothing would appear as you have not defined a <body> with any content in the html.
In wheezy.templates, you access local variables/functions with the #my_variable syntax (ie you prefix it with an # symbol). If you want to access a variable that was passed to the template as part of the context, you need to require it first, #require(my_variable). Your example uses an empty dict as the context, so there would be no variables to access/require.
path_for is part of wheezy.routing, not wheezy.templates. It is used for getting the url of a named route (ie you could do #path_for('test'), and it would return localhost:1234/test. Using path_for would only make sense if you are using the complete wheezy.web framework (which uses wheezy.routing and wheezy.templates). Flask would have its own functions for doing this (I'm not sure what they are though, I don't use Flask). You would need to pass these functions into the template via the context, then #require them to use them though (or make some custom extension for wheezy.template).
Below is the entry in urls.py
urlpatterns = patterns('',
# Examples:
url(r'^login/','juicy.views.login'),
url(r'^mylogin/',RedirectView.as_view(permanent=False,url="http:\\www.google.com")),
url(r'^admin/', include(admin.site.urls)),
)
And this is my template.
<html>
<head>
<title>Login Page</title>
</head>
<body>
<form action=\mylogin\ method = get>
<input type="submit" value="Go to Google">
</form>
</body>
</html>
Problem is whenever i Click the button "Go to Google" it tries to open the url
as
<code>
"http://localhost:8000/mylogin/%5Cwww.google.com".
<code>
Funny thing is it was working till yesterday evening. I was able to go to google.com. After clearing the cache/cookie and some other cosmetic modifications I re-run the server and wooah back to square one.
Any help is much appreciated.
"http:\\www.google.com" is not the URL you have in mind. Try it with forward slashes: "http://www.google.com".
More precisely, "\\" is being interpreted as a single escaped backslash, so your apparent URL is "http:\www.google.com". Without the // marker to separate the scheme from the hostname, that looks like a relative URL which should be resolved relative to the current page - which is exactly what you're seeing.
Fully escaping the "\\" sequence (or using a raw string, which don't interpret escape sequences) would not solve your problem - "http:\\www.google.com" is also a relative URL. I mention this mostly to explain why you're only seeing a single %5C sequence in your resolved URL. %5C is the hex for a backslash character.
You also seem to have backslashes in your form action - that should be <form action="/mylogin/" method="get">.