Static assets

Introduction

In web development, static asset refer to JavaScript, CSS and image files which are part of the website, but not usually generated by the web server itself. Static assets come with caching mechanisms to make websites load faster. Furthermore caching mechanisms come with cache busting mechanisms to make sure that when you update your website all connected clients get updated versions of static assets.

Referring static assets

Use pyramid.request.Request.static_url(). In templates use static_url filter.

<link rel="stylesheet" href="{{ 'websauna.system:static/theme.css'|static_url }}">

<img src="{{ 'myapp:static/logo.png'|static_url }}" alt="myapp">

The return value of static_url can be a random string depending on configured cache busting policy on the production server.

Adding static assets

Static assets are added through a static asset policy, an instance of websauna.system.http.static.DefaultStaticAssetPolicy. You can access this during the application initialization through:

static_asset_policy = self.config.registry.static_asset_policy

The policy has a method websauna.system.http.DefaultStaticAssetPolicy.add_static_view() to map folders in Python packages as static asset source folders. It is similar as underlying pyramid.configurator.Configurator.add_static_view() and adds a cache busting mechanism to added static views.

In your Initializer, override websauna.system.Initializer.configure_static() to incude more static views:

def configure_static(self):
    self.config.registry.static_asset_policy.add_static_view('myapp-static', 'myapp:static')

You need to have a folder static inside a Python module myapp.

Development web server runs without caching

The development web server using development.ini does not have any kind of cache busting configured. HTTP responses do not have cache headers. Static URLs are not mangled in whatsoever manner.

Default cache busting mechanism

The default cache busting mechanism is

  • Designed to be simple. Works on any web server with file system write access.
  • Hot deploys friendly, so that a website update does not break client browsers which are currently downloading static assets.

ws-collect-static: assembling cache busting information

When you deploy a new version of website you need to run ws-collect-static command. The command scans all configured static folders and creates permanent, MD5 hashed, copies of all files. If the content of the file changes, its MD5 hash changes, and pyramid.request.Request.static_url() can give a different URL pointing to the asset. Having a different URL invalidates the client cache.

By default cached content is placed in perma-asset folder next to the files inside the original static asset folder. This folder is included in .gitignore.

To run the command:

ws-collect-static conf/production

This will generate following structure inside each static folder:

static/perma-assets                      # A folder to store MD5 hashed files permanently
static/perma-assets/.manifest.json       # List of all current assets
static/perma-assets/boostrap.234131.css  # MD5 stamped asset file
...

Enabling cache and cache busting

The default cache busting mechanism has one setting

This is configured to two weeks in production.ini.

More information

You can find more advanced examples and integrations with CDN and asset pipelines (gulp) in Pyramid documentation.

Static assets and cache busting in Pyramid documentation.