diff --git a/news/67.feature b/news/67.feature
new file mode 100644
index 0000000..ecbdb3a
--- /dev/null
+++ b/news/67.feature
@@ -0,0 +1,12 @@
+Add support for the "accept" attribute on file inputs.
+
+If the widget's field - if there is one - has the "accept" attribute set (the
+`NamedImage` field has `image/*` set by default) then this is rendered as an
+`accept` attribute on the file input.
+
+This would restrict the allowed file types before uploading while still being
+checked on the server side.
+
+Fixes: https://github.com/plone/plone.formwidget.namedfile/issues/66
+Depends on: https://github.com/plone/plone.namedfile/pull/158
+[thet]
diff --git a/plone/formwidget/namedfile/file_input.pt b/plone/formwidget/namedfile/file_input.pt
index fb3bc0f..6bfb891 100644
--- a/plone/formwidget/namedfile/file_input.pt
+++ b/plone/formwidget/namedfile/file_input.pt
@@ -130,7 +130,8 @@
-
- >> 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,67 @@ stored in the field::
True
+Rendering field widgets with constraints on allowed media 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 media types with the `accept` attribute,
+like shown here::
+
+ >>> class IContentConstrained(Interface):
+ ... file_field = field.NamedFile(
+ ... title=u"File",
+ ... accept=("audio/mp3", "audio/flac", ".wav")
+ ... )
+ ... image_field = field.NamedImage(
+ ... title=u"Image",
+ ... accept=("image/webp", "image/png", ".jpg")
+ ... )
+
+ >>> @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
-------------