# Embedded ocaml templates

**URL:** <https://discuss.ocaml.org/t/embedded-ocaml-templates/6124>\
**Category:** Community\
**Tags:** announce\
**Created:** [July 21, 2020, 7:41pm UTC](https://discuss.ocaml.org/t/embedded-ocaml-templates/6124 "2020-07-21T19:41:05Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![EmileTrotignon](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/emiletrotignon/32/5913_2.png) [@EmileTrotignon](https://discuss.ocaml.org/u/EmileTrotignon)\
**Post date:** [July 21, 2020, 7:41pm UTC](https://discuss.ocaml.org/t/embedded-ocaml-templates/6124/1 "2020-07-21T19:41:05Z")

</div>

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](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](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.

---

<div class="post-metadata">

**Author:** ![yawaramin](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/yawaramin/32/3384_2.png) [@yawaramin](https://discuss.ocaml.org/u/yawaramin)\
**Post date:** [July 21, 2020, 8:52pm UTC](https://discuss.ocaml.org/t/embedded-ocaml-templates/6124/2 "2020-07-21T20:52:33Z")

</div>

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.

```auto
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:

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

```

…produce a function like mine?

---

<div class="post-metadata">

**Author:** ![EmileTrotignon](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/emiletrotignon/32/5913_2.png) [@EmileTrotignon](https://discuss.ocaml.org/u/EmileTrotignon)\
**Post date:** [July 21, 2020, 10:42pm UTC](https://discuss.ocaml.org/t/embedded-ocaml-templates/6124/3 "2020-07-21T22:42:11Z")

</div>

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 🙂

---

<div class="post-metadata">

**Author:** ![yawaramin](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/yawaramin/32/3384_2.png) [@yawaramin](https://discuss.ocaml.org/u/yawaramin)\
**Post date:** [July 21, 2020, 11:12pm UTC](https://discuss.ocaml.org/t/embedded-ocaml-templates/6124/4 "2020-07-21T23:12:11Z")

</div>

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](http://komar.in/en/code/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!

---

<div class="post-metadata">

**Author:** ![Drup](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/drup/32/35_2.png) [@Drup](https://discuss.ocaml.org/u/Drup)\
**Post date:** [July 22, 2020, 12:28pm UTC](https://discuss.ocaml.org/t/embedded-ocaml-templates/6124/5 "2020-07-22T12:28:21Z")

</div>

> [@yawaramin](#):
>
> Currently I’m using functions as views, e.g.
> 
> ```auto
> let view_article id name p =
> p {|<article id="|};
> p id;
> p {|"><h2>|};
> p name;
> p {|</h2></article>|}
> 
> ```
> 
> Obviously, this is sub-optimal.

What about

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

```

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

---

<div class="post-metadata">

**Author:** ![EmileTrotignon](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/emiletrotignon/32/5913_2.png) [@EmileTrotignon](https://discuss.ocaml.org/u/EmileTrotignon)\
**Post date:** [July 22, 2020, 12:32pm UTC](https://discuss.ocaml.org/t/embedded-ocaml-templates/6124/6 "2020-07-22T12:32:27Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![yawaramin](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/yawaramin/32/3384_2.png) [@yawaramin](https://discuss.ocaml.org/u/yawaramin)\
**Post date:** [July 22, 2020, 4:05pm UTC](https://discuss.ocaml.org/t/embedded-ocaml-templates/6124/7 "2020-07-22T16:05:28Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![yawaramin](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/yawaramin/32/3384_2.png) [@yawaramin](https://discuss.ocaml.org/u/yawaramin)\
**Post date:** [July 22, 2020, 4:05pm UTC](https://discuss.ocaml.org/t/embedded-ocaml-templates/6124/8 "2020-07-22T16:05:56Z")

</div>

Cool! Will check it out. Thank you!

---

<div class="post-metadata">

**Author:** ![borisd](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/borisd/32/3965_2.png) [@borisd](https://discuss.ocaml.org/u/borisd)\
**Post date:** [September 26, 2021, 11:26pm UTC](https://discuss.ocaml.org/t/embedded-ocaml-templates/6124/9 "2021-09-26T23:26:45Z")

</div>

> [@Drup](#):
>
> ```auto
> open Tyxml
> let%html view_article id name p =
> "<article id="id"><h2>"name"</h2></article>"
> 
> ```

How can I test this in the ocaml repl or utop? I’ve tried:

```auto
# #require "tyxml-jsx";;
# let%html view_article id name p =
   "<article id="id"><h2>"name"</h2></article>";;
Error: Uninterpreted extension 'html'.
# #ppx "/Users/boris/.opam/ocsi/lib/tyxml-jsx/./ppx.exe";;
# let%html view_article id name p =
   "<article id="id"><h2>"name"</h2></article>";;[%%html                                                                
  let view_article id name p =
    "<article id=" id "><h2>" name "</h2></article>"]
File "/var/folders/kl/7z2_bknj4ynch1dlb6d8w5jm0000gn/T/camlppx94864b", line 1:
Error: I can't decide whether /var/folders/kl/7z2_bknj4ynch1dlb6d8w5jm0# let%html view_article id name p =
   "<article id="id"><h2>"name"</h2></article>";;
Error: Error while running external preprocessor

```

Is this syntax from a different package?

---

<div class="post-metadata">

**Author:** ![EmileTrotignon](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/emiletrotignon/32/5913_2.png) [@EmileTrotignon](https://discuss.ocaml.org/u/EmileTrotignon)\
**Post date:** [September 27, 2021, 11:28am UTC](https://discuss.ocaml.org/t/embedded-ocaml-templates/6124/10 "2021-09-27T11:28:00Z")

</div>

Yes its from another package. The ppx rewriter for embedded ocaml templates uses %eml.  
Apart from that, I have no idea how to load a ppx in the REPL.

---

<div class="post-metadata">

**Author:** ![cemerick](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/cemerick/32/1383_2.png) [@cemerick](https://discuss.ocaml.org/u/cemerick)\
**Post date:** [September 27, 2021, 12:56pm UTC](https://discuss.ocaml.org/t/embedded-ocaml-templates/6124/11 "2021-09-27T12:56:46Z")

</div>

No need to mess with utop’s `#ppx` directives, it is set up automatically when you require the ppx library (but fwiw, you were trying to wire in the jsx ppx, which is not what Drup’s example is using).

```auto
─( 08:54:06 )─< command 0 >───────────────────────────────────────────────────────────────{ counter: 0 }─
utop # #require "tyxml";;
─( 08:54:06 )─< command 1 >───────────────────────────────────────────────────────────────{ counter: 0 }─
utop # #require "tyxml-ppx";;
─( 08:54:12 )─< command 2 >───────────────────────────────────────────────────────────────{ counter: 0 }─
utop # open Tyxml;;
─( 08:54:16 )─< command 3 >───────────────────────────────────────────────────────────────{ counter: 0 }─
utop # let%html view_article id name p =
   "<article id="id"><h2>"name"</h2></article>";;
val view_article :
  string ->
  [< Html_types.h2_content_fun] Tyxml_html.elt list ->
  'a -> [> Html_types.article] Tyxml_html.elt = <fun>

```
