コード例 #1
0
    def render(self, context):
        try:
            image = self.image_expr.resolve(context)
            mode = self.mode_expr.resolve(context)
            # We call abs() just in case the user set one of the dimensions to a negative number.
            width = abs(int(
                self.width_expr.resolve(context))) if self.width_expr else 1
            height = abs(int(
                self.height_expr.resolve(context))) if self.height_expr else 1
        except template.VariableDoesNotExist:
            return ''

        if not image:
            return ''

        # Build a filter spec based on the specified mode, height, and width for the base rendition.
        if mode == 'width':
            base_spec = "width-{}".format(width)
        elif mode == 'height':
            base_spec = "height-{}".format(height)
        else:
            base_spec = "{}-{}x{}-c100".format(mode, width, height)
        base_rendition = get_rendition_or_not_found(image,
                                                    Filter(spec=base_spec))

        # Build the fallback <img> tag for browsers that don't support <picture>.
        custom_attrs = {
            attr_name: expression.resolve(context)
            for attr_name, expression in self.attrs.items()
        }
        img_tag = base_rendition.img_tag(custom_attrs)

        # If the image is wider than a phone, add an additional, smaller rendition with the same aspect ratio.
        small_width = 425
        # Two notes here:
        # 1) We used 'from __future__ import division' to make this use floating point division.
        # 2) Filter specs don't accept floats, so we need to cast back to int at the end.
        small_height = int(height * (small_width / width))
        if mode == 'width':
            small_spec = "width-{}".format(small_width)
        else:
            # TODO: If the mode is 'height', this might not look right. I'm not really sure, though.
            small_spec = "fill-{}x{}-c100".format(small_width, small_height)
        small_rendition = get_rendition_or_not_found(image,
                                                     Filter(spec=small_spec))

        return """
            <picture>
              <source srcset="{small.url}" media="(max-width: 499px)">
              <source srcset="{full.url}" media="(min-width: 500px)">
              {img_tag}
            </picture>
        """.format(img_tag=img_tag, full=base_rendition, small=small_rendition)
コード例 #2
0
    def test_fallback_to_not_found(self):
        bad_image = Image.objects.get(id=1)
        good_image = Image.objects.create(
            title="Test image",
            file=get_test_image_file(),
        )

        rendition = get_rendition_or_not_found(good_image, 'width-400')
        self.assertEqual(rendition.width, 400)

        rendition = get_rendition_or_not_found(bad_image, 'width-400')
        self.assertEqual(rendition.file.name, 'not-found')
コード例 #3
0
    def render_html(self, name, value, attrs):
        image, value = self.get_instance_and_id(self.image_model, value)
        original_field_html = super().render_html(name, value, attrs)

        if image:
            preview_image = get_rendition_or_not_found(image, 'max-165x165')
        else:
            preview_image = None

        return render_to_string(
            "wagtailimages/widgets/image_chooser.html", {
                'widget':
                self,
                'original_field_html':
                original_field_html,
                'attrs':
                attrs,
                'value':
                value,
                'title':
                image.title if image else '',
                'preview': {
                    'url': preview_image.url,
                    'width': preview_image.width,
                    'height': preview_image.height,
                } if preview_image else {},
                'edit_url':
                reverse('wagtailimages:edit', args=[image.id])
                if image else '',
            })
コード例 #4
0
    def render(self, context):
        try:
            image = self.image_expr.resolve(context)
        except template.VariableDoesNotExist:
            return ""

        if not image:
            if self.output_var_name:
                context[self.output_var_name] = None
            return ""

        if not hasattr(image, "get_rendition"):
            raise ValueError("image tag expected an Image object, got %r" %
                             image)

        rendition = get_rendition_or_not_found(image, self.filter)

        if self.output_var_name:
            # return the rendition object in the given variable
            context[self.output_var_name] = rendition
            return ""
        else:
            # render the rendition's image tag now
            resolved_attrs = {}
            for key in self.attrs:
                resolved_attrs[key] = self.attrs[key].resolve(context)
            return rendition.img_tag(resolved_attrs)
