Hacker News new | past | comments | ask | show | jobs | submit | pelme's comments login

We have been doing something similar with https://htpy.dev the last ~6 months.

Writing out the code to generate this may not be easier than using templates, but it is not really harder either. I think it mostly looks a little different.

The real benefit is using this bootstrap modal component within your app, since it is just a regular function call. You can leverage your editor "goto definition" and static type checking within all the functions make up your web sites/apps HTML.


This looks great! Building HTML on the server with static types and htmx is a very productive combination!

At work, we have been exploring alternatives to templates in our Django project and just released it as a lib to help with this:

https://htpy.dev/


Whoa, a creative (in a good way IMO) use of __ getitem__() dunder method to depict attributes and children. No action at a distance using with blocks, static and strongly typing instead of stringly typing, no need to extend Python, composable from fragments.

Have you tried to "bring up front" if and for? For example

> if_(cond, tag1(), tag2()) # without eagerly execute both branches

Instead of

> tag1() if cond else tag2()

And

for_(cars, lambda car: car_details(car)) # while still being type checked

Instead of

> [car_details(car) for car in cars]


Python's inline if's still read backwards to me and it would be nice to switch the order. But we are kind of stuck with it. I also don't want to introduce new control structures in this lib. Just want to use whatever Python has to offer in terms of control structures/syntax to make it more approachable.

htpy supports generators/callables as children (https://htpy.dev/streaming/). As long as you are careful to wrap things in generators/lambdas everything is lazy. Implementing if_ and for_ is straightforward and anyone can build constructs like that to use. But will not be lazy unless all arguments are wrapped in lambdas:

  from htpy import div, li, ul

  def if_(cond, a, b):
      return a() if cond() else b()

  def for_(items, func):
      return (func(item) for item in items())

  print(div[if_(lambda: True, lambda: "True!", lambda: "False!")])
  print(div[if_(lambda: False, lambda: "True!", lambda: "False!")])
  print(ul[for_(lambda: ["a", "b", "c"], lambda x: li[x])])
output:

  <div>True!</div>
  <div>False!</div>
  <ul><li>a</li><li>b</li><li>c</li></ul>


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: