Changelog ========= To be released ------------------- - Officially support Python 3.12 (requires lxml 4.9.3 or higher) v4.4 (2023-06-28) ------------------- `Full list of changes from v4.3.1 `_ - Officially support Django 4.2 v4.3.1 (2023-01-22) ------------------- `Full list of changes from v4.3 `_ - Documentation fixes only v4.3 (2023-01-06) ----------------- `Full list of changes from v4.2 `_ - Officially support Python 3.11 v4.2 (2023-01-06) ----------------- `Full list of changes from v4.1 `_ - Drop Python 3.6 and 3.7 support - Drop Django 2.2 and 3.1 support - Drop SlimItFilter - Update the `CachedS3Boto3Storage` example storage subclass in "Remote Storages" to work properly after the v4.0 change to how duplicate file names are handled by `CompressorFileStorage` - Update rsmin and jsmin versions v4.1 (2022-08-03) ----------------- `Full list of changes from v4.0 `_ - Add Django 4.1 compatibility - New setting ``COMPRESS_OFFLINE_MANIFEST_STORAGE`` to customize the offline manifest's file storage (#1112) With this change the function ``compressor.cache.get_offline_manifest_filename()`` has been removed. You can now use the new file storage ``compressor.storage.default_offline_manifest_storage`` to access the location of the manifest. v4.0 (2022-03-23) ----------------- `Full list of changes from v3.1 `_ - Fix intermittent No such file or directory errors by changing strategy to deal with duplicate filenames in CompressorFileStorage Note: if your project has a custom storage backend following the example of `CachedS3Boto3Storage` from the "Remote Storages" documentation, it will need to be updated to call `save` instead of `_save` to work properly after this change to `CompressorFileStorage`. - Deprecate SlimItFilter, stop testing it with Python 3.7 or higher v3.1 (2021-12-18) ----------------- `Full list of changes from v3.0 `_ - Fix error with verbose offline compression when COMPRESS_OFFLINE_CONTEXT is a generator v3.0 (2021-12-12) ----------------- `Full list of changes from v2.4.1 `_ - Officially support Python 3.9 and 3.10 as well as Django 3.1, 3.2 and 4.0 - Drop support for Django 1.11, 2.1 and 3.0 - Drop support for Python 2.x and 3.4 - Fix compatibility with Jinja 3.x - Require django-sekizai 2.0 for django-sekizai extension - Make template compression in compress command threaded to improve performance - Correctly handle relative paths in ``extends`` tags (#979) - Enable ``rCSSMinFilter`` by default (#888) - Fix various deprecation warnings - Add ability to pass a logger to various classes & methods - Removed deprecated ``COMPRESS_JS_FILTERS`` and ``COMPRESS_CSS_FILTERS`` settings - Fix offline compression race condition, which could result in incomplete manifest v2.4.1 (2021-04-17) ------------------- `Full list of changes from v2.4 `_ - Raise proper ``DeprecationWarning`` for ``COMPRESS_JS_FILTERS`` and ``COMPRESS_CSS_FILTERS`` v2.4 (2019-12-31) ----------------- `Full list of changes from v2.3 `_ - Add support for Django 3.0 (#950, #967) - Officially support Python 3.8 (#967) - Add better support for JS strict mode and validation (#952) - Add support for rel=preload (#951) - Add support for Calmjs (#957) Note: in 2.3, a new setting ``COMPRESS_FILTERS`` has been introduced that combines the existing ``COMPRESS_CSS_FILTERS`` and ``COMPRESS_JS_FILTERS``. The latter are now deprecated. See `the docs `_ on how to use the new setting, the conversion is straightforward. v2.3 (2019-05-31) ----------------- `Full list of changes from v2.2 `_ - Drop support for Django 1.8, 1.9 and 1.10 - Add support for Django 2.1 and 2.2, as well as Python 3.7 - Update all dependencies. This required minor code changes, you might need to update some optional dependencies if you use any - Allow the mixed use of JS/CSS in Sekizai's templatetags ``{% addtoblock "js" %}`` and ``{% addtoblock "css" %}`` (#891) - Allow the implementation of new types other than css and js. (#900) - Update jinja2 extension to behave similar to the django tag (#899) - Fix crash in offline compression when child nodelist is None, again (#605) - Support STATIC_URL and COMPRESS_URL being string-like objects - Improve compress command memory usage (#870) - Ensure generated file always contains a base name (#775) - Add BrotliCompressorFileStorage (#867) v2.2 (2017-08-16) ----------------- `Full list of changes from v2.1.1 `_ - Switch from MD5 to SHA256 for hashes generation. - Add Django 1.11 compatibility - Various compatibility fixes for Python 3.6 and Django 1.8 - Made OfflineGenerationError easier to debug - Drop support for Python 3.2 - Add new CssRelativeFilter which works like CssAbsoluteFilter but outputs relative URLs. - Fix URL CssAbsoluteFilter URL detection v2.1.1 (2017-02-02) ------------------- `Full list of changes from v2.1 `_ - Fix to file permissions issue with packaging. v2.1 (2016-08-09) ----------------- `Full list of changes from v2.0 `_ - Add Django 1.10 compatibility - Add support for inheritance using a variable in offline compression - Fix recursion error with offline compression when extending templates with the same name - Fix UnicodeDecodeError when using CompilerFilter and caching - Fix CssAbsoluteFilter changing double quotes to single quotes, breaking SVG v2.0 (2016-01-07) ----------------- `Full list of changes from v1.6 `_ - Add Django 1.9 compatibility - Remove official support for Django 1.4 and 1.7 - Add official support for Python 3.5 - Remove official support for Python 2.6 - Remove support for coffin and jingo - Fix Jinja2 compatibility for Django 1.8+ - Stop bundling vendored versions of rcssmin and rjsmin, make them proper dependencies - Remove support for CSSTidy - Remove support for beautifulsoup 3. - Replace cssmin by csscompressor (cssmin is still available for backwards-compatibility but points to rcssmin) v1.6 (2015-11-19) ----------------- `Full list of changes from v1.5 `_ - Upgrade rcssmin and rjsmin - Apply CssAbsoluteFilter to precompiled css even when compression is disabled - Add optional caching to CompilerFilter to avoid re-compiling unchanged files - Fix various deprecation warnings on Django 1.7 / 1.8 - Fix TemplateFilter - Fix double-rendering bug with sekizai extension - Fix debug mode using destination directory instead of staticfiles finders first - Removed some silent exception catching in compress command v1.5 (2015-03-27) ----------------- `Full list of changes from v1.4 `_ - Fix compress command and run automated tests for Django 1.8 - Fix Django 1.8 warnings - Handle TypeError from import_module - Fix reading UTF-8 files which have BOM - Fix incompatibility with Windows (shell_quote is not supported) - Run automated tests on Django 1.7 - Ignore non-existent {{ block.super }} in offline compression instead of raising AttributeError - Support for clean-css - Fix link markup - Add support for COMPRESS_CSS_HASHING_METHOD = None - Remove compatibility with old 'staticfiles' app - In compress command, use get_template() instead of opening template files manually, fixing compatibility issues with custom template loaders - Fix FilterBase so that does not override self.type for subclasses if filter_type is not specified at init - Remove unnecessary filename and existence checks in CssAbsoluteFilter v1.4 (2014-06-20) ----------------- - Added Python 3 compatibility. - Added compatibility with Django 1.6.x and dropped support for Django 1.3.X. - Fixed compatibility with html5lib 1.0. - Added offline compression for Jinja2 with Jingo and Coffin integration. - Improved support for template inheritance in offline compression. - Made offline compression avoid compressing the same block multiple times. - Added a ``testenv`` target in the Makefile to make it easier to set up the test environment. - Allowed data-uri filter to handle external/protocol-relative references. - Made ``CssCompressor`` class easier to extend. - Added support for explicitly stating the block being ended. - Added rcssmin and updated rjsmin. - Removed implicit requirement on BeautifulSoup. - Made GzipCompressorFileStorage set access and modified times to the same time as the corresponding base file. - Defaulted to using django's simplejson, if present. - Fixed CompilerFilter to always output Unicode strings. - Fixed windows line endings in offline compression. v1.3 (2013-03-18) ----------------- - *Backward incompatible changes* - Dropped support for Python 2.5. Removed ``any`` and ``walk`` compatibility functions in ``compressor.utils``. - Removed compatibility with some old django settings: - :attr:`~COMPRESS_ROOT` no longer uses ``MEDIA_ROOT`` if ``STATIC_ROOT`` is not defined. It expects ``STATIC_ROOT`` to be defined instead. - :attr:`~COMPRESS_URL` no longer uses ``MEDIA_URL`` if ``STATIC_URL`` is not defined. It expects ``STATIC_URL`` to be defined instead. - :attr:`~COMPRESS_CACHE_BACKEND` no longer uses ``CACHE_BACKEND`` and simply defaults to ``default``. - Added precompiler class support. This enables you to write custom precompilers with Python logic in them instead of just relying on executables. - Made CssAbsoluteFilter smarter: it now handles URLs with hash fragments or querystring correctly. In addition, it now leaves alone fragment-only URLs. - Removed a ``fsync()`` call in ``CompilerFilter`` to improve performance. We already called ``self.infile.flush()`` so that call was not necessary. - Added an extension to provide django-sekizai support. See :ref:`django-sekizai Support ` for more information. - Fixed a ``DeprecationWarning`` regarding the use of ``django.utils.hashcompat`` - Updated bundled ``rjsmin.py`` to fix some JavaScript compression errors. v1.2 ---- - Added compatibility with Django 1.4 and dropped support for Django 1.2.X. - Added contributing docs. Be sure to check them out and start contributing! - Moved CI to Travis: http://travis-ci.org/django-compressor/django-compressor - Introduced a new ``compressed`` context dictionary that is passed to the templates that are responsible for rendering the compressed snippets. This is a **backwards-incompatible change** if you've overridden any of the included templates: - ``compressor/css_file.html`` - ``compressor/css_inline.html`` - ``compressor/js_file.html`` - ``compressor/js_inline.html`` The variables passed to those templates have been namespaced in a dictionary, so it's easy to fix your own templates. For example, the old ``compressor/js_file.html``:: The new ``compressor/js_file.html``:: - Removed old templates named ``compressor/css.html`` and ``compressor/js.html`` that were originally left for backwards compatibility. If you've overridden them, just rename them to ``compressor/css_file.html`` or ``compressor/js_file.html`` and make sure you've accounted for the backwards incompatible change of the template context mentioned above. - Reverted an unfortunate change to the YUI filter that prepended ``'java -jar'`` to the binary name, which doesn't always work, e.g. if the YUI compressor is shipped as a script like ``/usr/bin/yui-compressor``. - Changed the sender parameter of the :func:`~compressor.signals.post_compress` signal to be either :class:`compressor.css.CssCompressor` or :class:`compressor.js.JsCompressor` for easier customization. - Correctly handle offline compressing files that are found in ``{% if %}`` template blocks. - Renamed the second option for the ``COMPRESS_CSS_HASHING_METHOD`` setting from ``'hash'`` to ``'content'`` to better describe what it does. The old name is also supported, as well as the default being ``'mtime'``. - Fixed CssAbsoluteFilter, ``src`` attributes in includes now get transformed. - Added a new hook to allow developers to completely bypass offline compression in CompressorNode subclasses: ``is_offline_compression_enabled``. - Dropped versiontools from required dependencies again. v1.1.2 ------ - Fixed an installation issue related to versiontools. v1.1.1 ------ - Fixed a stupid ImportError bug introduced in 1.1. - Fixed Jinja2 docs of since ``JINJA2_EXTENSIONS`` expects a class, not a module. - Fixed a Windows bug with regard to file resolving with staticfiles finders. - Stopped a potential memory leak when memoizing the rendered output. - Fixed the integration between staticfiles (e.g. in Django <= 1.3.1) and compressor which prevents the collectstatic management command to work. .. warning:: Make sure to **remove** the ``path`` method of your custom :ref:`remote storage ` class! v1.1 ---- - Made offline compression completely independent from cache (by writing a manifest.json file). You can now easily run the ``compress`` management command locally and transfer the :attr:`~django.conf.settings.COMPRESS_ROOT` dir to your server. - Updated installation instructions to properly mention all dependencies, even those internally used. - Fixed a bug introduced in 1.0 which would prevent the proper deactivation of the compression in production. - Added a Jinja2_ :doc:`contrib extension `. - Made sure the rel attribute of link tags can be mixed case. - Avoid overwriting context variables needed for compressor to work. - Stopped the compress management command to require model validation. - Added missing imports and fixed a few :pep:`8` issues. .. _Jinja2: http://jinja.pocoo.org/2/ v1.0.1 ------ - Fixed regression in ``compressor.utils.staticfiles`` compatibility module. v1.0 ---- - **BACKWARDS-INCOMPATIBLE** Stopped swallowing exceptions raised by rendering the template tag in production (``DEBUG = False``). This has the potential to breaking lots of apps but on the other hand will help find bugs. - **BACKWARDS-INCOMPATIBLE** The default function to create the cache key stopped containing the server hostname. Instead the cache key now only has the form ``'django_compressor.'``. To revert to the previous way simply set the ``COMPRESS_CACHE_KEY_FUNCTION`` to ``'compressor.cache.socket_cachekey'``. - **BACKWARDS-INCOMPATIBLE** Renamed ambigously named ``COMPRESS_DATA_URI_MAX_SIZE`` setting to ``COMPRESS_DATA_URI_MAX_SIZE``. It's the maximum size the ``compressor.filters.datauri.DataUriFilter`` filter will embed files as data: URIs. - Added ``COMPRESS_CSS_HASHING_METHOD`` setting with the options ``'mtime'`` (default) and ``'hash'`` for the ``CssAbsoluteFilter`` filter. The latter uses the content of the file to calculate the cache-busting hash. - Added support for ``{{ block.super }}`` to ``compress`` management command. - Dropped Django 1.1.X support. - Fixed compiler filters on Windows. - Handle new-style cached template loaders in the compress management command. - Documented included filters. - Added `Slim It`_ filter. - Added new CallbackOutputFilter to ease the implementation of Python-based callback filters that only need to pass the content to a callable. - Make use of `django-appconf`_ for settings handling and `versiontools`_ for versions. - Uses the current context when rendering the render templates. - Added :func:`post_compress` signal. .. _`Slim It`: http://slimit.org/ .. _`django-appconf`: https://django-appconf.readthedocs.io/ .. _`versiontools`: http://pypi.python.org/pypi/versiontools v0.9.2 ------ - Fixed stdin handling of precompiler filter. v0.9.1 ------ - Fixed encoding related issue. - Minor cleanups. v0.9 ---- - Fixed the precompiler support to also use the full file path instead of a temporarily created file. - Enabled test coverage. - Refactored caching and other utility code. - Switched from SHA1 to MD5 for hash generation to lower the computational impact. v0.8 ---- - Replace naive jsmin.py with rJSmin (http://opensource.perlig.de/rjsmin/) and fixed a few problems with JavaScript comments. - Fixed converting relative URLs in CSS files when running in debug mode. .. note:: If you relied on the ``split_contents`` method of ``Compressor`` classes, please make sure a fourth item is returned in the iterable that denotes the base name of the file that is compressed. v0.7.1 ------ - Fixed import error when using the standalone django-staticfiles app. v0.7 ---- - Created new parser, HtmlParser, based on the stdlib HTMLParser module. - Added a new default AutoSelectParser, which picks the LxmlParser if lxml is available and falls back to HtmlParser. - Use unittest2 for testing goodness. - Fixed YUI JavaScript filter argument handling. - Updated bundled jsmin to use version by Dave St.Germain that was refactored for speed. v0.6.4 ------ - Fixed Closure filter argument handling. v0.6.3 ------ - Fixed options mangling in CompilerFilter initialization. - Fixed tox configuration. - Extended documentation and README. - In the compress command ignore hidden files when looking for templates. - Restructured utilities and added staticfiles compat layer. - Restructered parsers and added a html5lib based parser. v0.6.2 ------ - Minor bugfixes that caused the compression not working reliably in development mode (e.g. updated files didn't trigger a new compression). v0.6.1 ------ - Fixed staticfiles support to also use its finder API to find files during development -- when the static files haven't been collected in ``STATIC_ROOT``. - Fixed regression with the ``COMPRESS`` setting, pre-compilation and staticfiles. v0.6 ---- Major improvements and a lot of bugfixes, some of which are: - New precompilation support, which allows compilation of files and hunks with easily configurable compilers before calling the actual output filters. See the :attr:`~django.conf.settings.COMPRESS_PRECOMPILERS` for more details. - New staticfiles support. With the introduction of the staticfiles app to Django 1.3, compressor officially supports finding the files to compress using the app's finder API. Have a look at the documentation about :ref:`remote storages ` in case you want to use those together with compressor. - New ``compress`` management command which allows pre-running of what the compress template tag does. - Various performance improvements by better caching and mtime checking. - Deprecated ``COMPRESS_LESSC_BINARY`` setting because it's now superseded by the :attr:`~django.conf.settings.COMPRESS_PRECOMPILERS` setting. Just make sure to use the correct mimetype when linking to less files or adding inline code and add the following to your settings:: COMPRESS_PRECOMPILERS = ( ('text/less', 'lessc {infile} {outfile}'), ) - Added cssmin_ filter (``compressor.filters.CSSMinFilter``) based on Zachary Voase's Python port of the YUI CSS compression algorithm. - Reimplemented the dog-piling prevention. - Make sure the CssAbsoluteFilter works for relative paths. - Added inline render mode. See :ref:`usage ` docs. - Added ``mtime_cache`` management command to add and/or remove all mtimes from the cache. - Moved docs to Read The Docs: https://django-compressor.readthedocs.io/en/latest/ - Added optional ``compressor.storage.GzipCompressorFileStorage`` storage backend that gzips of the saved files automatically for easier deployment. - Reimplemented a few filters on top of the new ``compressor.filters.base.CompilerFilter`` to be a bit more DRY. - Added tox based test configuration, testing on Django 1.1-1.3 and Python 2.5-2.7. .. _cssmin: http://pypi.python.org/pypi/cssmin/