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

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)

Related

How do i load css file into html in Django

I'm trying to create a Django app and i have made all the static settings like
Settings.py
STATICFILES_DIRS = [
os.path.join(BASE_DIR,'CricketTeamManagement/static')
]
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
STATIC_URL = '/static/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'
URLS.py
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('Management.urls'))
] + static(settings.MEDIA_URL, document_root = settings.MEDIA_ROOT)
I have also created a static folder in Main project folder and ran python manage.py collectstatic it created a new static folder outside and it has admin folder in it and sub folders like js,css,font,images and collectstatic collects the images and stores in this folder. I see static files are clearly working.
All the models.py imagefields are uploaded to media folders and even that works.
The Problem comes here
My css files are not taking its styles and not altering my html elements.
If I have the below code in html file the styling works and if i separate it to a css folder and create a css file by removing style tag it is not working.
<style>
body {
background-color: powderblue;
}
h1 {
color: blue;
}
p {
color: red;
}
</style>
when i saw the css file Not Found error it got fixed with
to make html check the css file.
Unsure what is the issue. Thanks in Advance.
Update
Project Format
Link Tag in HTML
The href in your index.html right now refers to yourwebsite/stylesheet.css. Django doesn't know where that URL is as you defined your static URL as "/static/". Static located in the STATIC_DIRS will be loaded under the URL yourwebsite/static/stylesheet.css. This is why you are getting the 404 on the CSS file.
Change your index.html to use Django built-in template tags to make it easier.
{% load static %}
Some code here.....
<link rel="stylesheet" type='text/css' href="{% static 'css/stylesheet.css' %}">
This will automatically generate the right url for your static file which should solve the problem.
You don't need to run collect static in development as django's server will take care of the static files. During production will will need to run collect static and point your reverse proxy or the like towards the static files.
you have to link your css files this way in templates, also collectstatic command is not required during production stage only
{% load static %}
<link rel="stylesheet" type="text/css" href="{% static 'css/style.css' %}"/>

Playing uploaded video with Django

I am not able to play video on my Django website. I think something is wrong in my views.py render function
videoplay.html:
{% block contents %}
<video name='demo' controls autoplay width='50%' height='40%'>
<source src="{{STATIC_URL}}sample1.mp4" type="video/mp4"></source>
</video>
{% endblock %}
Included this in settings.py:
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')`
Views.py is:
from django.shortcuts import render, redirect
from django.conf import settings
from django.core.files.storage import FileSystemStorage
from django.views.generic.base import TemplateView
from uploads.core.models import Document
from uploads.core.forms import DocumentForm
def index(request):
return render(request, "core/videoplay.html")`
I am getting a play button and streaming line on my website
The STATIC_URL is where your static files are located such as CSS, Template Images, Javascript etc. There is a special Template Tag for Static Files in Django called {% static %}.
To generate the full url to where the static files are located, you use the template tag like this:
{% load static %}
<video src="{% static "/videos/demo.mp4" %}">
The MEDIA_URL is where your media files are located. Media files are uploaded files that change during the applications lifetime. They are not necessarily there at deployment but can be uploaded at any time by users or admins on the website.
Media files are set as fields on the model like this:
class DemoVideo(models.Model):
video = models.FileField(upload_to="videos")
They are accessed like this demovideo.video.url so in your template it would be src="{{demovideo.video.url}}.
Check if your file is a media or static file, and access it in the template in the correct way described above.

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.

How to not redefine url for static files in flask everytime

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' }}

A Simple View to Display/Render a Static image in Django

I am trying to find the most efficient way of displaying an image using django's template context loader. I have a static dir within my app which contains the image 'victoryDance.gif' and an empty static root dir at the project level (with settings.py). assuming the paths within my urls.py and settings.py files are correct. what is the best view?
from django.shortcuts import HttpResponse
from django.conf import settings
from django.template import RequestContext, Template, Context
def image1(request): # good because only the required context is rendered
html = Template('<img src="{{ STATIC_URL }}victoryDance.gif" alt="Hi!" />')
ctx = { 'STATIC_URL':settings.STATIC_URL}
return HttpResponse(html.render(Context(ctx)))
def image2(request): # good because you don't have to explicitly define STATIC_URL
html = Template('<img src="{{ STATIC_URL }}victoryDance.gif" alt="Hi!" />')
return HttpResponse(html.render(RequestContext(request)))
def image3(request): # This allows you to load STATIC_URL selectively from the template end
html = Template('{% load static %}<img src="{% static "victoryDance.gif" %}" />')
return HttpResponse(html.render(Context(request)))
def image4(request): # same pros as image3
html = Template('{% load static %} <img src="{% get_static_prefix %}victoryDance.gif" %}" />')
return HttpResponse(html.render(Context(request)))
def image5(request):
html = Template('{% load static %} {% get_static_prefix as STATIC_PREFIX %} <img src="{{ STATIC_PREFIX }}victoryDance.gif" alt="Hi!" />')
return HttpResponse(html.render(Context(request)))
thanks for answers These views all work!
If you need to render an image read a bit here http://www.djangobook.com/en/1.0/chapter11/ and use your version of the following code:
For django version <= 1.5:
from django.http import HttpResponse
def my_image(request):
image_data = open("/path/to/my/image.png", "rb").read()
return HttpResponse(image_data, mimetype="image/png")
For django 1.5+ mimetype was replaced by content_type(so happy I'm not working with django anymore):
from django.http import HttpResponse
def my_image(request):
image_data = open("/path/to/my/image.png", "rb").read()
return HttpResponse(image_data, content_type="image/png")
Also there's a better way of doing things!
Else, if you need a efficient template engine use Jinja2
Else, if you are using Django's templating system, from my knowledge you don't need to define STATIC_URL as it is served to your templates by the "static" context preprocessor:
TEMPLATE_CONTEXT_PROCESSORS = (
'django.contrib.auth.context_processors.auth',
'django.core.context_processors.debug',
'django.core.context_processors.i18n',
'django.core.context_processors.static',
'django.core.context_processors.media',
'django.core.context_processors.request',
'django.contrib.messages.context_processors.messages',
)
In your last example (image5) you should use {{ STATIC_PREFIX }} instead of {% STATIC_PREFIX %}
STATIC_PREFIX is variable, not a tag
To avoid defining STATIC_URL explicitly, you can use a RequestContext when rendering your template. Just make sure django.core.context_processors.static is in your TEMPLATE_CONTEXT_PROCESSORS setting.
from django.template import RequestContext
...
return HttpResponse(html.render(RequestContext(request, ctx)))
Alternatively, you could use the static template tag.
html = Template('<img src="{% static "victoryDance.gif" %} alt="Hi!" />')
A third option is the get_static_prefix template tag.

Categories