Service handlers

Output modules

Once the service identification mechanism identifies the service responsible for a given URL, it executes its service handler. The service handler is a function taking the GET and POST parameters as arguments and returning the content to be sent to the client. The return type of the service handler depends on the function used to register it. The most common case is HTML content build with the TyXML library, but Eliom additionally provides a lot of output modules to ease the implementation of common Web interaction. See section Predefined output modules for a comprehensive list.

List of predefined output modules

Services can send several types of data, using a variety of predefined modules. It is also possible to create your own output modules. The main predefined output modules are:

Generating content for the browser

Eliom_registration.​Html
Registration of functions that generate HTML pages statically checked using polymorphic variant types. You may use constructor functions from Eliom_content.​Html.​D or a syntax extension close to the standard HTML syntax.
Eliom_registration.​Flow5
Registration of functions that generate a portion of page using Eliom_content.​Html.​F or the syntax extension (useful for XMLHttpRequest requests for example). Do not use with Eliom applications: you can instead use Error a_api: invalid contents to call server functions that produce HTML nodes.
Eliom_registration.​HtmlText
Registration of functions that generate text HTML pages, without any validation of the content. The content type sent by the server is "text/html".
Eliom_registration.​CssText
Registration of functions that generate CSS pages, without any validation of the content. The content type sent by the server is "text/css".
Eliom_registration.​String
Registration of functions that generate text pages, without any validation of the content. The services return a pair of strings. The first string is the content of the page, while the second string is the content type.
Eliom_registration.​File
Registration of services that send files. See here for an example of use.
Eliom_registration.​Streamlist
Registration of services that send "byte" contents. It is used when big content (that does not fit in memory) is generated.

Generating content for client-server applications

Eliom_registration.​App
Functor that allows creation of services belonging to a client-server Eliom application (see chapter client-server applications).

Special browser interraction

