Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: matthewwithanm/django-imagekit
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 5.0
Choose a base ref
...
head repository: matthewwithanm/django-imagekit
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: develop
Choose a head ref
  • 10 commits
  • 5 files changed
  • 3 contributors

Commits on Jul 23, 2014

  1. allow Django template to supress missing src errors

    Paul Garner committed Jul 23, 2014
    Copy the full SHA
    491bc24 View commit details

Commits on Sep 28, 2023

  1. Merge branch 'master' into develop

    * master:
      Bump version to 5.0.0
      Update setup.py
      Update advanced_usage.rst
    vstoykov committed Sep 28, 2023
    Copy the full SHA
    92dff00 View commit details

Commits on Jun 20, 2024

  1. Copy the full SHA
    366687a View commit details

Commits on Jun 26, 2024

  1. Copy the full SHA
    02d60e2 View commit details

Commits on Jul 8, 2024

  1. Add tests

    autoantwort committed Jul 8, 2024
    Copy the full SHA
    3cdeba8 View commit details
  2. Add srcset tests

    autoantwort committed Jul 8, 2024
    Copy the full SHA
    5811279 View commit details

Commits on Jul 22, 2024

  1. Merge pull request #574 from autoantwort/default-thumbnail-format

    Add way to specify thumbnail format
    vstoykov authored Jul 22, 2024
    Copy the full SHA
    c4ed0bb View commit details
  2. Copy the full SHA
    973990d View commit details
  3. Merge pull request #575 from autoantwort/feature/srcset

    Make it possible to generate srcset with the thumbnail template tag
    vstoykov authored Jul 22, 2024
    Copy the full SHA
    aea457b View commit details
  4. Merge pull request #288 from anentropic/silent-failures

    Option to suppress exceptions with templatetags
    vstoykov authored Jul 22, 2024
    Copy the full SHA
    4cbbc52 View commit details
Showing with 67 additions and 3 deletions.
  1. +16 −0 docs/configuration.rst
  2. +1 −1 imagekit/exceptions.py
  3. +4 −1 imagekit/generatorlibrary.py
  4. +30 −1 imagekit/templatetags/imagekit.py
  5. +16 −0 tests/test_thumbnail_tag.py
16 changes: 16 additions & 0 deletions docs/configuration.rst
Original file line number Diff line number Diff line change
@@ -10,13 +10,29 @@ Settings
.. currentmodule:: django.conf.settings


.. attribute:: IMAGEKIT_DEFAULT_THUMBNAIL_FORMAT

:default: ``None``

The output format of the images generated by the ``thumbnail`` template tag.


.. attribute:: IMAGEKIT_CACHEFILE_DIR

:default: ``'CACHE/images'``

The directory to which image files will be cached.


.. attribute:: IMAGEKIT_DEFAULT_THUMBNAIL_SRCSET_SCALES

:default: ``None``

A list of scale factors, for example ``[2, 3]``. If specified, every
``<img>`` generated by the ``thumbnail`` template tag will have a ``srcset``
attribute with the given scales. To prevent this, set ``srcset=None``.


.. attribute:: IMAGEKIT_DEFAULT_FILE_STORAGE

:default: ``None``
2 changes: 1 addition & 1 deletion imagekit/exceptions.py
Original file line number Diff line number Diff line change
@@ -14,7 +14,7 @@ class MissingGeneratorId(Exception):


class MissingSource(ValueError):
pass
silent_variable_failure = True


# Aliases for backwards compatibility
5 changes: 4 additions & 1 deletion imagekit/generatorlibrary.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
from .processors import Thumbnail as ThumbnailProcessor
from .registry import register
from .specs import ImageSpec
from django.conf import settings

default_thumbnail_format = getattr(settings, 'IMAGEKIT_DEFAULT_THUMBNAIL_FORMAT', None)

class Thumbnail(ImageSpec):
def __init__(self, width=None, height=None, anchor=None, crop=None, upscale=None, **kwargs):
def __init__(self, width=None, height=None, anchor=None, crop=None, upscale=None, format=default_thumbnail_format, **kwargs):
self.processors = [ThumbnailProcessor(width, height, anchor=anchor,
crop=crop, upscale=upscale)]
super().__init__(**kwargs)
self.format = format