コード例 #5
0
def get_original_rendition(image):
    """
    Returns the original image rendition. Needed to get the correct image URL for processing
    when using external storage (such as S3)
    """
    from wagtail.images.shortcuts import get_rendition_or_not_found
    return get_rendition_or_not_found(image, 'original')
コード例 #6
0
ファイル: views.py プロジェクト: BertrandBordage/wagtail
 def get_image_field_display(self, field_name, field):
     """ Render an image """
     from wagtail.images.shortcuts import get_rendition_or_not_found
     image = getattr(self.instance, field_name)
     if image:
         return get_rendition_or_not_found(image, 'max-400x400').img_tag
     return self.model_admin.get_empty_value_display(field_name)
コード例 #7
0
    def render(self, context):
        try:
            image = self.image_expr.resolve(context)
            mode = self.mode_expr.resolve(context)
            # We call abs() just in case the user set one of the dimensions to a negative number.
            width = abs(int(
                self.width_expr.resolve(context))) if self.width_expr else 0
            height = abs(int(
                self.height_expr.resolve(context))) if self.height_expr else 0
        except template.VariableDoesNotExist:
            return ''

        if not image:
            return ''

        # Build a filter spec based on the specified mode, height, and width for the base rendition.
        if mode == 'width':
            spec = "width-{}".format(width)
        elif mode == 'height':
            spec = "height-{}".format(height)
        else:
            spec = "{}-{}x{}-c100".format(mode, width, height)
        rendition = get_rendition_or_not_found(image, Filter(spec=spec))

        if self.output_var_name:
            # Save the rendition into the context, instead of outputting a tag.
            context[self.output_var_name] = rendition
            return ''
        else:
            # Resolve custom attrs to their value in this context, then print them within this rendition's <img> tag.
            custom_attrs = {
                attr_name: expression.resolve(context)
                for attr_name, expression in self.attrs.items()
            }
            return rendition.img_tag(custom_attrs)
コード例 #8
0
 def get_image_field_display(self, field_name, field):
     """ Render an image """
     from wagtail.images.shortcuts import get_rendition_or_not_found
     image = getattr(self.instance, field_name)
     if image:
         return get_rendition_or_not_found(image, 'max-400x400').img_tag
     return self.model_admin.get_empty_value_display(field_name)
コード例 #9
0
def get_rendition_or_not_found_patch(image, filter):
    """
    This function is a monkey patch of wagtail.images.shortcuts.get_rendition_or_not_found (v2.1).
    Here, we try to find the requested rendition in Python before calling the original function.

    Wagtail's (v2.1) 'get_rendition_or_not_found' uses the ORM's 'get' method to lookup every image rendition,
    which causes a database request for every image we render. This implementation is really slow.

    Even worse, this method does not respect prefetch_related('renditions') so we cannot optimize this tag using
    ORM wizardry alone.

    This fix will allow you to use prefetch_related on renditions and grab all your renditions in one query.
    If you do not use prefetch related, then this function performs roughly as bad as it did before.
    """
    if type(filter) is str:
        filter = Filter(spec=filter)

    filter_spec = filter.spec
    focal_point_key = filter.get_cache_key(image)

    # This loop assumes that you've prefetched your image's renditions
    rendition = None
    for rend in image.renditions.all():
        if rend.filter_spec == filter_spec and rend.focal_point_key == focal_point_key:
            rendition = rend

    if not rendition:
        rendition = get_rendition_or_not_found(image, filter)

    return rendition
