How to replicate <button> in Eliom

227 Views Asked by At

I am trying to replicate the following code in Eliom but I cannot figure out the best way to replicate the <button> tag. The Eliom docs have only left me more confused. It seems like using string_button may be the best way to go but I do not understand what I supply for the name argument.

<!DOCTYPE html>
<html lang="en">
<head>
  <title>Bootstrap Example</title>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
  <script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
</head>
<body>

<div class="container">
  <h2>Button Styles</h2>
  <button type="button" class="btn btn-default">Default</button>
  <button type="button" class="btn btn-primary">Primary</button>
  <button type="button" class="btn btn-success">Success</button>
  <button type="button" class="btn btn-info">Info</button>
  <button type="button" class="btn btn-warning">Warning</button>
  <button type="button" class="btn btn-danger">Danger</button>
  <button type="button" class="btn btn-link">Link</button>      
</div>

</body>
</html>

string_button:

val string_button : 
  ?a:HTML5_types.button_attrib Eliom_pervasives.HTML5.M.attrib list ->
  name:[< string Eliom_parameters.setone ] Eliom_parameters.param_name ->
  value:string ->
  HTML5_types.button_content Eliom_pervasives.HTML5.M.elt list ->
  [> HTML5_types.button ] Eliom_pervasives.HTML5.M.elt

string_button doc: http://ocsigen.org/eliom/2.0/api/client/Eliom_output.Html5#VALstring_button

Edit: I would think that the type signatures from the Eliom documentation

name:[< string Eliom_parameters.setone ] Eliom_parameters.param_name

type +'a param_name

type 'a setone = [ `One of 'a | `Set of 'a ]

would mean that I would use something like

~name:(`One "name_goes_here")

which has the type signature

[> `One of string ]

which would lead me to believe that I need use

~name:(`One "name_goes_here") param_name

to get a signature of

[< string Eliom_parameters.setone ] Eliom_parameters.param_name

but it only yields the following error:

Error: Parse error: currified constructor

What am I doing wrong?

1

There are 1 best solutions below

4
On

The type of that parameter indeed looks a bit confusing at first glance, but by looking at each element of the type, it is actually quite understandable:

Eliom_parameters.param_name

From the Eliom documentation:

type 'a param_name

Abstract type for parameters' name. The 'a type parameter is a phantom type, usually a subtype of Eliom_parameters.​setoneradio, used to denotes the parameter's arity.

Here, a phantom type means that the type parameter doesn't actually appear in the type definition, but only serves as a way to help the type checker discriminate values further than just their original "undecorated type" (what I mean here is the type without the phantom parameter type). In other words, whatever 'a may be, it will not change the actual value your function will expect, but it may restrict which other function could then manipulate that value, once it's been typed.

That said, the type itelf is an abstract type, which means that we cannot construct a value of that type directly, we must rely on functions included in the framework to provide them for us.

If we look at how services are constructed in eliom, we notice that forms are built using placeholders for values of this kind, and wrapped with a function sporting a parameter for each of these values. This let us construct reusable and meaningful html fragments like forms with strongly typed parameters.

The documentation confirms this insight:

Eliom redefines most forms elements (inputs, textareas, checkboxes, etc.) to make possible to check the type of the form w.r.t. the type of the service.

In your case, the elements are not yet embedded in a form, so your best option is probably to use so called raw elements. Most (if not all) of them are located in the same modules as regular form widgets; the one you wish to use is called raw_button and takes string arguments for both name and value parameters.