diff --git a/README.md b/README.md index 78c5eb2..4f45182 100644 --- a/README.md +++ b/README.md @@ -129,6 +129,7 @@ For attributes `class` and `for` which conflict with Python's [reserved keywords |cls | fr | |className|htmlFor| |class_name|html_for| +|klass|phor| ```python @@ -139,27 +140,54 @@ print(test) ``` -Use `data_*` for [custom HTML5 data attributes](http://www.w3.org/html/wg/drafts/html/master/dom.html#embedding-custom-non-visible-data-with-the-data-*-attributes "HTML5 Data Attributes"). +You can also modify the attributes of tags through a dictionary-like interface: ```python -test = div(data_employee='101011') -print(test) +header = div() +header['id'] = 'header' +print(header) +``` +```html +
+``` + +### Dashed Attributes + +Dashed attributes for `data_` and `aria_` are supported by default: + +```python +from dominate.tags import div + +print( + div(data_employee='101011'), + div(aria_role='button'), +) ``` ```html + ``` -You can also modify the attributes of tags through a dictionary-like interface: +If you using a 3rd party library like HTMX, Unpoly, or AlpineJS that uses dashed attrs, you will +need to configure dominate accordingly: ```python -header = div() -header['id'] = 'header' -print(header) +import dominate +from dominate.tags import div + +dominate.dashed_attrs_add('hx_', 'x_') +print( + div(hx_target='/foo'), + div(x_show='open'), +) ``` + ```html - + + ``` + Complex Structures ------------------ diff --git a/dominate/__init__.py b/dominate/__init__.py index becc617..9803bc6 100644 --- a/dominate/__init__.py +++ b/dominate/__init__.py @@ -1,2 +1,3 @@ from .version import __version__, version from .document import document +from .dom_tag import DASHED_ATTRS, dashed_attrs_add, dashed_attrs_reset diff --git a/dominate/community/htmx.py b/dominate/community/htmx.py deleted file mode 100644 index 79c70b1..0000000 --- a/dominate/community/htmx.py +++ /dev/null @@ -1,12 +0,0 @@ - -from .. import tags - -class HtmxTag: - @classmethod - def clean_attribute(cls, attribute): - attribute = super().clean_attribute(attribute) - if attribute.startswith('hx_'): - attribute = attribute.replace('_', '-') - return attribute - -tags.html_tag.__bases__ = (HtmxTag,) + tags.html_tag.__bases__ diff --git a/dominate/dom_tag.py b/dominate/dom_tag.py index 15228ab..cfe2c3c 100644 --- a/dominate/dom_tag.py +++ b/dominate/dom_tag.py @@ -45,6 +45,18 @@ except ImportError: greenlet = None +# These prefixes will be converted to dashed html attributes. +DASHED_ATTRS = ['data_', 'aria_'] +_DASHED_ATTRS_ORIG = DASHED_ATTRS[:] + +def dashed_attrs_add(*args: tuple[str]): + DASHED_ATTRS.extend(args) + + +def dashed_attrs_reset(): + DASHED_ATTRS.clear() + DASHED_ATTRS.extend(_DASHED_ATTRS_ORIG) + # We want dominate to work in async contexts - however, the problem is # when we bind a tag using "with", we set what is essentially a global variable. # If we are processing multiple documents at the same time, one context @@ -447,7 +459,7 @@ def clean_attribute(attribute): attribute = attribute[1:] # Workaround for dash - special_prefix = any([attribute.startswith(x) for x in ('data_', 'aria_')]) + special_prefix = any([attribute.startswith(x) for x in DASHED_ATTRS]) if attribute in set(['http_equiv']) or special_prefix: attribute = attribute.replace('_', '-').lower() diff --git a/tests/community/test_htmx.py b/tests/community/test_htmx.py deleted file mode 100644 index bd0ccd2..0000000 --- a/tests/community/test_htmx.py +++ /dev/null @@ -1,7 +0,0 @@ - -from dominate import tags -import dominate.community.htmx - -def test_hx(): - d = tags.div(hx_foo=1) - assert d.render() == '' diff --git a/tests/test_html.py b/tests/test_html.py index 610c0c2..0c6b615 100644 --- a/tests/test_html.py +++ b/tests/test_html.py @@ -2,7 +2,7 @@ from dominate.tags import * from dominate.util import raw - +import dominate def test_arguments(): assert html(body(h1('Hello, pyy!'))).render() == \ @@ -366,3 +366,15 @@ class Card(div): assert Card().render() == '' assert Card(tagname='div').render() == '' + + +def test_custom_dashed_attrs(): + assert div(hx_post='/clicked').render() == '' + + dominate.dashed_attrs_add('hx_', 'un_') + assert div(hx_post='/clicked').render() == '' + assert div(un_post='/clicked').render() == '' + + # Ensure the reset works + dominate.dashed_attrs_reset() + assert div(hx_post='/clicked').render() == ''