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

htmx integration #69

Open
CRY-D opened this issue Feb 18, 2024 · 4 comments
Open

htmx integration #69

CRY-D opened this issue Feb 18, 2024 · 4 comments

Comments

@CRY-D
Copy link

CRY-D commented Feb 18, 2024

Hey👋 I'm exploring ways to integrate htmx with domonic. Although the **{"":""} method works just fine, but it tends to result in spaghetti-like code just like React or Vue 😝

Screenshot_20240218_184043

To avoid this, I've worked around. However, the challenge lies in creating custom elements inherited from base elements for inputs, links, buttons, forms, and perhaps divs each one for each one .
here is an example of my simple cutom button:

from domonic import button

class Button(button):
    def __init__(self, text, accent, icon):
        super().__init__(text)
        self.setAttribute("accent", accent)

    def change_accent(self, accent):
        self.setAttribute("accent", accent)

    def htmx_get(self, url: str):
        self.setAttribute("hx-get", url)

    def htmx_post(self, url: str):
        self.setAttribute("hx-post", url)

    def htmx_trigger(self, event: str):
        self.setAttribute("hx-trigger", event)

    def htmx_target(self, target: str):
        self.setAttribute("hx-target", target)

    def htmx_swap(self, swap: str):
        self.setAttribute("hx-swap", swap)

the question, Is there a way to achieve this without having to inherit from each element and create a custom one?
It would be fantastic if domonic had a built-in htmx functions for buttons, inputs, forms, hrefs, or even divs, similar to the div.html() For example:

htmx_button = button('some action').htmx_post('/post').htmx_target('.post')
# or like so
htmx_button = button('some action')
htmx_button.set_hxpost("/post")
htmx_button.set_hxtarget(".post")

You get the point.

@byteface
Copy link
Owner

byteface commented Feb 18, 2024

Hi @CRY-D ... sorry its been ages. I recall doing some kind of undocumented htmx features a long time ago.

https://github.com/byteface/domonic/blob/master/domonic/dom.py#L212

You just had to set:

DOMConfig.HTMX_ENABLED = True

But I'm not sure if htmx has changed since. It might need updating if so.

I guess if it is obsolete, for now as a work around you could monkey patch def __attributes__(self): on Node and have it check for attributes? literally copy out the attributes function and set it with your own method formatted exactly how you'd like it.

@CRY-D
Copy link
Author

CRY-D commented Feb 18, 2024

Thank you, and It's quite interesting, now I have an idea that doesn't require altering the source code of the library. What if I create a class that generates dynamic methods from the attributes provided by HTMX and directly applies them to the corresponding DOMONIC elements? Just like that. What do you think? I know it ain't much, but it's more friendly for my eyes 😅

from domonic import a  
from static_strings import HTMX_ATTR
class HtmxElement:
    def __init__(self, element):
        self.element = element
        for attr in HTMX_ATTR:
            htmx_attr = f"hx-{attr.replace('_', '-')}" # just to handle attrs like push_url, history_elt...
            setattr(self, attr, lambda value, htmx_attr=htmx_attr: self.element.setAttribute(htmx_attr, value))


element = a("Post", _href="/post")
htmx_element = HtmxElement(element)
htmx_element.push_url("true")
htmx_element.target("#result")
htmx_element.swap("outerHTML swap:200ms settle:200ms")
print(element)
# output: <a href="/post" hx-push-url="true" hx-target="#result" hx-swap="outerHTML swap:200ms settle:200ms">Post</a>

static_strings.py

HTMX_ATTR = [
    "boost",
    "confirm",
    "delete",
    "disable",
    "disinherit",
    "encoding",
    "ext",
    "get",
    "headers",
    "history_elt",
    "include",
    "indicator",
    "params",
    "patch",
    "post",
    "preserve",
    "prompt",
    "push_url",
    "put",
    "request",
    "select",
    "sse",
    "swap",
    "swap_oob",
    "sync",
    "target",
    "trigger",
    "vals",
    "vars",
    "ws",
]

@byteface
Copy link
Owner

Oh @CRY-D I see.. actual method names. push_url etc. Yes that does look like a good idea.

@CRY-D
Copy link
Author

CRY-D commented Feb 23, 2024

Looks promising! By the way, I'm currently developing a set of useful components, and domonic seems very promising.
Thank you again.

Screenshot_20240223_230317

Screenshot_20240223_230431

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants