This short tutorial is an example of client-server Eliom application. It gives an example of client-server widgets. You can find the original version of this tutorial (and many others) here.
It is probably a good starting point if you know OCaml well, and want to quickly learn how to write a client-server Eliom application with a short example and concise explanations. For more detailed explanations, see the “Graffiti” tutorial, or read the manuals.
This tutorial also shows that it is possible to use the same code to build the widget either on client or server side.
We choose a very simple widget, that could be the base for example for implementing a drop-down menu. It consists of several boxes with a title and a content. Clicking on the title opens or closes the content. Furthermore, it is possible to group some of the boxes together to make them behave like radio buttons: when you open one of them, the previously opened one is closed.
The following code defines a client-server Web application with only one service, registered at URL / (the root of the website).
The code also defines a client-side application (section
[%%client ... ]) that appends a client-side generated widget to the page. Section
[%%shared ... ] is compiled on both the server and client side programs. Alternatively, you can write
let%shared (default) to define values on client side, on server side, or on both sides.
To compile it, first create a project by calling
eliom-distillery -name ex -template basic.ppx
The name of the project must match the name given to the functor
After you adapt the file
ex.eliom, you can compile by calling make, and run the server by calling
make test.byte. Download the CSS file and place it in directory
static/css. Then open a browser window and go to URL
This section gives very quick explanations on the rest of the program. For more detailed explanations, see the tutorial for the graffiti app or the manual of each of the projects.
##is used to call a JS method from OCaml and
##.to access a JS object field (See Js_of_ocaml’s documentation: Ppx_js).
Lwtis the concurrent library used to program threads on both client and server sides. The syntax
let%lwt a = e1 in e2allows waiting (without blocking the rest of the program) for an Lwt thread to terminate before continuing.
e2must ben a Lwt thread itself.
Lwt.returnenables creating an already-terminated Lwt thread.
Lwt_js_eventsdefines a convenient way to program interface events (mouse, keyboard, …). For example,
Lwt_js_events.onloadis a Lwt thread that waits until the page is loaded. There are similar functions to wait for other events, e.g., for a click on an element of the page, or for a key press.
To make the widget work, we must bind the click event. Replace function
mywidget by the following lines:
clicksis used to bind a handler to clicks on a specific element.
Lwtthread asynchronously (without waiting for its result).
Lwt_js_events.clicks elt fcalls function
ffor each mouseclick on element
Js.to_boolare conversion functions between OCaml values and JS values.
The following version of the program shows how to generate the widget on server side, before sending it to the client.
The code is exactly the same, with the following modifications:
[%client (... : unit) ]. This code will be executed by the client-side program when it receives the page. Note that you must give the type (here
unit), as the type inference for client values is currently very limited. The client section may refer to server side values, using the
~%xsyntax. These values will be serialized and sent to the client automatically with the page.
If you make function
mywidget shared, it will be available both on server and client sides:
To implement this, we record a client-side reference to a function for closing the currently opened window.
Now we want to enable several sets of widgets in the same page. A single reference no longer suffices. In the following version, the server-side program asks the client-side program to generate two different references, by calling function
new_set. This function returns what we call a client value. Client values are values of the client side program that can be manipulated on server side (but not evaluated). On server side, they have an abstract type.
An important feature missing from this tutorial is the ability to call server functions from the client-side program (“server functions”). You can find a quick description of this in this mini HOWTO or in Eliom’s manual.
For many applications, you will need several services. By default, client-side Eliom programs do not stop when you follow a link or send a form. This enables combining rich client side features (playing music, animations, stateful applications …) with traditional Web interaction (links, forms, bookmarks, back button …). Eliom proposes several ways to identify services, either by the URL (and parameters), or by a session identifier (we call this kind of service a coservice). Eliom also allows creating new (co-)services dynamically, for example coservices depending on previous interaction with a user. More information on the service identification mechanism in Eliom’s manual.
Eliom also offers a rich session mechanism, with scopes (see Eliom’s manual).