Package: htmxido
What is htmxido?HTMXido is declerative HTMX generation library for Python.Installpip install htmxidoWhy?Since the invention of React SSR (like Next.js), there has been newfound enthusiasm for writing server-side views. Although this method isn't new (consider PHP, the grandfather of all), I was searching for a solution close to writing inline code capable of generating HTML and processing HTMX attributes on those elements.After exploring various libraries and finding them unsatisfactory, I ended up creating something for myself. It later dawned on me that it could benefit more people.What does it look like?fromhtmxidoimportdomxasxexample_dom=x.div(id="root",class_="bg-white dark:bg-slate-800 rounded-lg px-6 py-8 ring-1 ring-slate-900/5 shadow-xl")(x.h1(hxIndicator="#spinner")('Hello World'),x.p('You can have nested elements like this:'),x.ul(x.li(f"Item{i}")foriinrange(1,3)),x.div('Not only that but also you can have HTMX attributes'),x.button(hxTarget="rubber-band")('Click me')x.img(id="spinner",src="loading.gif",class_="spinner-animation"))print(str(example_dom))NOTE: Any keyword attributes should be suffixed with_, and they will be removed as per showin in following output.<divid="root"class="bg-white dark:bg-slate-800 rounded-lg px-6 py-8 ring-1 ring-slate-900/5 shadow-xl"><h1hx-indicator="#spinner">Hello World</h1><p>You can have nested elements like this:</p><ul><li>Item 1</li><li>Item 2</li></ul><div>Not only that but also you can have HTMX attributes</div><buttonhx-target="rubber-band">Click me</button><imgid="spinner"src="loading.gif"class="spinner-animation"/></div>So I can write views like code, what's the big deal?As much as people hated PHP and made fun of it, with the invention of HTMX, it has become evident that building medium-sized applications in React is bloated (as React was intended for smaller parts of the page). The effort engineers put into basic tasks that could be accomplished by merely sending back HTML from the server was underestimated.While you might be averse to the idea of replacing .innerHTML the old-school way, it turns out you can achieve a lot with just HTMX and jQuery-like declarative DOM (here is an example).Now, there are a few excellent aspects that backend developers will truly appreciate about htmxido:It's all Python- This means it runs fast! You can use existing tooling and linters.Lazy evaluated- Unless you serialize your DOM (with conversion to str), it remains a DOM! This implies that you can cache for even more speed.Functional components- You can easily envision view functions returning these DOM elements that can be reused across requests.So in a nutshell you can do something like this:fromhtmxidoimportDOMElement,domx## Imagine more functional components here## For this example let's imagine we want to render a header component with hamburger menu.@cached(ttl=3600)defheader(account:AccountInfo)->DOMElement:"""Returns header DOM component for given element account info"""returndomx.div(class_="nav-bar full-width responsive")(domx.h1(f"Welcome{account.name}"),hamburger(account)# Reusing another component)More usage examples:Here is an example app Sanic:fromsanicimportSanic,htmlfromhtmxidoimportdomxasxapp=Sanic("Pythia")@app.post("/clicked")asyncdefclicked(request):returnhtml(str(x.div("Clicked!!!")))@app.get("/")asyncdefhome(request):returnhtml(str(x.html(x.head(x.script(src="https://unpkg.com/htmx.org@1.9.9")),x.body(x.h1("Running htmxido"),x.div(id="container")(x.button("Reveal!!!",hxTarget="#container",hxTrigger="click",hxPost="/clicked")),))))ContributingI use pytest for testing, and coverage for coverage report. You can simply run tests by:coveragerun-mpytest&&coveragehtml&&openhtmlcov/index.html