Just installed a recent version of mod-pagespeed on my django instance and tried to minify CSS/JS with the following pagespeed.conf but in vain, even though remove_comments and collapse_whitespace seemed to work out.
ModPagespeedEnableFilters rewrite_javascript,rewrite_css,flatten_css_imports
ModPagespeedEnableFilters collapse_whitespace,elide_attributes
ModPagespeedEnableFilters combine_javascript,remove_comments
In django templates, CSS/JS url was pointed by {{ STATIC_URL }}media/main.js, etc and the matching folder was set up as an alias at the apache setup, but JS/CSS (and its link) are all unchanged at all.
I suspect mod-pagespeed didn't pick up the js/css due to the intervention from template engine..?
I just finally found out the option that will make difference.
# Explicitly tell mod_pagespeed to load some resources from disk.
# This will speed up load time and update frequency.
#
# This should only be used for static resources which do not need
# specific headers set or other processing by Apache.
#
# Both URL and filesystem path should specify directories and
# filesystem path must be absolute (for now).
#
ModPagespeedLoadFromFile "http://example.com/static/" "/var/www/static/"
Commenting out ModPagespeedLoadFromFile and locate static folders for your js/css
Related
I am severely confused about where to put my templates files and static files.
I understand absolute and relative paths just fine, but I can't seem to find any instructions that mirror the installation I have. I know this resembles other questions, but those answers aren't working. The video I watched to successfully build a simple app didn't put templates in the Project folder, which is where logic tells me they should be.
I have Python at:
C:\Python27
Django (v1.6.5) at:
C:\Python27\Lib\site-packages\django
I created a project "mysite" and an app called "films."
Project "mysite":
C:\Python27\Scripts\venv\mysite
and an App "films":
C:\Python27\Scripts\venv\mysite\films
The video I watched had me put my templates at:
C:\Python27\Lib\site-packages\django\contrib\admin\templates
But this seems completely stupid because the templates are outside of both the Project and the App.
Shouldn't I put a templates folder in the Project folder:
C:\Python27\Scripts\venv\mysite\templates
And then create subdirectories using the App name?
What files do I need to edit (and how) to tell Django where to find them?
Follow a similar process for static files (css, images)?
Like all frameworks, django offers great benefits if you follow some guidelines (and give up some control). The trick is to know what these guidelines are.
For templates:
If the template is not tied to a particular application, put it in a templates directory at the root of your project. Add the full path to this directory to TEMPLATE_DIRS.
All other templates should go in a directory called templates inside your application directory. So if you application is called myapp, templates for myapp will go in myapp/templates/
For static files:
For files related to specific applications, inside your application directory create a directory called static, then inside it a directory with the name of your application. So, if your application is called myapp, you would have myapp/static/myapp. Place all your static content for this application here; for example myapp/static/myapp/js/funky.js.
For static files that are generic, create a directory called assets (or static) in the root directory of your project. Add the full path to this directory to STATICFILES_DIRS.
By default, django will search all applications listed in INSTALLED_APPS, and add any templates and static directories to its search path for files. This is how, by default, the admin works without you having to configure anything.
If you chose to place your templates and static files in some other location, only then do you need to modify the TEMPLATE_DIRS and STATICFILES_DIRS settings. If all your templates and static assets are tied to applications, just creating the directories as mentioned above makes everything work.
If you are wondering why you need to create another directory under myapp/static/ to store your static files, this is more for portability. The collectstatic command is a simply "copy and replace" utility. It will overwrite all files in the STATIC_DIR location. This means that if two applications have some static file with the same name, they will be overwritten without warning. Adding a subdirectory keeps your application's static assets from being overwritten, because the exact path will be created.
Suppose you have two applications, app1 and app2, and both have a file named style.css in their respected directories:
app1/static/css/style.css
app2/static/css/style.css
When you run collectstatic, you'll end up with the following (assuming static is the name of your STATIC_DIR setting):
static/css/style.css
This may be the style.css from app1 or app2, the other cannot be determined (its actually based on the INSTALLED_APPS order). To prevent this, if you have:
app1/static/app1/css/style.css
app2/static/app2/css/style.css
Now, you'll end up with:
static/app1/css/style.css
static/app2/css/style.css
Both files will be preserved.
You also shouldn't put your code in your virtual environment directory. The virtual environment is not part of your source code, and placing your project in the same directory may cause problems later.
Create a single directory for your environments - I call mine envs (creative, I know). Create all your environments in this directory. Once you activate the environment, you can work in any directory in your system and your shell will be configured for that environment's Python.
Finally for the best, accurate, most up-to-date information - always refer to the django manual and the tutorial. Almost all other resources (even the often suggested djangobook.com) are outdated.
I've been running into a lot of issues trying to use static files and getting them to work with the development server.
I've been using the link: https://docs.djangoproject.com/en/1.4/howto/static-files/#staticfiles-development
When I run the development server, I notice that my CSS files are not getting pulled in but they are specified with the correct directory implying that Django is not finding my static files folder. My folder is defined in the project directory fold as 'static' and contains a folder called 'css' with 'bootstrap.css'.
When I look at the page source, I see:
<link href="css/bootstrap.css" rel="stylesheet">
but I can't view the CSS implying a problem with finding the correct directory.
What I added in settings was
STATICFILES_DIRS = (
'static',
# Put strings here, like "/home/html/static" or "C:/www/django/static".
# Always use forward slashes, even on Windows.
# Don't forget to use absolute paths, not relative paths.
)
my dir structure: mysite/static/css/bootstrap.css
Thanks for any help :D
EDIT: Also if I can put non-existent directories into STATICFILES_DIR in settings.py without triggering an error in debug mode; does that imply that I have not configured Django to even look for static directories?
EDIT: I've also added a RequestContext to my views.py but it did not work out.
1: Make sure settings.DEBUG is True
2: Give absolute path to directory that contains static media. In this case, /PATH/TO/mysite/static/
3: Make sure calls to static files actually point to settings.STATIC_URL
Your example points to relative url css/bootstrap.css. It should probably point to {{ STATIC_URL }}css/bootstrap.css unless you got lucky and your page is routed at a URL that matches your STATIC_URL exactly.
With condition 1 and 2 met, static media is served AT settings.STATIC_URL FROM settings.STATICFILES_DIRS and other staticfiles finders.
Context
I am trying to setup a django continuous integration developpement system on a apache2 server via wsgi and Mercurial.
Setup seems to work fine, but with the changegroup hook, I run python manage.py collectstatic --settings="sitename.settings" --noinput to update the static files directory located in /path/to/sitename/static/.
Problem
But with each run of the python manage.py collectstatic --settings="sitename.settings" --noinput command, my /path/to/sitename/static/ directory gets a complete copy of the filesystem in /path/to/sitename/, thus leading in easy access to all code files, settings files, etc... with 5 run, i have 5 nested /static/ in the static directory, eg. static/, static/static/, static/static/static/ and so on...
This will become a real problem. I could just remove everything inside static/ with each run, but some file permissions need to be preserved.
Configuration used
At the moment, DEBUG = True
/path/to/sitename/settings.py:
# Absolute path to the directory static files should be collected to.
# Don't put anything in this directory yourself; store your static files
# in apps' "static/" subdirectories and in STATICFILES_DIRS.
# Example: "/home/media/media.lawrence.com/static/"
STATIC_ROOT = '/path/to/sitename/static/'
# URL prefix for static files.
# Example: "http://media.lawrence.com/static/"
STATIC_URL = '/static/'
# URL prefix for admin static files -- CSS, JavaScript and images.
# Make sure to use a trailing slash.
# Examples: "http://foo.com/static/admin/", "/static/admin/".
ADMIN_MEDIA_PREFIX = '/static/admin/'
# Additional locations of static files
STATICFILES_DIRS = (
# Put strings here, like "/home/html/static" or "C:/www/django/static".
# Always use forward slashes, even on Windows.
# Don't forget to use absolute paths, not relative paths.
'/path/to/sitename/blog/static',
)
# List of finder classes that know how to find static files in
# various locations.
STATICFILES_FINDERS = (
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
'django.contrib.staticfiles.finders.DefaultStorageFinder',
)
Question
What am I missing? Is there something in the use of staticfile i did not understand?
Will I have other problems with this kind of solution?
STATIC_ROOT is where collectstatic will dump the files, and STATICFILES_DIRS is where it will search for static files, note that this is optional. By default django will search for a static directory in all registered apps.
As far as duplication, as per the docs:
Duplicate file names are by default resolved in a similar way to how
template resolution works: the file that is first found in one of the
specified locations will be used. If you're confused, the findstatic
command can help show you which files are found.
I didn't see where STATIC_ROOT is set in your settings, so I suspect you need to make sure these two are pointing at the right place.
The easiest way to use static files is to create a directory called static as a subdirectory of your application directory and leave STATICFILES_DIRS empty.
Here's the scenario:
I'm running Django 1.3.1, utilizing staticfiles, and django-compressor (latest stable) to, among other things, compile LESS files.
I have an "assets" directory that's hooked into staticfiles with STATICFILES_DIRS (for project-wide static resources). In that directory I have a "css" directory and in that a "lib.less" file that contains LESS variables and mixins.
So the physical path is <project_root>/assets/css/lib.less and it's served at /static/css/lib.less.
In one of my apps' static directory, I have another LESS file that needs to import the one above. The physical path for that is <project_root>/myapp/static/myapp/css/file.less and it would be served at /static/myapp/css/file.less.
My first thought was:
#import "../../css/lib.less"
(i.e. based on the URL, go up to levels from /static/myapp/css to /static/, then traverse down into /static/css/lib.less).
However, that doesn't work, and I've tried just about every combination of URLs and physical paths I can think of and all of them give me FilterErrors in the template, resulting from not being able to find the file to import.
Anyone have any ideas what the actual import path should be?
After tracking down exactly where the error was coming from in the django-compressor source. It turns out to be directly passed from the shell. Which clued me into removing all the variables and literally just trying to get the lessc compiler to parse the file.
Turns out it wants a relative path from the source file to the file to be imported in terms of the physical filesystem path. So I had to back all the way out to my <project_root> and then reference assets/css/lib.less from there. The actual import that finally worked was:
#import "../../../../assets/css/lib.less"
What's very odd though is that lessc would not accept an absolute filesystem path (i.e. /path/to/project/assets/css/lib.less). I'm not sure why.
UPDATE (02/08/2012)
Had a complete "DUH" moment when I finally pushed my code to my staging environment and ran collectstatic. The #import path I was using worked fine in development because that was the physical path to the file then, but once collectstatic has done it's thing, everything is moved around and relative to <project_root>/static/.
I toyed with the idea of using symbolic links to try to match up the pre and post-collectstatic #import paths, but I decided that that was far too complicated and fragile in the long run.
SO... I broke down and moved all the LESS files together under <project_root>/assets/css/, and rationalized moving the LESS files out of the apps because since they're tied to a project-level file in order to function, they're inherently project-level themselves.
I'm sort of in the same bind and this is what I've come up with for the most recent versions of compressor and lessc to integrate with staticfiles. Hopefully this will help some other people out
As far as I can tell from experimenting, lessc doesn't have a notion of absolute or relative paths. Rather, it seems to maintain a search path, which includes the current directory, the containing directory of the less file, and whatever you pass to it via --include-path
so in my configuration for compressor I put
COMPRESS_PRECOMPILERS = (
('text/less', 'lessc --include-path=%s {infile} {outfile}' % STATIC_ROOT),
)
Say, after running collectstatic I have bootstrap living at
STATIC_ROOT/bootstrap/3.2.0/bootstrap.css.
Then from any less file, I can now write
#import (less, reference) "/bootstrap/3.2.0/bootstrap.css"
which allows me to use the bootstrap classes as less mixins in any of my less files!
Every time I update a less file, I have to run collectstatic to aggregate them in a local directory so that compressor can give less the right source files to work on. Otherwise, compressor handles everything smoothly. You can also use collectstatic -l to symlink, which means you only need to collect the files when you add a new one.
I'm considering implementing a management command to smooth out the development process that either subclasses runserver to call collectstatic each time the server is reloaded, or uses django.utils.autoreload directly to call collectstatic when things are updated.
Edit (2014/12/01): My approach as outlined above requires a local static root. I was using remote storage with offline compression in my production environment, so deployment requires a couple extra steps. In addition to calling collectstatic to sync the static files to the remote storage, I call collectstatic with different django config file that uses local storage. After I have collected the files locally, I can call 'compress', having configured it to upload the result files to remote storage, but look in local storage for source files.
In my development environment I'm getting intermittent failures for serving static files (js scripts and css). In the error console in Chrome I get 404s. But if I refresh on those items, or visit the URLs directly, they're served up fine.
This is annoying.
Example:
GET http://127.0.0.1:8000/static/js/editor/xyz.js?v=1 404 (NOT FOUND)
but if I visit that URL directly fine. And if I refresh the page a few times, it will work again.
Any ideas?
Chrome 14.0.835.202
Django==1.3
Fabric==1.0.1
Jinja2==2.5.5
PIL==1.1.7
Pygments==1.3.1
South==0.7.3
Sphinx==1.0.5
boto==2.0
chunks==0.1
django-devserver==0.2.1
django-pagination==1.0.7
django-sorting==0.1
django-storages==1.1.3
docutils==0.8
gunicorn==0.12.1
ipython==0.10.1
paramiko==1.7.6
pep8==0.6.1
psycopg2==2.2.2
pycrypto==2.0.1
python-dateutil==1.5
python-memcached==1.45
wsgiref==0.1.2
The dev server is single-threaded so if something keeps waiting, it blocks every request.
I usualy work with the django concurent dev server which is multi-threaded and works much better. Also it is very fast and easy to setup ;)
it might depends on your setup.
what did you do for the static? what's the settings? did you do the collect static?
try this in case
however, about serving static files in development:
Warning This will only work if DEBUG is True.
That’s because this view is grossly inefficient and probably insecure.
This is only intended for local development, and should never be used
in production.
from here
can't you just supply the static files in another server?
After reading all answers if still anyone having this problem then ...
As per Django nature you don't need to do anything to serve static files
just your settings file should have proper configuration as follows:
STATIC_URL = '/static/'
STATICFILES_DIRS = (
# **THIS IS USED WHEN YOUR STATIC FILES ARE IN SOME OTHER FOLDER ALSO**
# Put strings here, like "/home/html/static" or "C:/www/django/static".
# Always use forward slashes, even on Windows.
# Don't forget to use absolute paths, not relative paths.
FOLDER_NAME,
)
STATICFILES_FINDERS = (
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
'django.contrib.staticfiles.finders.DefaultStorageFinder',
)
INSTALLED_APPS = (
# other apps
'django.contrib.staticfiles',
)
But if still you face problem put this into your urls.py:
(r'^(path of your file)$', 'django.views.static.serve' , {'document_root': 'PROJECT_ROOT_DIR' + "path to the static folder"}),
Above URL will serve for static files whether they are JS files or CSS or images.
In case of production server you don't need this.
Then run: python manage.py collecstatic.
Hope this helps.