コード例 #10
0
    def admin_thumb(self, obj):
        try:
            image = getattr(obj, self.thumb_image_field_name, None)
        except AttributeError:
            raise ImproperlyConfigured(
                u"The `thumb_image_field_name` attribute on your `%s` class "
                "must name a field on your model." % self.__class__.__name__
            )

        img_attrs = {
            'src': self.thumb_default,
            'width': self.thumb_image_width,
            'class': self.thumb_classname,
        }
        if not image:
            if self.thumb_default:
                return mark_safe('<img{}>'.format(flatatt(img_attrs)))
            return ''

        # try to get a rendition of the image to use
        from wagtail.images.shortcuts import get_rendition_or_not_found
        spec = self.thumb_image_filter_spec
        rendition = get_rendition_or_not_found(image, spec)
        img_attrs.update({'src': rendition.url})
        return mark_safe('<img{}>'.format(flatatt(img_attrs)))
コード例 #11
0
ファイル: markup.py プロジェクト: torchbox/wagtail-webstories
def _replace_image_id(match):
    try:
        image = Image.objects.get(id=match.group(1))
    except Image.DoesNotExist:
        return ''

    rendition = get_rendition_or_not_found(image, 'original')
    return 'src="%s"' % escape(rendition.url)
コード例 #12
0
 def get_value_data_from_instance(self, instance):
     data = super().get_value_data_from_instance(instance)
     preview_image = get_rendition_or_not_found(instance, "max-165x165")
     data["preview"] = {
         "url": preview_image.url,
         "width": preview_image.width,
         "height": preview_image.height,
     }
     return data
コード例 #13
0
    def image_to_html(self, image, alt_text, extra_attributes=None):
        if extra_attributes is None:
            extra_attributes = {}
        rendition = get_rendition_or_not_found(image, self.filter_spec)
        extra_attributes['alt'] = escape(alt_text)
        default_html = rendition.img_tag(extra_attributes)

        return format_html(
            "<div class='{}'>{}<figcaption>{}</figcaption></div>",
            "%s" % escape(self.classnames), default_html, alt_text)
コード例 #14
0
        def get_form_extra_data(form):
            """
            Some components require a bit of extra data in order to render properly.

            For example, the choosers need to know the name of the thing they
            have been linked to (while the field value is just the ID).

            This function returns this extra data for a particular form in a mapping
            of field names => values.
            """
            if not form.instance:
                return {}

            data = {}

            # Find choosers
            for bound_field in form:
                field_name = bound_field.name
                field = bound_field.field
                value = bound_field.value()

                if isinstance(field.widget, forms.HiddenInput):
                    continue

                if isinstance(field, forms.ModelChoiceField):
                    model = field.queryset.model
                    obj = model.objects.filter(pk=value).first()

                    if obj is not None:
                        if issubclass(model, Page):
                            data[field_name] = {
                                'title': obj.title
                            }
                        elif issubclass(model, AbstractImage):
                            rendition = get_rendition_or_not_found(obj, 'max-130x130')
                            data[field_name] = {
                                'title': obj.title,
                                'preview_image': {
                                    'src': rendition.url,
                                    'alt': rendition.alt,
                                    'width': rendition.width,
                                    'height': rendition.height,
                                }
                            }
                        elif issubclass(model, Document):
                            data[field_name] = {
                                'title': obj.title
                            }
                        else:
                            data[field_name] = {
                                'title': str(obj)
                            }

            return data
コード例 #15
0
ファイル: srcset.py プロジェクト: janun/janunde
def srcset(image, filter_specs):
    """
    generate a list of image renditions suitable for html5 srcset
    usage:
        srcset="{{ image|srcset:'width-320|jpg width-640|jpg' }}"
    """
    sources = {}
    for filter_spec in filter_specs.split(" "):
        rendition = get_rendition_or_not_found(image, filter_spec)
        if not rendition.width in sources:
            sources[rendition.width] = "%s %iw" % (rendition.url, rendition.width)
    return ", ".join(sources.values())
