
# Miscellaneous


## HTML widgets


### Images, CSS, Javascript

To include an image, simply use function [`Eliom_content.Html.D.img`](./eliom.server/Eliom_content-Html-D.md#val-img):

```ocaml
img ~alt:"Ocsigen"
    ~src:(Eliom_content.Html.F.make_uri
            ~service:(Eliom_service.static_dir ())
            ["images"; "ocsigen1024.jpg"])
    ()
```
The function [`Eliom_content.Html.D.make_uri`](./eliom.server/Eliom_content-Html-D.md#val-make_uri) creates a relative URL string from current URL (see above) to the URL of the image (here in the static directory configured in the configuration file).

To simplify the creation of `<link>` tags for CSS or `<script>` tags for Javascript, use the following functions:

```ocaml
Eliom_content.Html.F.css_link
  ~uri:(Eliom_content.Html.F.make_uri
         ~service:(Eliom_service.static_dir ()) ["style.css"]) ()
```
```ocaml
Eliom_content.Html.F.js_script
  ~uri:(Eliom_content.Html.F.make_uri
         ~service:(Eliom_service.static_dir ()) ["funs.js"]) ()
```

### Basic menus

To generate a context-aware menu on your Web page, you can use the function [`Eliom_tools.HTML5_TOOLS.menu`](./eliom.server/Eliom_tools-module-type-HTML5_TOOLS.md#val-menu). This function can be used from either of the modules `Eliom_tools.Html.D` or `Eliom_tools.Html.F`. (See [HTML element manipulation, by value and by reference](./clientserver-html.md#unique)).

Here is a simple example:

```ocaml
let mymenu =
  let items =
    [(home,     [txt "Home"]);
     (info,     [txt "More info"]);
     (tutorial, [txt "Documentation"])]
  in
    Eliom_tools.D.menu
    ~classe:["menuprincipal"]
    items
    ~service:Eliom_service.reload_action
```
`items` is a list of pairs correlating the services to be linked with the text to be displayed: `home`, `info`, and `tutorial` are our three services (generated, for example, by [`Eliom_registration.App.create`](./eliom.server/Eliom_registration-App.md#val-create) or [`Eliom_service.create`](./eliom.server/Eliom_service.md#val-create)).

The argument to the optional parameter `classe` adds the class `menuprincipal` to the resulting menu element.

The argument to the optional parameter `service` determines which menu item to highlight. In this case, we use [`Eliom_service.reload_action`](./eliom.server/Eliom_service.md#val-reload_action) to highlight whichever service is currently being visited.

`mymenu ()`, when viewed on the home page, will generate the following HTML:

```ocaml
<ul class="eliomtools_menu menuprincipal caml_r" data-eliom-id="x1TqwAXRlB1I">
  <li class="eliomtools_current eliomtools_first">
    Home
  </li>
  <li>
    <a class="caml_c" href="info/" data-eliom-c-onclick="P7IUw76wowL1">
      More info
    </a>
  </li>
  <li class="eliomtools_last">
    <a class="caml_c" href="tutorial/" data-eliom-c-onclick="P7IUw76wowL2">
      Documentation
    </a>
  </li>
</ul>
```
You may then personalize the element in your CSS stylesheet as normal.

Note: [`Eliom_tools.D.menu`](./eliom.server/Eliom_tools-D.md#val-menu) takes a list of services without GET parameters. If you want one of the links to contain GET parameters, pre-apply the service.


### Hierarchical menus

```ocaml
(* Hierarchical menu *)
open Eliom_tools_common

let hier1 = service ~path:["hier1"] ~get_params:unit ()
let hier2 = service ~path:["hier2"] ~get_params:unit ()
let hier3 = service ~path:["hier3"] ~get_params:unit ()
let hier4 = service ~path:["hier4"] ~get_params:unit ()
let hier5 = service ~path:["hier5"] ~get_params:unit ()
let hier6 = service ~path:["hier6"] ~get_params:unit ()
let hier7 = service ~path:["hier7"] ~get_params:unit ()
let hier8 = service ~path:["hier8"] ~get_params:unit ()
let hier9 = service ~path:["hier9"] ~get_params:unit ()
let hier10 = service ~path:["hier10"] ~get_params:unit ()

let mymenu =
  (
   (Main_page hier1),

   [([txt "page 1"], Site_tree (Main_page hier1, []));

    ([txt "page 2"], Site_tree (Main_page hier2, []));

    ([txt "submenu 4"],
     Site_tree
       (Default_page hier4,
         [([txt "submenu 3"],
          Site_tree
             (Not_clickable,
              [([txt "page 3"], Site_tree (Main_page hier3, []));
               ([txt "page 4"], Site_tree (Main_page hier4, []));
               ([txt "page 5"], Site_tree (Main_page hier5, []))]
             )
          );

          ([txt "page 6"], Site_tree (Main_page hier6, []))]
       )
    );

    ([txt "page 7"],
     Site_tree (Main_page hier7, []));

    ([txt "disabled"], Disabled);

    ([txt "submenu 8"],
     Site_tree
       (Main_page hier8,
        [([txt "page 9"], Site_tree (Main_page hier9, []));
         ([txt "page 10"], Site_tree (Main_page hier10, []))]
       )
    )
  ]
  )

let f i s () () =
  return
    (html
       (head (title (txt ""))
          ((style ~contenttype:"text/css"
             [cdata_style
 "a {color: red;}\n
  li.eliomtools_current > a {color: blue;}\n
  .breadthmenu li {\n
    display: inline;\n
    padding: 0px 1em;\n
    margin: 0px;\n
    border-right: solid 1px black;}\n
  .breadthmenu li.eliomtools_last {border: none;}\n
                "])::
                Html_tools.F.structure_links mymenu ~service:s ())
             )
       (body [h1 [txt ("Page "^string_of_int i)];
              h2 [txt "Depth first, whole tree:"];
              div
                (Html_tools.F.hierarchical_menu_depth_first
                   ~whole_tree:true mymenu ~service:s ());
              h2 [txt "Depth first, only current submenu:"];
              div (Html_tools.F.hierarchical_menu_depth_first mymenu ~service:s ());
              h2 [txt "Breadth first:"];
              div
                (Html_tools.F.hierarchical_menu_breadth_first
                   ~classe:["breadthmenu"] mymenu ~service:s ())]))


let _ =
  register hier1 (f 1 hier1);
  register hier2 (f 2 hier2);
  register hier3 (f 3 hier3);
  register hier4 (f 4 hier4);
  register hier5 (f 5 hier5);
  register hier6 (f 6 hier6);
  register hier7 (f 7 hier7);
  register hier8 (f 8 hier8);
  register hier9 (f 9 hier9);
  register hier10 (f 10 hier10)
```