Repository: wtforms/wtforms
Pull request #389 (2018-05-10 21:14:44)

Modified html_params to treat aria attributes the same as data attributes
Fixing #239, when specifying field attributes in a template if the attribute begins with `aria_`, then the generated attribute shall begin with `aria-`, just like how `data` attributes are handled.

For example
```python
{{ form.username(aria_describedby='usernameHelp') }}
```
will now make
```html
<input aria-describedby="usernameHelp" id="username" name="username" value="" type="text">
```

I also corrected the documentation for `html_params`, clarifying how when using `data_` or `aria_` attributes every underscore gets replaced with a hyphen - not just the first one.



Patch:
diff --git a/CHANGES.rst b/CHANGES.rst
index b227eff..1310d0b 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -9,11 +9,16 @@ Version 3.0
 
 Unreleased
 
+-   ``aria_`` args are rendered the same way as ``data_`` args, by
+    converting underscores to hyphens. ``aria_describedby="name-help"``
+    becomes ``aria-describedby="name-help"``. (`#239`_, `#389`_)
 -   HTML5 :class:`~fields.html5.IntegerField` and
     :class:`~fields.html5.RangeInput` don't render the ``step="1"``
     attribute by default. (`#343`_)
 
+.. _#239: https://github.com/wtforms/wtforms/issues/239
 .. _#343: https://github.com/wtforms/wtforms/pull/343
+.. _#389: https://github.com/wtforms/wtforms/pull/389
 
 
 Version 2.2
diff --git a/wtforms/widgets/core.py b/wtforms/widgets/core.py
index aabfefd..9b87a4f 100644
--- a/wtforms/widgets/core.py
+++ b/wtforms/widgets/core.py
@@ -41,11 +41,12 @@ def html_params(**kwargs):
     frequent use of the normally reserved keywords `class` and `for`, suffixing
     these with an underscore will allow them to be used.
 
-    In order to facilitate the use of ``data-`` attributes, the first underscore
-    behind the ``data``-element is replaced with a hyphen.
+    In order to facilitate the use of ``data-`` and ``aria-`` attributes, if the
+    name of the attribute begins with ``data_`` or ``aria_``, then every
+    underscore will be replaced with a hyphen in the generated attribute.
 
-    >>> html_params(data_any_attribute='something')
-    'data-any_attribute="something"'
+    >>> html_params(data_attr='user.name', aria_labeledby='name')
+    'data-attr="user.name" aria-labeledby="name"'
 
     In addition, the values ``True`` and ``False`` are special:
       * ``attr=True`` generates the HTML compact output of a boolean attribute,
@@ -56,12 +57,20 @@ def html_params(**kwargs):
     'class="text" id="f" name="text1"'
     >>> html_params(checked=True, readonly=False, name="text1", abc="hello")
     'abc="hello" checked name="text1"'
+
+    .. versionchanged:: 3.0
+        ``aria_`` args convert underscores to hyphens like ``data_``
+        args.
+
+    .. versionchanged:: 2.2
+        ``data_`` args convert all underscores to hyphens, instead of
+        only the first one.
     """
     params = []
     for k, v in sorted(iteritems(kwargs)):
         if k in ('class_', 'class__', 'for_'):
             k = k[:-1]
-        elif k.startswith('data_'):
+        elif k.startswith('data_') or k.startswith('aria_'):
             k = k.replace('_', '-')
         if v is True:
             params.append(k)


Test patch:
diff --git a/tests/test_widgets.py b/tests/test_widgets.py
index 8b11a68..3e26c00 100644
--- a/tests/test_widgets.py
+++ b/tests/test_widgets.py
@@ -41,6 +41,10 @@ class HTMLParamsTest(TestCase):
         self.assertEqual(html_params(data_foo=22), 'data-foo="22"')
         self.assertEqual(html_params(data_foo_bar=1), 'data-foo-bar="1"')
 
+    def test_aria_prefix(self):
+        self.assertEqual(html_params(aria_foo='bar'), 'aria-foo="bar"')
+        self.assertEqual(html_params(aria_foo_bar='foobar'), 'aria-foo-bar="foobar"')
+
     def test_quoting(self):
         self.assertEqual(html_params(foo='hi&bye"quot'), 'foo="hi&amp;bye&quot;quot"')