How to use Eliom_parameter.listnames to build a form for POST service

I’m using Eliom 6.6 and I have a post service which takes two lists of integers.

let my_post_service =
  Eliom_service.create
    ~path:Eliom_service.No_path
    ~meth:(
      Eliom_service.Post (
        Eliom_parameter.unit,
        list "group_1_ids" (int "id_1") **
        list "group_2_ids" (int "id_2")
      )
    ) ()

I now want to build a form for this service. The ocsigen website says that Eliom_parameter.listnames should be used to build the form.

“To create the form, an iterator of type Eliom_parameter.listnames is given to generate the name for each value.”

I know how to build a POST form with simple Eliom_parameter types, but I’m not sure how to use listnames to build a form for my POST service with two lists.

Are there any examples on how to do this? I’m honestly a little confused by the type signature for listnames, and I could not find any examples online.

type 'an listnames = {
  it: 'el 'a. ('an -> 'el -> 'a -> 'a) -> 'el list -> 'a -> 'a;}

Thanks,
Thomas

There is an example here: https://ocsigen.org/eliom/latest/manual/server-links#h5o-9

I rewrote it in modern Eliom here:

let service_list =
  Eliom_registration.Html.create
    ~path:(Eliom_service.Path ["thepath"])
    ~meth:(Eliom_service.Get Eliom_parameter.(list "a" (string "str")))
    (fun l () ->
      let open Eliom_content.Html.D in
      let ll = List.map (fun s -> strong [txt s]) l in
      Lwt.return (html (head (title (txt "Example")) []) (body [p ll])))

let create_listform f =
  (* Here, f.it is an iterator like List.map,
     but it must be applied to a function taking 3 arguments
     (unlike 1 in map), the first one being the name of the parameter,
     and the second one the element of list.
     The last parameter of f.it is the code that must be appended at the
     end of the list created
  *)
  let open Eliom_content.Html.D in
  f.Eliom_parameter.it
    (fun stringname v init ->
      p
        [ txt "Write the value for "
        ; txt v
        ; txt " :"
        ; Form.input ~input_type:`Text ~name:stringname Form.string ]
      :: init)
    ["one"; "two"; "three"; "four"]
    [p [Form.input ~input_type:`Submit ~value:"Click" Form.string]]

let _ =
  Eliom_registration.Html.create
    ~path:(Eliom_service.Path ["listform"])
    ~meth:(Eliom_service.Get Eliom_parameter.unit)
    (fun () () ->
      let open Eliom_content.Html.D in
      let f = Form.get_form ~service:service_list create_listform in
      Lwt.return (html (head (title (txt "Example")) []) (body [f])))

Thanks for helping me out! I’m not sure how I missed that on the Ocsigen website, but the example is great.