From bda6a37539a0c957a820cd3f1431eef6ad4d1085 Mon Sep 17 00:00:00 2001 From: Johannes Raggam Date: Thu, 14 Mar 2024 00:56:35 +0100 Subject: [PATCH] Add support for accept attribute on file input. If the widget's field - if there is one - has `allowedContentTypes` set (the `NamedImage` field has `image/*` set by default) the allowed content types are rendered as `accept` attribute on the file input. This already restricts the allowed file types before uploading while still being checked on the server side too. Fixes: https://github.com/plone/plone.formwidget.namedfile/issues/66 Depeds on: https://github.com/plone/plone.namedfile/pull/158 --- news/67.feature | 8 +++ plone/formwidget/namedfile/file_input.pt | 1 + plone/formwidget/namedfile/image_input.pt | 1 + plone/formwidget/namedfile/widget.py | 6 +++ plone/formwidget/namedfile/widget.rst | 64 ++++++++++++++++++++++- 5 files changed, 78 insertions(+), 2 deletions(-) create mode 100644 news/67.feature diff --git a/news/67.feature b/news/67.feature new file mode 100644 index 0000000..f37367e --- /dev/null +++ b/news/67.feature @@ -0,0 +1,8 @@ +Add support for accept attribute on file input. + +If the widget's field - if there is one - has `allowedContentTypes` set (the `NamedImage` field has `image/*` set by default) the allowed content types are rendered as `accept` attribute on the file input. + +This already restricts the allowed file types before uploading while still being checked on the server side too. + +Fixes: https://github.com/plone/plone.formwidget.namedfile/issues/66 +Depeds on: https://github.com/plone/plone.namedfile/pull/158 diff --git a/plone/formwidget/namedfile/file_input.pt b/plone/formwidget/namedfile/file_input.pt index fb3bc0f..8def069 100644 --- a/plone/formwidget/namedfile/file_input.pt +++ b/plone/formwidget/namedfile/file_input.pt @@ -131,6 +131,7 @@ tal:omit-tag="not:allow_nochange" > >> image_widget.extract() -The rendering is unchanged: +The rendering is unchanged:: >>> print(file_widget.render()) @@ -284,7 +284,7 @@ At first, there is no value, so the behaviour is much like before:: >>> image_widget.update() >>> print(image_widget.render()) - + However, if we now set a value, we will have the option of keeping it, @@ -388,6 +388,66 @@ stored in the field:: True +Rendering field widgets with constraints on allowed content types +----------------------------------------------------------------- + +The NamedImage already has a constraint on `image/*` mime types for files and +this is also rendered for the input element. See above. +You can also customize the allowed content types, like shown here:: + + >>> class IContentConstrained(Interface): + ... file_field = field.NamedFile( + ... title=u"File", + ... allowedContentTypes=("audio/mp3", "audio/flac") + ... ) + ... image_field = field.NamedImage( + ... title=u"Image", + ... allowedContentTypes=("image/webp", "image/png") + ... ) + + >>> @implementer(IContentConstrained, IImageScaleTraversable, IAttributeAnnotatable) + ... class ContentConstrained(object): + ... def __init__(self, file, image): + ... self.file_field = file + ... self.image_field = image + ... self._p_mtime = DateTime() + ... self.path = '/content_constrained' + ... + ... def absolute_url(self): + ... return root_url + self.path + ... + ... def Title(self): + ... return 'A content item' + + >>> content_constrained = ContentConstrained(None, None) + + >>> file_widget_constrained = NamedFileFieldWidget(IContentConstrained['file_field'], make_request()) + >>> image_widget_constrained = NamedImageFieldWidget(IContentConstrained['image_field'], make_request()) + + >>> file_widget_constrained.context = content_constrained + >>> image_widget_constrained.context = content_constrained + + >>> file_widget_constrained.id = 'widget.id.file' + >>> file_widget_constrained.name = 'widget.name.file' + + >>> image_widget_constrained.id = 'widget.id.image' + >>> image_widget_constrained.name = 'widget.name.image' + +At first, there is no value, so the behaviour is much like before:: + + >>> file_widget_constrained.update() + >>> print(file_widget_constrained.render()) + + + + + >>> image_widget_constrained.update() + >>> print(image_widget_constrained.render()) + + + + + Download view -------------