コード例 #16
0
ファイル: serializers.py プロジェクト: marqpdx/Wagtail-Pipit
    def get_renditions(self, obj):
        if hasattr(self, "_mocked_renditions"):
            return self._mocked_renditions

        if not hasattr(self, "_renditions"):
            return None

        renditions = {}
        for (name, spec) in self._renditions:
            rendition = get_rendition_or_not_found(obj, spec)
            renditions[name] = rendition.attrs_dict

        return renditions
コード例 #17
0
    def get_seo_twitter_image(self, page):
        root_url = page.get_site().root_url
        image = page.seo_twitter_image

        if not image:
            return None

        rendition = get_rendition_or_not_found(image, "max-1200x630")

        if not rendition:
            return None

        return f"{root_url}{rendition.url}"
コード例 #18
0
ファイル: models.py プロジェクト: kingsdigitallab/mmee-django
    def get_image_tag(self, specs='height-500'):
        '''
        Returns an html <image> tag for the related image.
        See Wagtail get_rendition_or_not_found() for valid specs.
        '''
        ret = ''

        if self.image:
            rendition = get_rendition_or_not_found(self.image, specs)
            # Remove height and width to keep things responsive.
            # they will be set by CSS.
            ret = re.sub(r'(?i)(height|width)=".*?"', '', rendition.img_tag())

        return ret
コード例 #19
0
 def render(self, context):
     image = self.image_expr.resolve(context)
     # set 'self.native_format' for 'filter()' to pick up
     self.extract_native_format(image)
     # generate the <img> tag using 'filter' for the rendition
     img_tag = super().render(context)
     if not img_tag:
         return img_tag
     # now wrap in a <picture> tag with the webp version as a source
     webp_rendition = get_rendition_or_not_found(image, self.webp_filter)
     return format_html(
         '<picture><source srcset="{}" type="image/webp">{}</picture>',
         webp_rendition.url,
         mark_safe(img_tag),
     )
コード例 #20
0
ファイル: streamfield.py プロジェクト: CRJI/theblacksea.eu
    def get_context(self, value, parent_context=None):
        context = super().get_context(value, parent_context=parent_context)

        if value:
            width = 1110
            img0 = value[0]['image']
            ratio = img0.width / img0.height
            filter = Filter(spec=f'fill-{width}x{int(width/ratio)}')

            context['images'] = [
                (item, get_rendition_or_not_found(item['image'], filter))
                for item in value
            ]
            context['carousel_id'] = f'carousel-{img0.pk}'

        return context
コード例 #21
0
ファイル: rich_text.py プロジェクト: melody40/monorepo
    def create_entity(self, name, attrs, state, contentstate):
        Image = get_image_model()
        try:
            image = Image.objects.get(id=attrs['id'])
            image_format = get_image_format(attrs['format'])
            rendition = get_rendition_or_not_found(image, image_format.filter_spec)
            src = rendition.url
        except Image.DoesNotExist:
            src = ''

        return Entity('IMAGE', 'IMMUTABLE', {
            'id': attrs['id'],
            'src': src,
            'alt': attrs.get('alt'),
            'format': attrs['format']
        })
コード例 #22
0
def image_link_handler(attrs):
    """Handle a link of the form <embed embedtype="image" id="123">"""
    # Default implementation from wagtail.images.rich_text.image_embedtype_handler
    Image = get_image_model()
    try:
        image = Image.objects.get(id=attrs['id'])
    except Image.DoesNotExist:
        return "<img>"

    image_format = get_image_format(attrs['format'])

    # form extra src attribute
    base_url = Site.objects.first().root_url
    rendition = get_rendition_or_not_found(image, image_format.filter_spec)
    extra_attributes = {'src': '{}{}'.format(base_url, rendition.url)}

    # From default implementation, except extra src attribute
    return image_format.image_to_html(image, attrs.get('alt', ''),
                                      extra_attributes)
