Search code examples
plonearchetypesdexterity

Preventing users to upload BMP, TIFF etc. images to ImageField in Plone


The users do it because they can.

However, image auto-resize etc. breaks down.

This make me a sad boy.

How to limit image uploads to GIF, PNG and JPEG sitewide?

  • For Archetypes

  • For Dexterity


Solution

  • i ran into similar problems these days and worked around them like that:

    • add a custom widget that adds an accept attribute to the file input
    • set field.swallowResizeExceptions = True so users at least don't get a site-error when uploading an unsopported image type
    • state mimetypes that work in description

    The field definition looks like this:

    atapi.ImageField('image1',
        swallowResizeExceptions = True,
        widget = atapi.ImageWidget(
            label = _(u"Image 1"),
            description = _(u"Image used in listings. (JPEG, PNG and GIF are supported)"),
            show_content_type = False,
            accept = 'image/*',
            macro = 'mywidgets/myimage',
            ),
        ),
    

    note that accept="image/jpeg,image/gif"was ignored by firefox11 although it sould be supported according to http://www.w3schools.com/tags/att_input_accept.asp

    mywidgets/myimage is a customized version of archetypes/skins/widgets/image.pt that uses a customized version of archetypes/skins/widgets/file.pt

    <metal:define define-macro="edit">
    ...
       <metal metal:use-macro="here/mywidgets/myfile/macros/file_upload"/>
    ...
    

    and mywidgets/myfile.pt simply defines this macro:

    <metal:define define-macro="file_upload"
           tal:define="unit accessor;
                       size unit/get_size | python:unit and len(unit) or 0;">
        <input type="file"
               size="30"
               tal:attributes="name string:${fieldName}_file;
                               id string:${fieldName}_file;
                               accept widget/accept|nothing;" />
        <script type="text/javascript"
            tal:define="isDisabled python:test(accessor() and size!=0, 'true', 'false')"
                tal:content="string:document.getElementById('${fieldName}_file').disabled=$isDisabled;">
        </script>
    </metal:define>