Htmx/htmlact web development approach

This is also particularly useful when working with CSS frameworks, as you can design your own combinators to mirror the CSS components provided by the framework.

Another benefit I’ve had is that I can parameterise my CSS framework binding by the signature of the underlying HTML combinators, and then transparently get a library that I can use for both static server-side HTML rendering (using Tyxml and then printing to string), and also dynamic HTML generation using a js_of_ocaml library like @dbuenzli’s Brr library.

module Bulma (H: HTML_SIG) = struct
  let txt = H.txt
  let a_class = H.a_class
  let a_class' v = H.a_class [v]

...

  let navbar_item_with_dropdown ?a_class:cls ?a elt elts =
    navbar_item ~a_class:(o_cat cls ["has-dropdown"; "is-hoverable"]) ?a [
      elt;
      navbar_dropdown elts
    ]


I agree, any sufficient templating option should make it trivial to define reusable components. Just for completeness’ sake, here’s the JSX transliteration of this card container snippet, exploded in the way you’ve done with tyxml directly:

open Tyxml.Html;

let medium_txt = heading => <h3 class_="font-medium"> {txt(heading)} </h3>;

let card_title = title =>
  <div class_="py-4 px-5 lg:px-6 w-full bg-gray-50">
    {medium_txt(title)}
  </div>;

let card_footer = footer_txt =>
  <div class_="py-4 px-5 lg:px-6 w-full text-sm text-gray-600 bg-gray-50">
    <p> {txt(footer_txt)} </p>
  </div>;
  
let card_container = children =>
  <div class_="flex flex-col rounded shadow-sm bg-white overflow-hidden">
    ...children
  </div>;

let card =
  card_container([card_title("Card Title"), card_footer("Card Footer")]);
2 Likes

I’m not too familiar with Dream and eml files, but if there’s a command that can turn a .eml file into ocaml source code, you can define a dialect for it - see dune docs - dialect. Then dune will automatically know how to handle .eml files (that’s how Reason support is implemented for example).

4 Likes

Indeed, if you read me well that’s exactly what I suggested – to keep the designer out of your ml code.

To be fair, that’s not OCaml, that’s automatically generated OCaml barf. In OCaml you have let bindings to name components of your structures and make it digestible to readers.

More broadly since the whole separation of content and look turned out to be a fiction, the average webpage source is no longer really human digestible so working with the actual medium and its concrete syntax is of little interest to me. I rather seek to abstract and factor out composable structures which is an excellent application of OCaml.

One thing that was not mentioned but that all these messages about build systems and editor churn reminded me is that by sticking to a simple pure OCaml approach, your build is trivial and your files will likely still compile in 20 years. But I know… programmers do like to invent themselves sophisticated problems :–)

2 Likes

Oh interesting…
dream_eml transform eml file (a mix of HTML & OCaml) into valid OCaml file. Is there a tool already for transforming a valid ml file in to its binary ast?
If so we could pipe the result of dream_eml through it and create the format expected by dune dialect.

Sure, that was just the most direct comparison between canonical source HTML and its tyxml equivalent. See above for a decomposed transliteration of the original HTML.

Right, this is the nut of the differences of opinion. HTML’s concrete syntax is truly a lingua franca, so it’s important to many people to be able to trade in it as directly as possible, while hopefully carrying along as many of the programming tools for abstraction and composition we can manage.

3 Likes

see Consider a more Unix-y interface for dream_eml · Issue #227 · aantron/dream · GitHub and add stdout as output from dream_eml by tcoopman · Pull Request #228 · aantron/dream · GitHub
I think dune is happy accepting an ml file (at least it seemed that way in my tests, only tested very quickly so might have missed something)

1 Like

All I know is, web development is busy reinventing the wheel on UIs and it stinks. GUIs have settled on standardized widgets, and obtaining information from them can be fairly effortless, as in pysimplegui. The web insists on building widgets from scratch, on integrating style into the html (bootstrap), and on embedding application code inside widgets. The result is a mess of bugs and unclear expectations on differing webpages.

Oh and @dbuenzli, I’d love to have pysimplegui in OCaml.

3 Likes

My projet solves this issue I believe : GitHub - EmileTrotignon/embedded_ocaml_templates
The way it is done is by defining a rule on a directory instead of a single file, and all the templates in the directory are then compiled, recursively, into a single ocaml file with submodules. Its a bit ad-hoc, but very useable in my opinion. I used it to generate my resume in both HTML and latex here : GitHub - EmileTrotignon/resume_of_ocaml (in src/lib/templates) with the following dune rule :

(rule
 (target templates.ml)
 (deps
  (source_tree templates))
 (action
  (run eml_compiler templates)))
2 Likes

That’s actually very smart. I assume the dream_eml processor doesn’t support this usage but presumably it could be changed to do so.

Thanks ! No idea if Dream supports that. If it did not break editor support, I would be tempted to do that even with OCaml files, but since eml files don’t have real editor support anyway, its ok.

clever storage is a super power. And is for free, 0 LOC, no dependencies.

1 Like