Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for HTMX and Unpoly tags #201

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,8 @@ print(test)
<div data-employee="101011"></div>
```

Similarly, use `aria_*` for [Aria](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA), `hx_*` for custom [HTMX](https://htmx.org/), and `up_*` for custom [Unpoly](https://unpoly.com/) attributes

You can also modify the attributes of tags through a dictionary-like interface:

```python
Expand All @@ -160,6 +162,18 @@ print(header)
<div id="header"></div>
```

If attributes don't have values, you can explicitly mark them as having no value:

```python
from dominate.util import novalue

link = a(href="https://url.com", up_instant=novalue(), "Click Here)
print(link)
```
```html
<a href="https://url.com" up-instant>Click Here</a>
```

Complex Structures
------------------

Expand Down
14 changes: 11 additions & 3 deletions dominate/dom_tag.py
Original file line number Diff line number Diff line change
Expand Up @@ -372,8 +372,11 @@ def _render(self, sb, indent_level, indent_str, pretty, xhtml):
for attribute, value in sorted(self.attributes.items()):
if value in (False, None):
continue
val = unicode(value) if isinstance(value, util.text) and not value.escape else util.escape(unicode(value), True)
sb.append(' %s="%s"' % (attribute, val))
elif isinstance(value, util.novalue):
sb.append(' %s' % (attribute, ))
else:
val = unicode(value) if isinstance(value, util.text) and not value.escape else util.escape(unicode(value), True)
sb.append(' %s="%s"' % (attribute, val))

sb.append(' />' if self.is_single and xhtml else '>')

Expand Down Expand Up @@ -440,12 +443,17 @@ def clean_attribute(attribute):
'phor': 'for',
}.get(attribute, attribute)

# A list of attribute prefixes which mean that underscores should be converted to dashes
# This allows attributes like data_username or hx_post become data-username and hx-post
# hx_ prefix is for HTMX and up_ prefix is for Unpoly
SPECIAL_PREFIX_LIST = ('data_', 'aria_', 'up_', 'hx_')

# Workaround for Python's reserved words
if attribute[0] == '_':
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 SPECIAL_PREFIX_LIST])
if attribute in set(['http_equiv']) or special_prefix:
attribute = attribute.replace('_', '-').lower()

Expand Down
8 changes: 8 additions & 0 deletions dominate/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -184,3 +184,11 @@ def raw(s):
Inserts a raw string into the DOM. Unsafe. Alias for text(x, escape=False)
'''
return text(s, escape=False)

class novalue:
'''
A class to mark tag attributes as having no value.
important for libraries like Unpoly which require attribute values like
<a href="https://url.com" up-instant>Link</a>
'''
pass