Eliom_registration.​Action
Registration of actions (functions that do not generate any page. See Action). The page corresponding to the URL (without the special parameter identifying the action) is reloaded after the action by default if possible.
Eliom_registration.​Unit
Like Eliom_registration.​Action, but the URL is not reloaded after the action. (Same as Eliom_registration.Action with [`NoReload] option).
Eliom_registration.​Redirection
Registration of HTTP redirections. The handler returns the service (without parameter) of the page you want to redirect to. The browser will get a 301 or 307 code in answer and redo the request to the new URL. To specify whether you want temporary (307) or permanent (301) redirections, use the ?options parameter of registration functions. For example: register options:`Permanent ... or register options:`Temporary ....
Eliom_registration.​String_redirection
Same but the ouput type is a string. Use with care! Warning: According to the RFC of the HTTP protocol, the URL must be absolute!

Customization of other outputs

Eliom_registration.​Customize
Specialization of service registration functions by customizing the page type.

Sending caml values to client side code

Eliom_registration.​Ocaml
Registration of services sending marshalled OCaml values. See the section on communications in the chapter about client-server applications.

Runtime choice of content

Eliom_registration.​Any
Registration of services that can choose what they send, for example an HTML page or a file, depending on some situation (parameter, user logged or not, page present in a cache ...). It is also possible to create your own modules for other types of pages. See here for an example of use.

Advanced output modules

Sending files

You may want to register a service that sends files. To do so, use the Eliom_registration.​File module. Example:

let sendfile =
  Eliom_registration.File.create
    ~path:(Eliom_service.Path ["sendfile"])
    ~meth:(Eliom_service.Get Eliom_parameter.unit)
    (fun () () -> return "filename")

Other example, with "suffix" services (see here):

let sendfile2 =
  Eliom_registration.File.create
    ~path:(Eliom_service.Path ["files"])
    ~meth:
      (Eliom_service.Get
         Eliom_parameter.(suffix (all_suffix "filename")))
    (fun s () -> Lwt.return @@
      "//path//" ^
      Ocsigen_lib.Url.string_of_url_path ~encode:false s)

The extension Staticmod is another way to handle static files.

Sending portions of pages

The Eliom_registration.​Flow5 module allows you to register services that send portions of pages, of any element type. It is sometimes useful to create AJAX pages (i.e. pages using the XMLHttpRequest JavaScript object). Note that the service returns a list of blocks. For sending HTML to the client-side portion of an Eliom application, server functions (Error a_api: invalid contents) are better-suited.

let divpage =
  Eliom_registration.Flow5.create
    ~path:(Eliom_service.Path ["div"])
    ~meth:(Eliom_service.Get Eliom_parameter.unit)
    (fun () () ->
      Lwt.return
        [div [h2 [pcdata "Hallo"];
              p [pcdata "Blablablabla"] ]])

The Eliom_registration.​Make_typed_xml_registration module allows the creation of new modules for registering portions of pages of other types. For example, Eliom_registration.​Flow5 is defined by:

module Flow5 = Make_typed_xml_registration(Xml)(Html.F)(struct
  type content = Html_types.body_content
end)

Redirections

Redirections to Eliom services

The Eliom_registration.​Redirection module allows one to register HTTP redirections.
If a request is made for such a service, the server asks the browser to retry with another URL.

Redirection services need to return a GET service without parameter at all. Example:

let redir1 =
  Eliom_registration.Redirection.create
    ~options:`TemporaryRedirect
    ~path:(Eliom_service.Path ["redir"])
    ~meth:(Eliom_service.Get Eliom_parameter.uni)
    (fun () () -> Lwt.return someservice)

If you want to give parameters to such services, use Eliom_service.​preapply (see also in section about pre-applied services). Example:

let redir = Eliom_registration.Redirection.create
   ~options:`TemporaryRedirect
   ~path:(Eliom_service.Path ["redir"])
   ~meth:(Eliom_service.Get Eliom_parameter.(int "o"))
   (fun o () ->
      Lwt.return
        (Eliom_service.preapply service_with_params (o,(22,"ee"))))

The options parameter may be either `Temporary or `Permanent.

Note that the cost of a redirection is one more request and one more response.

Redirections to generated URLs

The Eliom_registration.​String_redirection module allows one to register HTTP redirections to custom URLs provided as strings. In most cases, it is a better idea to use Eliom_registration.​Redirection, even for external redirections (using Eliom_service.​extern). Use Eliom_registration.​String_redirection only when it is not possible to have a service corresponding to a URL.

Notice that the supplied URL must be absolute.

Actions

Actions are used to perform side effects before generating the fallback of a service. When an action is called, the service handler is executed, then the service handler of the fallback service is executed.

Eliom references of scope Eliom_common.​request_scope set in an action handler are still available in the service handler of the fallback.

A common use of actions and pathless services working synergistically is the implementation of login/logout forms. Actions are well-suited for the following reasons:

  • Connection and disconnection can happen as the side-effect of the action, after which we stay on the same page; and
  • The connection/disconnection form generally needs to be present on all pages. An action implemented as a pathless service will respond no matter what page it is called from, so there is no need to create a version with POST parameters of each service. The implementation of the same behavior with standard Web programming techniques is usually much more complicated.

Registering services that decide what they want to send

You may want to register a service that will send, for instance, sometimes an HTML page, sometimes a file, sometimes something else. To do that, use the Eliom_registration.​Any module, together with the send function of the module you want to use. Example:

let send_any =
  Eliom_registration.Any.create
    ~path:(Eliom_service.Path ["sendany"])
    ~meth:(Eliom_service.Get Eliom_parameter.(string "type"))
    (fun s () ->
       if s = "valid" then
         Eliom_registration.Html.send
           (html
              (head (title (pcdata "")) [])
              (body [p [pcdata "This page has been statically checked. ";
                        pcdata "If you change the parameter in the URL ";
                        pcdata "will get an unchecked text page"]]))
       else
         Eliom_registration.Html_text.send
           "<p>Not a valid page. Try with type=\"valid\" in the URL.</p>")
Dynamically modifying register options using Any

You may also use Eliom_registration.​Any to dynamically modify the parameters usually set on the register function. You can set the HTTP code, the charset, the content_type, the HTTP headers and the speci