Knio / dominate

Dominate is a Python library for creating and manipulating HTML documents using an elegant DOM API. It allows you to write HTML pages in pure Python very concisely, which eliminate the need to learn another template language, and to take advantage of the more powerful features of Python.
GNU Lesser General Public License v3.0
1.72k stars 108 forks source link

Underscore as an attribute is not rendered - used with htmx/hyperscript #193

Open pablo8itall opened 7 months ago

pablo8itall commented 7 months ago

When trying to generate html that uses hyperscript in my htmx webapp Dominate does not allow me to use _ as an attribute for a tag.

>>>tag = div(_='on click do something')
>>>tag.render()  
'<div ="on click do something"></div>'

I assume its something to do with Python as typically we'd ignore named variables when they are underscores.

>>> def test(_):
...     print(_)
... 
>>> test(1)
1
>>> 

Although this just seems to be a convention and not a hard coded language feature.

pablo8itall commented 7 months ago

Works if you do this:

>>> tag['_']='on fix do fixin'
>>> tag.render()
'<div ="on click do something" _="on fix do fixin"></div>'
Knio commented 7 months ago

This is actually from here, as a way to allow leading underscores to attribute names that would otherwise collide with Python reserved words.

pablo8itall commented 7 months ago

Ah I see, should be straightforward to change it to leave it if it is just the "_" and remove if it is "_something"?

I'm switching to Dominate from Jinja templates, and its a good deal faster and cleaner for me.

pablo8itall commented 7 months ago

Regarding how Dominate handles the hyphen and underscore generally. If I add an attribute with an underscore, when is it converted to a hyphen. I see that data_something will convert to data-something at render.

This is important for htmx as it uses hx- for all its attributes.

EDIT: Found it here:

   # Workaround for dash
    special_prefix = any([attribute.startswith(x) for x in ('data_', 'aria_')])
    if attribute in set(['http_equiv']) or special_prefix:
      attribute = attribute.replace('_', '-').lower()

I could just fork Dominate and add 'hx_' in here as well I suppose.

Knio commented 7 months ago

yes, hx_ could be added there. Or that logic could be revisited (how many html attrs use underscores?)

angelsen commented 7 months ago

Adding hx_ would handle htmx tags as they are hx-sometag.

# Workaround for dash
special_prefix = any([attribute.startswith(x) for x in ('data_', 'aria_', 'hx_')])
if attribute in set(['http_equiv']) or special_prefix:
  attribute = attribute.replace('_', '-').lower()

handle:

  input(
    placeholder="Begin typing to search",
    name="search",
    hx_post=url("search", 1),
    hx_trigger="load, input changed delay:500ms, search",
    hx_target=f"#{id}",
    hx_headers=csrf_header(request),
),
hasansezertasan commented 7 months ago

I'm switching to Dominate from Jinja templates, and its a good deal faster and cleaner for me.

How is that going, if it's an open source project, please live a link.

juanjo-nan commented 6 months ago

Hi, I encountered similar issue with htmx tags, it may be interesting to add the tags that begin with hx_ to the special prefixes.

nikalexis commented 2 months ago

Have a look also in this pull request for HTMX (and some more) helpers / directives.

https://github.com/Knio/dominate/pull/203