Source code for smart_media.templatetags.smart_image
from django import template
from django.conf import settings
from sorl.thumbnail.shortcuts import get_thumbnail
from ..exceptions import (
InvalidFormatError, IncompatibleSvgToBitmap, IncompatibleBitmapToSvg
)
from ..mixins import SmartFormatMixin
from ..thumbnailing import SvgFile
register = template.Library()
[docs]@register.simple_tag
def media_thumb(source, geometry, *args, **kwargs):
"""
Determine the right format and return the Sorl thumb file url path for
given image file.
.. _Sorl: https://github.com/jazzband/sorl-thumbnail
Arguments:
source (object): Either a FileField or an ImageField.
geometry (string): Geometry string as expected by Sorl. It should be
something like ``200`` for 200px width and automatic height or
``200x100`` for 200px width and 100px height.
*args: Not used, there is no other expected positionnal arguments.
**kwargs: Keyword arguments are passed to `Sorl`_, watch its documentation
for more details.
Keyword Arguments:
format (string):
An available format name from settings ``SMART_FORMAT_AVAILABLE_FORMATS``:
* ``PNG``, ``JPEG`` and ``GIF`` enforce the thumb format no matter
the source image format. Be careful to not enforce a format where
a SVG is a possible source format, since Sorl can't read SVG.
* ``SVG`` will not produce any thumb, just return the same path
than the source one since SVG does not need a thumb and is not
supported from image libraries.
* ``auto`` to automatically find and use the same format than
the source image. This is the recommended way.
When argument is empty the default value is ``auto``.
Example:
The most basic usage is to define only thumbnail geometry in default
"auto" format mode: ::
{% load smart_image %}
{% media_thumb instance.image "250x200" as thumb %}
<img src="{{ thumb.url }}" alt="">
You can also enforce a specific format: ::
{% load smart_image %}
{% media_thumb instance.image "250x200" format="JPEG" as thumb %}
<img src="{{ thumb.url }}" alt="">
Keep it in mind this will raise an error with SVG image files (if you
allowed SVG format in plugins) since image libraries (like Pillow or
ImageMagick) has no support for SVG.
Every argument but ``format`` is passed to Sorl, so for cropping an image you
can do : ::
{% load smart_image %}
{% media_thumb instance.image "250x200" crop="center" as thumb %}
<img src="{{ thumb.url }}" alt="">
Again, see `Sorl`_ documentation to know about available options.
Return:
sorl.thumbnail.images.ImageFile or SvgFile: Either Sorl ImageFile instance for
created thumb or SvgFile which mimic Sorl ImageFile.
"""
# Safe return when there is no source file
# NOTE: Should trigger a warning log ?
if not source:
return None
required_format = kwargs.pop("format", "auto")
source_extension = source.name.split(".")[-1].lower()
available_extensions = [k for k, v in settings.SMART_FORMAT_AVAILABLE_FORMATS]
# Automatic format guess
if required_format.lower() == "auto":
required_format = SmartFormatMixin().media_format(source)
# Specific SVG format
elif required_format.lower() == "svg":
# A bitmap file cannot be converted to a SVG
if source_extension != "svg":
msg = ("Incompatible required format (SVG) with source format "
"(Bitmap).")
raise IncompatibleBitmapToSvg(msg.format(
format_name=required_format.lower(),
))
# SVG to SVG is correct (nothing to do)
return SvgFile(source)
# Unknown format
elif required_format.lower() not in available_extensions:
msg = ("Required format '{format_name}' does not match available "
"formats: {available}")
raise InvalidFormatError(msg.format(
format_name=required_format.lower(),
available=", ".join(available_extensions),
))
# SVG source with required bitmap format
elif source_extension == "svg":
msg = ("Incompatible required format (Bitmap) with source format "
"(SVG).")
raise IncompatibleSvgToBitmap(msg.format(
format_name=required_format.lower(),
))
kwargs["format"] = required_format
# Vector format does not create a thumb and so just return original
# source file
if required_format == "SVG":
return SvgFile(source)
# Here we assume the format is ok, if it has been manually defined, user
# is responsible about possible error with its content
return get_thumbnail(source, geometry, **kwargs)