Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
...
compare: master
Checking mergeability… Don’t worry, you can still create the pull request.
  • 8 commits
  • 9 files changed
  • 0 commit comments
  • 3 contributors
Commits on Mar 19, 2009
Patrick Altman fixed bug in not handling external_urls defined 40727e0
Patrick Altman fixed external_urls bug when force flag is used 8feefca
Patrick Altman Added a CSS string replacement filter 5038b5b
@ipmb ipmb allows for source file root, compressed file root and compressed file
URL to vary from MEDIA_ROOT and MEDIA_URL while retaining backwards
compatibility. Optional settings are COMPRESS_SOURCE, COMPRESS_ROOT,
COMPRESS_URL. Needs docs.

Signed-off-by: Patrick Altman <patrick@studionow.com>
0ee308a
Patrick Altman Merge branch 'integration' 1ce0fab
Commits on Mar 24, 2009
Patrick Altman added logic to only check logic compressed files if prefix didn't exi…
…st in extra context
bef9a80
Commits on Oct 18, 2010
Marc Leglise Including Google Closure filter from unknown source. eb850e3
Marc Leglise Added handling for LESS files to flow directly into development, with…
… a template tag to include Less.js for the browser.
2e2a6f6
View
3  compress/conf/settings.py
@@ -2,6 +2,9 @@
from django.conf import settings
COMPRESS = getattr(settings, 'COMPRESS', not settings.DEBUG)
+COMPRESS_SOURCE = getattr(settings, 'COMPRESS_SOURCE', settings.MEDIA_ROOT)
+COMPRESS_ROOT = getattr(settings, 'COMPRESS_ROOT', settings.MEDIA_ROOT)
+COMPRESS_URL = getattr(settings, 'COMPRESS_URL', settings.MEDIA_URL)
COMPRESS_AUTO = getattr(settings, 'COMPRESS_AUTO', True)
COMPRESS_VERSION = getattr(settings, 'COMPRESS_VERSION', False)
COMPRESS_VERSION_PLACEHOLDER = getattr(settings, 'COMPRESS_VERSION_PLACEHOLDER', '?')
View
17 compress/filters/css_url_replace/__init__.py
@@ -0,0 +1,17 @@
+from django.conf import settings
+
+from compress.filter_base import FilterBase, FilterError
+
+REPLACE_LIST = getattr(settings, 'COMPRESS_CSS_URL_REPLACE', [])
+
+class CSSURLReplace(FilterBase):
+
+ def filter_css(self, css):
+ filtered_css = css
+ if type(REPLACE_LIST) == list:
+ for REPLACE in REPLACE_LIST:
+ if len(REPLACE) == 2:
+ filtered_css = filtered_css.replace(REPLACE[0], REPLACE[1])
+ if self.verbose:
+ print 'Replaced "%s" with "%s"' % REPLACE
+ return filtered_css
View
43 compress/filters/google_closure/__init__.py
@@ -0,0 +1,43 @@
+import subprocess
+
+from django.conf import settings
+
+from compress.filter_base import FilterBase, FilterError
+
+BINARY = getattr(settings, 'COMPRESS_CLOSURE_BINARY', 'java -jar compiler.jar')
+JS_ARGUMENTS = getattr(settings, 'COMPRESS_CLOSURE_JS_ARGUMENTS', '')
+
+class GoogleClosureCompilerFilter(FilterBase):
+
+ def filter_common(self, content, arguments):
+ command = BINARY
+ for argument in arguments:
+ command += ' --' + argument + ' ' + arguments[argument]
+
+ if self.verbose:
+ command += ' --verbose'
+
+ p = subprocess.Popen(command, shell = True, stdout = subprocess.PIPE, stdin = subprocess.PIPE, stderr = subprocess.PIPE)
+ p.stdin.write(content)
+# p.stdin.close()
+#
+# filtered_css = p.stdout.read()
+# p.stdout.close()
+#
+# err = p.stderr.read()
+# p.stderr.close()
+ filtered_css, err = p.communicate()
+
+ if p.wait() != 0:
+ if not err:
+ err = 'Unable to apply Google Closure Compiler filter'
+
+ raise FilterError(err)
+
+ if self.verbose:
+ print err
+
+ return filtered_css
+
+ def filter_js(self, js):
+ return self.filter_common(js, JS_ARGUMENTS)
View
9 compress/management/commands/synccompress.py
@@ -34,8 +34,11 @@ def handle_noargs(self, **options):
print
for name, js in settings.COMPRESS_JS.items():
- u, version = needs_update(js['output_filename'],
- js['source_filenames'])
+ if 'external_urls' in js:
+ u, version = False, "External"
+ else:
+ u, version = needs_update(js['output_filename'],
+ js['source_filenames'])
if (force or u) or verbosity >= 2:
msg = 'JavaScript Group \'%s\'' % name
@@ -43,7 +46,7 @@ def handle_noargs(self, **options):
print len(msg) * '-'
print "Version: %s" % version
- if force or u:
+ if (force or u) and 'external_urls' not in js:
filter_js(js, verbosity)
if (force or u) or verbosity >= 2:
View
1  compress/templates/compress/less.html
@@ -0,0 +1 @@
+<link href="{{ url }}" rel="stylesheet/less" type="text/css"{% if media %} media="{{ media }}"{% endif %}{% if title %} title="{{ title|default:"all" }}"{% endif %}{% if charset %} charset="{{ charset }}"{% endif %}>
View
22 compress/templatetags/compressed.py
@@ -5,7 +5,7 @@
from django.conf import settings as django_settings
from compress.conf import settings
-from compress.utils import media_root, media_url, needs_update, filter_css, filter_js, get_output_filename, get_version, get_version_from_file
+from compress.utils import compress_root, compress_url, needs_update, filter_css, filter_js, get_output_filename, get_version, get_version_from_file
register = template.Library()
@@ -18,12 +18,15 @@ def render_common(template_name, obj, filename, version):
if filename.startswith('http://'):
context['url'] = filename
else:
- context['url'] = media_url(filename, prefix)
+ context['url'] = compress_url(filename, prefix)
return template.loader.render_to_string(template_name, context)
def render_css(css, filename, version=None):
- return render_common(css.get('template_name', 'compress/css.html'), css, filename, version)
+ if filename.endswith('.less'):
+ return render_common(css.get('template_name', 'compress/less.html'), css, filename, version)
+ else:
+ return render_common(css.get('template_name', 'compress/css.html'), css, filename, version)
def render_js(js, filename, version=None):
return render_common(js.get('template_name', 'compress/js.html'), js, filename, version)
@@ -49,9 +52,9 @@ def render(self, context):
css['source_filenames'])
if u:
filter_css(css)
- else:
+ elif not css.get('extra_context', {}).get('prefix', None):
filename_base, filename = os.path.split(css['output_filename'])
- path_name = media_root(filename_base)
+ path_name = compress_root(filename_base)
version = get_version_from_file(path_name, filename)
return render_css(css, css['output_filename'], version)
@@ -90,9 +93,9 @@ def render(self, context):
js['source_filenames'])
if u:
filter_js(js)
- else:
+ elif not js.get('extra_context', {}).get('prefix', None):
filename_base, filename = os.path.split(js['output_filename'])
- path_name = media_root(filename_base)
+ path_name = compress_root(filename_base)
version = get_version_from_file(path_name, filename)
return render_js(js, js['output_filename'], version)
@@ -122,3 +125,8 @@ def compressed_js(parser, token):
return CompressedJSNode(name)
compressed_js = register.tag(compressed_js)
+
+#@register.tag
+def less_js():
+ return '<script src="http://lesscss.googlecode.com/files/less-1.0.35.min.js"></script>'
+less_js = register.tag(less_js)
View
29 compress/utils.py
@@ -46,7 +46,7 @@ def needs_update(output_file, source_files, verbosity=0):
version = get_version(source_files)
on = get_output_filename(output_file, version)
- compressed_file_full = media_root(on)
+ compressed_file_full = compress_root(on)
if not os.path.exists(compressed_file_full):
return True, version
@@ -54,16 +54,22 @@ def needs_update(output_file, source_files, verbosity=0):
update_needed = getattr(get_class(settings.COMPRESS_VERSIONING)(), 'needs_update')(output_file, source_files, version)
return update_needed
-def media_root(filename):
+def compress_root(filename):
"""
- Return the full path to ``filename``. ``filename`` is a relative path name in MEDIA_ROOT
+ Return the full path to ``filename``. ``filename`` is a relative path name in COMPRESS_ROOT
"""
- return os.path.join(django_settings.MEDIA_ROOT, filename)
+ return os.path.join(settings.COMPRESS_ROOT, filename)
-def media_url(url, prefix=None):
+def compress_source(filename):
+ """
+ Return the full path to ``filename``. ``filename`` is a relative path name in COMPRESS_SOURCE
+ """
+ return os.path.join(settings.COMPRESS_SOURCE, filename)
+
+def compress_url(url, prefix=None):
if prefix:
return prefix + urlquote(url)
- return django_settings.MEDIA_URL + urlquote(url)
+ return settings.COMPRESS_URL + urlquote(url)
def concat(filenames, separator=''):
"""
@@ -71,20 +77,17 @@ def concat(filenames, separator=''):
"""
r = ''
for filename in filenames:
- fd = open(media_root(filename), 'rb')
+ fd = open(compress_source(filename), 'rb')
r += fd.read()
r += separator
fd.close()
return r
-def max_mtime(files):
- return int(max([os.stat(media_root(f)).st_mtime for f in files]))
-
def save_file(filename, contents):
- dirname = os.path.dirname(media_root(filename))
+ dirname = os.path.dirname(compress_root(filename))
if not os.path.exists(dirname):
os.makedirs(dirname)
- fd = open(media_root(filename), 'wb+')
+ fd = open(compress_root(filename), 'wb+')
fd.write(contents)
fd.close()
@@ -121,7 +124,7 @@ def filter_common(obj, verbosity, filters, attr, separator, signal):
filename = get_output_filename(obj['output_filename'], get_version(obj['source_filenames']))
if settings.COMPRESS_VERSION:
- remove_files(os.path.dirname(media_root(filename)), obj['output_filename'], verbosity)
+ remove_files(os.path.dirname(compress_root(filename)), obj['output_filename'], verbosity)
if verbosity >= 1:
print "Saving %s" % filename
View
7 compress/versioning/mtime/__init__.py
@@ -1,6 +1,6 @@
import os
-from compress.utils import get_output_filename, media_root
+from compress.utils import get_output_filename, compress_source, compress_root
from compress.versioning.base import VersioningBase
class MTimeVersioning(VersioningBase):
@@ -8,12 +8,13 @@ class MTimeVersioning(VersioningBase):
def get_version(self, source_files):
# Return the modification time for the newest source file
- return str(max([int(os.stat(media_root(f)).st_mtime) for f in source_files]))
+ return str(max(
+ [int(os.stat(compress_source(f)).st_mtime) for f in source_files]))
def needs_update(self, output_file, source_files, version):
output_file_name = get_output_filename(output_file, version)
- compressed_file_full = media_root(output_file_name)
+ compressed_file_full = compress_root(output_file_name)
return (int(os.stat(compressed_file_full).st_mtime) < int(version)), version
View
40 docs/Configuration.textile
@@ -85,6 +85,46 @@ Network, you can use the optional _prefix_ parameter:
In this example, the template tags will render _http://cdn.example.com/css/one_compressed.css_ in the link tag. You will need to manually put there after you build as part of your deployment process.
+h4. CSS URL Replace Filter
+
+This is a really simple filter for doing Python string replacements on your CSS. The use case for this is when you have root relative
+urls defined in your css:
+
+<pre><code>
+ body {background-image:url(/media/images/background.gif);}
+</code></pre>
+
+If you are compiling your media to live on another server, for example if you are deploying the compiled resources to Amazon S3, these
+root relative urls will break. That is of course unless you also deploy all the media so they stay relative. However, then you limit yourself
+from being able to prefix the source with a date or version number. Ideally, you should be able to control where the images are deployed
+and those might be different from where your js/css media are being served from.
+
+This filter offers a very simple solution. Really too simple. One could make the argument for just doing this search and replace manually
+after the fact, however, I like for my build process to be as automated as possible. Therefore, I want to write down the rules/settings
+once and be able to repeat the build process when needed without thinking about the find and replace.
+
+Enough babbling, here is an example settings.py section:
+
+<pre><code>
+ COMPRESS_CSS_FILTERS = ('compress.filters.yui.YUICompressorFilter', 'compress.filters.css_url_replace.CSSURLReplace')
+ URL_REPLACE_HOST = 'http://localhost:8000'
+ COMPRESS_CSS_URL_REPLACE = [("url(/media", "url(%s/media" % URL_REPLACE_HOST),]
+</code></pre>
+
+This will run the CSSURLReplace filter after the CSS is compressed (it is safe to do this in any order, at least for this filter). The URL_REPLACE_HOST
+is not required, just a variable I defined in my settings file to keep things clean (and to override in other environments -- this is obviously my dev
+settings file).
+
+The COMPRESS_CSS_URL_REPLACE is the only required setting by this filter. It takes a list of tuples, each tuple being exactly two strings.
+
+The first argument in each tuple is the string to find, and the second is the string to replace it with. The replace operations will execute
+in the order they are inserted into the list. Here I am replacing all url(/media....) in my compiled css to an absolute url of url(http://localhost:8000/media...).
+
+This will have the result of my compiled css can be hosted anywhere and the images will still be served off of http://localhost:8000 (or anywhere else
+that I define in URL_REPLACE_HOST prior to build).
+
+You could obviously use this filter to do other types of replacements.
+
h4. External urls
While django-compress does a great job of minimizing the amount of http requests on your site (hence increasing performence) there are sometimes cases

No commit comments for this range

Something went wrong with that request. Please try again.