pelme / htpy

Generate HTML in Python
http://htpy.dev
MIT License
261 stars 11 forks source link

'vueish' html attributes with html2htpy #28

Closed OleJoik closed 5 months ago

OleJoik commented 5 months ago

'vueish' html attributes with html2htpy

html2htpy is not currently able to handle conversion of key word attributes prefixed with special characters such as @click or :show, which I stumped into while converting some templates containing attributes from alpine.js.

I added a test and a bit to the transformation algorithm to support converting these attributes to htpy's dictionary attr syntax.

def test_convert_vueish_attrs() -> None:
    input = """
      <button id="btn-id" @click="doSomething" type="submit">Submit</button>
      <img id="img-id" :src="imageSrc" />
    """

    actual = html2htpy(input, import_mode="no") 
    assert actual == (
        "["
        'button("#btn-id",{"@click":"doSomething"},type="submit")["Submit"],'
        'img("#img-id",{":src":"imageSrc"})'
        "]"
    )
OleJoik commented 5 months ago

Not sure though if you want to support all sorts of strange non-standard attributes that might show up. I guess these are fairly common though, so I thought why not.

pelme commented 5 months ago

I think https://docs.python.org/3/library/stdtypes.html#str.isidentifier can be used to decide whether or not an attribute name should be a direct argument or be put into the dict:

>>> '@click'.isidentifier()
False
>>> ':src'.isidentifier()
False
>>> 'foo'.isidentifier()
True
>>> 'type'.isidentifier()
True

Also, keyword.iskeyword(x) can be used to add a trailing underscore consistently instead of hard coding special cases for for_ and class_.

pelme commented 5 months ago

I added checks for keyword/identifiers+dict attributes so it is hopefully robust with all kinds of attributes now. Published htpy 24.6.1 to pypi with this fix :)

 $ echo '<img id="img-id" :src="imageSrc" @click.prevent="foo=bar">' | html2htpy
from htpy import img

img("#img-id", {":src": "imageSrc", "@click.prevent": "foo=bar"})
OleJoik commented 5 months ago

Apologies for leaving that stale, I became quite busy at work. Was planning to come back to it, but here we are!

pelme commented 5 months ago

No worries! :)