コード例 #23
0
    def get_value_data(self, value):
        if value is None:
            return None
        elif isinstance(value, self.image_model):
            image = value
        else:  # assume image ID
            image = self.image_model.objects.get(pk=value)

        preview_image = get_rendition_or_not_found(image, "max-165x165")

        return {
            "id": image.pk,
            "title": image.title,
            "preview": {
                "url": preview_image.url,
                "width": preview_image.width,
                "height": preview_image.height,
            },
            "edit_url": reverse("wagtailimages:edit", args=[image.id]),
        }
コード例 #24
0
    def get_value_data(self, value):
        if value is None:
            return None
        elif isinstance(value, self.image_model):
            image = value
        else:  # assume image ID
            image = self.image_model.objects.get(pk=value)

        preview_image = get_rendition_or_not_found(image, 'max-165x165')

        return {
            'id': image.pk,
            'title': image.title,
            'preview': {
                'url': preview_image.url,
                'width': preview_image.width,
                'height': preview_image.height,
            },
            'edit_url': reverse('wagtailimages:edit', args=[image.id]),
        }
コード例 #25
0
    def create_entity(self, name, attrs, state, contentstate):
        Image = get_image_model()
        try:
            image = Image.objects.get(id=attrs["id"])
            image_format = get_image_format(attrs["format"])
            rendition = get_rendition_or_not_found(image,
                                                   image_format.filter_spec)
            src = rendition.url
        except Image.DoesNotExist:
            src = ""

        return Entity(
            "IMAGE",
            "IMMUTABLE",
            {
                "id": attrs["id"],
                "src": src,
                "alt": attrs.get("alt"),
                "format": attrs["format"],
            },
        )
コード例 #26
0
    def render(self, context):
        image = self.image_expr.resolve(context)
        if not image:
            return ""

        rendition = get_rendition_or_not_found(image, self.filter)
        rendition.lazy_url = _get_placeholder_url(rendition)

        lazy_attr = str(self.attrs.pop("lazy_attr", '"data-src"'))[1:-1]

        attrs = {"src": rendition.lazy_url, lazy_attr: rendition.url}
        for key in self.attrs:
            attrs[key] = self.attrs[key].resolve(context)

        if self.output_var_name:
            lazy_attrs = dict(rendition.attrs_dict, **attrs)
            rendition.lazy_attrs = flatatt(lazy_attrs)
            context[self.output_var_name] = rendition
            return ""

        return rendition.img_tag(attrs)
コード例 #27
0
    def render(self, context):
        try:
            image = self.image_expr.resolve(context)
        except template.VariableDoesNotExist:
            return ''

        if not image:
            return ''

        rendition = get_rendition_or_not_found(image, self.filter)

        if self.output_var_name:
            # return the rendition object in the given variable
            context[self.output_var_name] = rendition
            return ''
        else:
            # render the rendition's image tag now
            resolved_attrs = {}
            for key in self.attrs:
                resolved_attrs[key] = self.attrs[key].resolve(context)
            return rendition.img_tag(resolved_attrs)
コード例 #28
0
ファイル: ImageFormat.py プロジェクト: bennof/edo365_v2
    def image_to_html(self, image, alt_text, extra_attributes=None):

        #default_html = super().image_to_html(image, alt_text, extra_attributes)
        if extra_attributes is None:
            extra_attributes = {}
        rendition = get_rendition_or_not_found(image, self.filter_spec)

        extra_attributes['alt'] = escape(alt_text)
        if self.classnames:
            extra_attributes['class'] = "%s" % escape(self.classnames)

        #default_html =  rendition.img_tag(extra_attributes)
        attrs = OrderedDict([
            ('src', rendition.url),
            #('width', self.width),
            #('height', self.height),
            ('alt', rendition.alt),
        ])
        attrs.update(extra_attributes)
        #return mark_safe(''.format())

        return format_html('<img {}>', flatatt(attrs), alt_text)
コード例 #29
0
 def get_rendition_url(self, image):
     width = self.context.get('width', 800)
     filter_spec = 'width-{}'.format(width)
     return get_rendition_or_not_found(image, Filter(spec=filter_spec)).url