Last active
July 6, 2016 20:41
-
-
Save kottenator/fe4b0a05d1645af6986fbfdd407c57a7 to your computer and use it in GitHub Desktop.
django-compressor - abstract static URL
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
Django 'base' app - compressor filters. | |
""" | |
from compressor.filters.css_default import CssAbsoluteFilter | |
class CssRelativeFilter(CssAbsoluteFilter): | |
""" | |
``compressor.filters.css_default.CssAbsoluteFilter`` converts relative URLs to images, fonts, etc | |
in CSS code to absolute URLs like '/static/base/images/logo.svg'. | |
But STATIC_URL may change in different environments - | |
this is important for offline compression. | |
All compressed CSS files are served on URLs like '/static/CACHE/css/25b44215c797.css'. | |
So we can convert relative URLs inside '/static/CACHE/css/25b44215c797.css' | |
to '../../base/images/logo.svg' which works with _any_ STATIC_URL. | |
""" | |
def __init__(self, *args, **kwargs): | |
super(CssRelativeFilter, self).__init__(*args, **kwargs) | |
self.url = '../..' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
Django 'base' app - config. | |
""" | |
from functools import wraps | |
from compressor.management.commands.compress import Command | |
from compressor.templatetags.compress import CompressorNode | |
from django.apps.config import AppConfig | |
from django.conf import settings | |
class BaseConfig(AppConfig): | |
name = 'base' | |
STATIC_URL_PLACEHOLDER = '$STATIC_URL/' | |
def ready(self): | |
self._patch_compressor() | |
def _patch_compressor(self): | |
""" | |
Patch ``django-compressor`` to read/write offline manifest with STATIC_URL replaced | |
by special placeholder, because STATIC_URL may change in different environments. | |
""" | |
# Patch django-compressor offline manifest generator command | |
self._patch_compressor_method(Command, 'compress') | |
# Patch django-compressor offline manifest check | |
self._patch_compressor_method( | |
CompressorNode, 'render_offline', lambda r, u: r.replace(self.STATIC_URL_PLACEHOLDER, u) | |
) | |
def _patch_compressor_method(self, cls, name, post_process=None): | |
""" | |
Replace class method with patched one: | |
- substitute ``settings.STATIC_URL`` with special placeholder | |
- execute original method | |
- optionally, post-process method return value | |
- restore original ``settings.STATIC_URL`` value | |
:param type cls: Class object to patch | |
:param str name: Class method name | |
:param function post_process: Takes 2 arguments: method return value and static URL | |
""" | |
method = getattr(cls, name) | |
placeholder = self.STATIC_URL_PLACEHOLDER | |
if hasattr(method, '_original'): | |
return | |
@wraps(method) | |
def patched_method(self, *args, **kwargs): | |
static_url = settings.STATIC_URL | |
# TODO: some processing for settings.COMPRESS_URL needed | |
settings.STATIC_URL = settings.COMPRESS_URL = placeholder | |
try: | |
result = method(self, *args, **kwargs) | |
if post_process is not None: | |
result = post_process(result, static_url) | |
return result | |
finally: | |
# TODO: some processing for settings.COMPRESS_URL needed | |
settings.STATIC_URL = settings.COMPRESS_URL = static_url | |
patched_method._original = method | |
setattr(cls, name, patched_method) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
INSTALLED_APPS = [ | |
'base.conf.BaseConfig' | |
] | |
COMPRESS_CSS_FILTERS = [ | |
'base.compressor_filters.CssRelativeFilter' | |
] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment