Asset management for Django =========================== Assets are defined inline in templates: {% load assets %} {% assets filter="jsmin", output="packed.js", "common/file1.js", "common/file2.js", "cadmin/file3.js" %} {% endassets %} Apart from any number of source files, the following keyword-like arguments can be passed to the template tag: * output: Name/path of the output file. All source files will be merged and the result stored at this location. * filter: The filter to apply to the merged file. Currently, the following filters are supported: * jsmin * jspacker * cssutils * yui_js * yui_css * gzip * cssrewrite * clevercss If the filter argument is missing, none will be applied (merge only). Multiple filters are supported as well (separate with commas). Note that all filenames/paths must be relative to MEDIA_URL and MEDIA_ROOT. The templatetag will usually render it's contents once for the final output file, but can output links to the unmodified source file themselves (see the ASSETS_DEBUG setting). All urls are prefixed with MEDIA_URL. How assets are built -------------------- Assets can be updated automatically, or built manually using a management command. By default, if the filesystem modification date of any of the source files exceeds the target file's, the target will be recreated. This behaviour can be disabled or changed using the ASSETS_UPDATER setting. The management command for a manual rebuild is used like this: ./manage.py assets rebuild This will go through all the templates in your project and tries to find all assets you have in use. It will then create or recreate them. Rewriting CSS relative urls --------------------------- If your output file is stored at a path different from any of the original source file, relative URLs within CSS will likely become invalid. To avoid this, apply the "cssrewrite" filter which will fix url() instructions. Jinja support ------------- django-assets strives to also offer full support for Jinja (version 2). An extension is available in: ``django_assets.jinja.extension.assets`` It will provide a {% assets %} tag that functions pretty much like the Django template version, except inheriting the more expressive syntax of Jinja. For example, filters may be specified as tuples: {% assets filter=("jsmin", "gzip") ... %} There is a minor catch if you intend to use the management command to manually rebuild assets: Since that step involves parsing your templates, the command needs to know what extensions you are using. Because there is no "one way" to integrate Jinja and Django, it can't do so by itself. Instead, it expects you to specify the ``ASSETS_JINJA2_EXTENSIONS`` setting. In most cases, you would simply to something like ASSETS_JINJA2_EXTENSIONS = JINJA2_EXTENSIONS i.e. aliasing it to the actual setting you are using. Settings -------- ASSETS_DEBUG can be used to switch off or modify asset functionality during debugging. Apart from False, supported values "nomerge" and "nofilter", the latter only disabling the application of filters, the former causing the unmodified source files to be given out. You can make the value of this dependent on your DEBUG setting. ASSETS_UPDATER modifies the auto-rebuild behaviour. By default, this is set to "timestamp", e.g. assets will be updated when a change can be determined via the filesystem modification dates. Currently, the only other usable values are "always" and "never", the former only recommended during debugging, the latter useful if you want to limit yourself to manual building. ASSETS_AUTO_CREATE defaults to True and can be used to disable automatic creation of an assets even if it does not exist yet. This is useful in combination with ASSETS_UPDATER="never", to disable any sort of automatic asset building. ASSETS_EXPIRE is needed if you send your assets to the client using a far future expires header. Unless set to False, it will modify the asset url using it's modification timestamp, so that browsers will reload the file when necessary. Possible values are "querystring" (asset.js?1212592199) and "filename" (asset.1212592199.js). The latter might work better with certain proxies or exotic browers, but will require you to rewrite those modified filenames via your webserver. ASSETS_JINJA2_EXTENSIONS is needed in some cases if you want to use django-assets within the Jinja template system. For more information, see the "Jinja support" section. Dependencies ------------ Nose is required to run the tests: http://somethingaboutorange.com/mrl/projects/nose/ Future TODOs ------------ * Maybe an alternative way to define assets within Python might make sense after all, e.g. say assets.register() calls, by convention in app/assets.py. * Automatically create (and delete, i.e. manage) symlinks to make the ASSETS_EXPIRE="filename" option work without server rewrites. * Support functionality for applying a filter directly within a template, i.e. pack inline scripts; also, if the output argument to {%assets%} is missing, the result could be piped directly into the template. * Should be provide features for normalizing encodings? * Handle far future expires for images: add a new templatetag that can output image urls with timestamps; the cssrewrite filter could modify urls within CSS files when ASSETS_EXPIRE is enabled. * Find a good solution to making filter debug/log information available in a standardized way across the board. * Allow an option to fall back to rendering source files in case asset building fails for some reason. Right now, the user would get to see a server error. This would probably most simply be accomplished by having AssetsNode catch exceptions in create_merged() and redirect to render_sources. We probably want to activate this only in production mode. * Support asset deployment to services like Amazon S3.