register.generator('imagekit:thumbnail', Thumbnail)
31 changes: 30 additions & 1 deletion imagekit/templatetags/imagekit.py
Original file line number Diff line number Diff line change
@@ -3,6 +3,7 @@
from django.utils.encoding import force_str
from django.utils.html import escape
from django.utils.safestring import mark_safe
from django.conf import settings

from ..cachefiles import ImageCacheFile
from ..registry import generator_registry
@@ -13,6 +14,7 @@
ASSIGNMENT_DELIMETER = 'as'
HTML_ATTRS_DELIMITER = '--'
DEFAULT_THUMBNAIL_GENERATOR = 'imagekit:thumbnail'
default_thumbnail_srcset_scales = getattr(settings, 'IMAGEKIT_DEFAULT_THUMBNAIL_SRCSET_SCALES', None)


def get_cachefile(context, generator_id, generator_kwargs, source=None):
@@ -97,6 +99,8 @@ def render(self, context):
# recursion errors when anchor is set to a SafeString instance.
# This converts the SafeString into a str instance.
kwargs['anchor'] = kwargs['anchor'][:]
if kwargs.get('format'):
kwargs['format'] = kwargs['format'][:]
generator = generator_registry.get(generator_id, **kwargs)

context[variable_name] = ImageCacheFile(generator)
@@ -124,9 +128,27 @@ def render(self, context):
# recursion errors when anchor is set to a SafeString instance.
# This converts the SafeString into a str instance.
kwargs['anchor'] = kwargs['anchor'][:]
srcset_scales = default_thumbnail_srcset_scales
if "srcset" in kwargs:
if kwargs['srcset'] is not None:
srcset_scales = list(map(float, kwargs['srcset'].split()))
else:
srcset_scales = None
kwargs.pop("srcset")
if kwargs.get('format'):
kwargs['format'] = kwargs['format'][:]
generator = generator_registry.get(generator_id, **kwargs)

file = ImageCacheFile(generator)
srcset = []
if srcset_scales:
for scale in srcset_scales:
scaled_kwargs = dict(kwargs)
if scaled_kwargs.get("height"):
scaled_kwargs["height"] = int(scaled_kwargs["height"] * scale)
if scaled_kwargs.get("width"):
scaled_kwargs["width"] = int(scaled_kwargs["width"] * scale)
srcset.append(ImageCacheFile(generator_registry.get(generator_id, **scaled_kwargs)))

attrs = {k: v.resolve(context) for k, v in self._html_attrs.items()}

@@ -136,6 +158,9 @@ def render(self, context):
attrs.update(width=file.width, height=file.height)

attrs['src'] = file.url
if len(srcset) > 0:
attrs['srcset'] = f'{file.url} 1x , ' + ' , '.join(
f'{entry[0].url} {entry[1]}x' for entry in zip(srcset, srcset_scales))
attr_str = ' '.join('%s="%s"' % (escape(k), escape(v)) for k, v in
attrs.items())
return mark_safe('<img %s />' % attr_str)
@@ -241,7 +266,11 @@ def thumbnail(parser, token):
The thumbnail tag supports the "--" and "as" bits for adding html
attributes and assigning to a variable, respectively. It also accepts the
kwargs "anchor", and "crop".
kwargs "format", "srcset", "anchor", and "crop".
To use "srcset" (generating multiple thumbnails for different pixel densities) list the scale factors::
{% thumbnail '100x100' mymodel.profile_image srcset='2 3' %}
To use "smart cropping" (the ``SmartResize`` processor)::
16 changes: 16 additions & 0 deletions tests/test_thumbnail_tag.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import pytest
import re
from django.template import TemplateSyntaxError

from . import imagegenerators # noqa
@@ -87,3 +88,18 @@ def test_alternate_generator():
clear_imagekit_cache()
html = render_tag(ttag)
assert html == '1'


def test_srcset_arg():
ttag = r"""{% thumbnail '100x' img srcset="1.5 2" %}"""
clear_imagekit_cache()
html = render_tag(ttag)
srcset_regex = re.compile('srcset=".* 1x ,.* 1\\.5x ,.* 2.0x"')
assert srcset_regex.search(html) is not None


def test_alternate_format():
ttag = r"""{% thumbnail '100x' img format='webp' as th %}{{ th.url }}"""
clear_imagekit_cache()
html = render_tag(ttag)
assert html.endswith('webp')