How to not redefine url for static files in flask everytime - python

My app has a lot of routes that use the same set of static files.
I have to define them for every route like this:
css_reset = url_for("static", filename="reset.css")
css_main = url_for("static", filename="main.css")
css_fonts = url_for("static", filename="fonts.css")
js_jquery = url_for("static", filename="jquery-1.7.2.min.js")
js_main = url_for("static", filename="main.js")
And then, when I render a template it looks like this:
return render_template("person.html",
css_main=css_main,
css_reset=css_reset,
css_fonts=css_fonts,
js_jquery=js_jquery,
js_main=js_main)
I'm new to flask and python and I think that what I'm doing is a bit ridiculous. Can I define them in one place and then just use in my templates, without copying and pasting in every route definition?

Instead of passing these variables to your templates every time you can register them as globals in Jinja:
app.jinja_env.globals.update(
css_reset=url_for("static", filename="reset.css"),
css_main=url_for("static", filename="main.css"),
...
)
Or, better yet, register a helper function:
app.jinja_env.globals['static'] = (
lambda filename: url_for('static', filename=filename))
And then in your templates:
<link ref=stylesheet href="{{ static('main.css') }}">

The simplest way is to use Flask-Assets extension.
from flask.ext.assets import Environment, Bundle
assets = Environment(app)
css_all = Bundle('reset.css','main.css','fonts.css')
assets.register('css_all',css_all)
In template:
{% assets %}
<link rel="stylesheet" href="{{ ASSET_URL }}">
{% endassets %}
You can also compress css and js files for production by using certain options of this extension.
Since you need to use these files in many templates, define them in a base.html template and in every template extend that base.html. You don not have to write them again and again.

You don't need to do that, url_for is for generating urls (so that when you change the structure of a url, you don't need to change it a dozen times). You can just use a fixed path to your static files directly in your templates instead. Just put your static files in /static folder and use it in your template :
<link rel="stylesheet" href="{{ YOUR_SITE_URL_HERE+'/static/main.css' }}">
Instead of replacing YOUR_SITE_URL with your site's url directly, you might want to define a variable in your config.py and use it in your template : {{ config['SITE_URL']+'/static/main.css' }}

Related

Wagtail: Setting a dedicated Static folder for each app in Multisite

I am using Multisite to administer several websites and a custom admin on a single build of Wagtail. Currently, I have my static folder set like this:
settings.py:
INSTALLED_APPS = [
'websites.sua_umn_edu',
'admin_sua_umn_edu',
...
]
STATIC_URL = '/static/'
Is there some way to set the STATIC_URL dynamically, so each app looks for a static directory within its own folder?
Maybe a template tag that creates a path based on the request.site fits your needs? I created a template tag for a per site stylesheet:
#register.inclusion_tag('website/tags/stylesheet.html', takes_context=True)
def stylesheet(context):
slug = slugify(context['request'].site)
return {
'path': '/css/{}/main.css'.format(slug)
}
website/tags/stylesheet.html
{% load static %}
<link rel="stylesheet" href="{% static path %}">
This template tag can be used in your base.html
{% stylesheet %}
Maybe stylesheets is too limited for your websites but this concept can be generalised. Here is pseudo code for a {% site_static '...' %} template tag. It looks up the current site and calls the normal static template tag.
from django.templatetags.static import do_static
#register.tag('site_static', takes_context=True)
def site_static(context, parser, token)
site_slug = slugify(context['request'].site)
token = '{}/{}'.format(site_slug, token)
return do_static(parser, token)

Static file in django without Using {% static "abc.jpg" %}

I had static files in django.
Project Structure Sample
I have project structure like above i want to use js and img from asset folder. How can i do this ? How i can avoid using {% static "abc.jpg" %} ?
First you need to keep this files in static folder
Keep these files out of templates like
project_main_folder/static/img/abc.jpg
The recommended way is to use static tag provided by django.
{% static "abc.jpg" %}
Without static tag you can do this like
<img src="host:port/static/img/abc.jpg" />
or
<img src="/static/img/abc.jpg" />
This is not recommend.

Django static templatetag not displaying SVG

I'm trying to use django's static templatetag to display an SVG, but it doesn't seem to recognize the SVG as a valid image url. This is what I currently have:
settings.py
import mimetypes
mimetypes.add_type("images/svg+xml", ".svg", True)
landing.html
{% load staticfiles %}
<img src="{% static 'images/right-arrow.svg' %}" />
At least in my view.py, it recognizes the SVG mimetype:
views.py
print(mimetypes.guess_type(static('images/right-arrow.svg')))
# returns ('images/svg+xml', None)
The SVG does display in a non-django page, and it will download the SVG if I try to open the SVG path in a new browser tab.
I'm currently using python 3.4 and django 1.8.4.
I found the issue. In settings.py, it should be mimetypes.add_type('image/svg+xml', '.svg', True). image should be singular.
I faced a similar issue.I would recommend you to use :
src="{{ STATIC_URL }} images/right-arrow.svg" instead of src="{% static 'images/right-arrow.svg' %}"
svg format might not always identify django's method of obtaining staticfile contents.Hope this helps :)
Add this in your settings.py file.
import mimetypes
mimetypes.add_type("image/svg+xml", ".svg", True)
mimetypes.add_type("image/svg+xml", ".svgz", True)
In your cases you have added images in add_type which should be singular (image).
You are loading staticfiles and using static?
This is wrong.
Try changing {% load staticfiles %} <img src="{% static 'images/right-arrow.svg' %}" /> to
{% load static %} <img src="{% static 'images/right-arrow.svg' %}" /> and you also need to consider which app you should find your static files.

using a variable as an image source in html? (python)

Before I start please pardon my english, totally newbie in HTML and this is the very first django app I'm creating.
So let's say I want to view static images based on the input in the forms for testing purpose, so if I type in the form goat.jpg it will display goat.jpg
this is my html
<!DOCTYPE html>
{% load static %}
<html>
<head>
<title>test</title>
</head>
<body>
<center><img src="{% static "{{staticpath}}" %}" alt="gif" align="middle"/></center>
{{boldmessage}}
and this is my views
from django.shortcuts import render
from django.http import HttpResponse
from django.template import RequestContext
from django.shortcuts import render_to_response
def generate(request):
context = RequestContext(request)
if request.GET:
path = request.GET.get('path','')
context_dict = {'staticpath':path}
return render_to_response("generated/generated.html", context_dict, context)
path is already a string, but if I remove the staticpath double quote django will raise an exception. So how do I exactly put the path's string in the html image source so it will display the static images correctly? thanks!
Calling {% static 'some/path/' %} will call the Django static file finders. If the image you are looking for is in a directory and you only pass the file name to {% static 'some/path' %} it will not find the file.
Read about the {{ STATIC_URL }} tag as solution that will avoid nesting tags. If your files are all stored in the root folder of your staticfiles directory (set by the STATIC_ROOT setting in settings.py) then this will work-
<img src="{{ STATIC_URL }}{{ staticpath }}"/>
However, it would probably be best to implement a function called by your view that SEARCHES your STATIC_ROOT folder, and all child folders, to find the full relative ( to STATIC_ROOT ) path for the file and returns it. The approach is convoluted but would work.

Django: Static vs Assets

I'm new in Django,
I'm adding new CSS files to my application!
<link href="{% static 'css/style.css' %}" rel="stylesheet">
EDIT:
I'm using {% load static %} before rendering the teamplate!
I can't see any change when add files to the /static/ folder
(it works when adding them to /assets/)
My Question:
What the deference between the two folders? Do I need to add the new files to /static/ anyway? Because I see the var {% static .. %}

Categories