Embedded ocaml templates

I am very happy to announce the release of ocaml-embedded-templates.

This is a tool similar to camlmix, but camlmix was not updated for 7 years, and there is no easy way to handle a lot of templates (my command takes a directory as an argument and generate an ocaml module by going through the directory recursively)
I also choosed to use a syntax similar to EJS, and there is a ppx for inline EML.

You can check it out here : https://github.com/EmileTrotignon/embedded_ocaml_templates

Here is a more extensive exemple of what can be done with this : https://github.com/EmileTrotignon/resume_of_ocaml (This project generate my resume/website in both latex and html).

This is my first opam package : feedback is very much welcome.

1 Like

This looks very interesting, I’ll try it out. I’m writing a web framework and need a good view compiler. Currently I’m using functions as views, e.g.

let view_article id name p =
  p {|<article id="|};
  p id;
  p {|"><h2>|};
  p name;
  p {|</h2></article>|}

Obviously, this is sub-optimal.

My question is, how close is ocaml-embedded-templates output to my view functions? I.e., will a template like:

<%# id name %>
<article id="<%-id%>"><h2><%-name%></h2></article>

…produce a function like mine?

I will not really do that.
Your function/view is of type string -> string -> (string -> unit) -> unit.
The function generated by EML will be of type string -> string -> string.

However I see the benefits of your approach, and I think it might be a good idea to add this, maybe as an option to EML, or maybe p could be an optionnal parameter to the function. It would be really easy to implement and provide a lot of benefits (less allocations I guess, depending on p's value).
Dont you think having type (string -> unit) -> string -> string -> unit would be better though ? This would allow to curry the template by the output function you like.

Tell me what you think :slight_smile:

Exactly, the idea is to avoid allocations, e.g. imagine that p is print_string. In my web framework I have an API for responding with a view, Response.of_view (view_article id name). Keeping the p as the final parameter allows me to partially apply all the other parameters of the view and always pass a ((string -> unit) -> unit) to Response.of_view.

To be honest, this approach is not completely my idea, I saw ECaml doing something very close, but didn’t use ECaml itself because it is GPL licensed (although that’s probably not a great reason).

EDIT: but I will play around with your repo, see how it works. Thanks for publishing!

What about

open Tyxml
let%html view_article id name p =
   "<article id="id"><h2>"name"</h2></article>"

? :slight_smile:
You can even use Reason’s JSX if that’s your thing.

2 Likes

Oh Tyxml is quite nice, I did not knew it could do that.

I have pushed a commit that allow you to do exactly what you wanted, I also modified the exemple to use the new option, tell me if you think it’s useful.

For now I want an unopinionated templating language that can output anything from HTML to JSON to CSV, etc., but Tyxml is a very cool technology, I will take another look at it.

Cool! Will check it out. Thank you!