How to Use django-compressor Offline Compression with Widgy

gavin

Posted by gavin

django

Widgy uses django-compressor in order to process and bundle JavaScript and SCSS assets. django-compressor has two deployment scenarios: in-request compression and offline compression.

Normally we use in-request compression. It is perfectly acceptable for many websites. On the first page that requests a bundle, the bundle is compiled and cached for all future requests.

However, this doesn’t really work for multi-server setups. It’s possible that a page is served from one server and the static file request hits another server. This makes it possible for one server to expect static files that don’t exist on all servers. Also, in a high-performance environment, it may not be desirable to let compression block the request-response cycle, even if it’s only the first request.

In these situations, offline compression may be necessary. With offline compression enabled, django-compressor compiles all the bundles with itscompress management command and stores them using your staticfiles storage. Then requests for the assets can use the precompiled bundle.

Offline compression can be tricky to enable because it requires rendering your templates without the views that normally render them. compressor has a setting called COMPRESS_OFFLINE_CONTEXT that is used as the context to render templates in the absence of a view to provide their context. Here we show how to configure offline compression with Widgy and widgy_mezzanine.

First, create a new file called something like settings_compress_offline.py. By putting all of the compressor related settings in one file, we can enable the offline compression just by importing that file into our settings.

In that file add the following:

# settings_compress_offline.py
COMPRESS_OFFLINE = True

 

Then in your main settings file, add the following:

# settings.py
from .settings_compress_offline import *

 

This will turn on the offline compression mechanism. And you can run the offline compression:

$ python manage.py compress

 

If you try to run this however, you may get some errors, because we need to add some variables to the context.

We need site to the context for widgy_field.html. To add this, we can add the following to settings_compress_offline.py:

# settings_compress_offline.py
def get_site():
    # if not using widgy_mezzanine, just import your widgy site directly here.
    from django.conf import settings
    from widgy.utils import fancy_import
    return fancy_import(settings.WIDGY_MEZZANINE_SITE)


COMPRESS_OFFLINE_CONTEXT = {
    'site': get_site,
}

 

If you are using Widgy with Mezzanine, there are a couple of context variables it needs:

def get_setting_lazy(setting_name):
    """
    Returns a function that returns the value of the setting_name.
    """
    def inner():
        from django.conf import settings
        return getattr(settings, setting_name)
    return inner


def get_mezzanine_settings():
    """
    Returns the value of the mezzanine.conf.context_processors.settings context
    processor. Context processors usually can only be run during a request, but
    luckily, mezzanine ignores the request parameter, so we don't have to worry
    about it.
    """
    from mezzanine.conf.context_processors import settings
    return settings()['settings']

COMPRESS_OFFLINE_CONTEXT = {
    # ...

    'STATIC_URL': get_setting_lazy('STATIC_URL'),
    # some mezzanine templates require the settings.
    'settings': get_mezzanine_settings,
}

 

Test the configuration with manage.py compress. If successful, you are now using offline compression!

The full settings file is available athttps://gist.github.com/gavinwahl/b7e8de4b92cf508ec13c. All code samples are the under the Simplified BSD License.

Learn more about Fusionbox, a python development company.

Return to Articles & Guides