Wagtail getting/generating image urls from JSON api or directly
Asked Answered
G

1

5

I've been using Wagtail as a headless CMS to use with a frontend application, However I noticed some limitations regarding images. Normally in your jinja template you would generate the correct image size you need and all is fine, However I don't have access to these helpers in my frontend code. I have been trying several things. for example, to solve this for simple page models and their fields I could render a custom api field like so:

api_fields = [
    # Adds information about the source image (eg, title) into the API
    APIField('feed_image'),

    # Adds a URL to a rendered thumbnail of the image to the API
    APIField('feed_image_thumbnail', serializer=ImageRenditionField('fill-100x100', source='feed_image')),
    ...
]

However this will not work for streamfield since these will only return the image id. So I figured I would use the Wagtail image API, however this does not allow me to access the direct URL either.

I find some google group answers refering to this documentation: http://docs.wagtail.io/en/v1.9/advanced_topics/images/image_serve_view.html

However this page does not seem to exists in the latest version of the documentation and doesn't seem to allow me to generate images from a url on the frontend.

Is there a way to perhaps create a url that allows me to fetch an image based on its ID?

for example: somehost:8000/images/1?width=200&height=200

Or perhaps there is some other solution I am overlooking.

I love wagtail but not having easy access to image urls really limits its API usage, I hope there is a good solution for this.

Thanks

EDIT: I managed to find this in the docs: http://docs.wagtail.io/en/v1.11.1/advanced_topics/images/image_serve_view.html

However they state:

The view takes an image id, filter spec and security signature in the URL. If these parameters are valid, it serves an image file matching that criteria.

But they don't give a clear example of what a request like that would look like or how I would generate that security signature.

Gumm answered 17/8, 2017 at 10:25 Comment(1)
Just chiming in that as of April 2018, v2.0.1, the documentation on "Dynamic image serve view" is still just as lacking. : (Arthur
K
9

One (slightly hacky) way to get an image rendition as part of the StreamField data structure is to override ImageChooserBlock's get_api_representation method:

from wagtail.wagtailimages.blocks import ImageChooserBlock as DefaultImageChooserBlock

class ImageChooserBlock(DefaultImageChooserBlock):
    def get_api_representation(self, value, context=None):
        if value:
            return {
                'id': value.id,
                'title': value.title,
                'large': value.get_rendition('width-1000').attrs_dict,
                'thumbnail': value.get_rendition('fill-120x120').attrs_dict,
            }

Using this version of ImageChooserBlock in your StreamField definition will then give you 'large' and 'thumbnail' renditions as part of the API response, rather than just the image ID.

Kaciekacy answered 17/8, 2017 at 13:28 Comment(3)
This will work perfectly for my use case! thanks :) I wish this was something more documented or easier to configure, can't imagine others not having a similar problem with the APIGumm
For consistency with the v2 API I suggest the following: ImageRenditionField('width-1000').to_representation(value) this produces a dict with keys: 'url', 'width', 'height', rather than: 'src', 'width', 'height', 'alt'. ImageRenditionField can be imported as such: from wagtail.images.api.fields import ImageRenditionFieldMicrocircuit
Perfect! Also works for images in a StreamField.Farrier

© 2022 - 2024 — McMap. All rights reserved.