Previous Up Next

4  Programming with the CamlTemplate Library

When reading this section, you will probably find it helpful to refer to the CamlTemplate API documentation, which is generated by ocamldoc and provided in the doc/api directory of the CamlTemplate distribution.

4.1  The General Procedure

The general procedure is as follows:
  1. Create a template cache using Cache.create.
  2. Create a data model consisting of values of type Model.tvalue.
  3. Load a template using Cache.get_template.
  4. Pass the template to the merge function to generate output.
Here is `Hello, world!' with a template. The template is as follows:
Here is the message: ${message}
And here is a program that uses it:
open Printf ;;
open CamlTemplate.Model ;;

let _ =
  (* Make a template cache. *)
  let cache = CamlTemplate.Cache.create () in
    (* Create a model. *)
  let model = Hashtbl.create 4 in
    Hashtbl.add model "message"
      (Tstr "Hello, world!");    
    try
      (* Get the template. *)
      let tmpl =
        CamlTemplate.Cache.get_template
          cache "hello.tmpl"
          (* Make a buffer for the output. *)
      and buf = Buffer.create 256 in
        (* Generate output. *)
        CamlTemplate.merge tmpl model buf;
        print_string (Buffer.contents buf)
    with
        CamlTemplate.Syntax_error msg ->
          eprintf "\n%s\n" msg
      | CamlTemplate.Template_error msg ->
          eprintf "\n%s\n" msg ;;
There are other examples in the examples directory of the distribution.

4.2  Template Data Models

A template data model is a tree of values; these values can be scalars (strings, integers, floats or booleans), lists, hashtables or functions. The root of the tree must be a hashtable. In a template, an identifier by itself is the name of an entry in that root hashtable.

Tabular data can be represented as a list of hashes of scalars. Each element in the list represents a row in the table, and consists of a hash in which the names are column names and the values are cell values. Such a model can be handled as shown in Section 2.3.

4.3  Loading and Caching Templates

Once loaded and parsed, templates are cached; the Cache module provides functions for creating template caches, getting templates from them and configuring the behaviour of a cache (e.g. how often it is refreshed). By default, templates are loaded from files, but you can provide a class of type source_loader to load them from another source.

The #include and #open statements fetch the included or opened template from the cache when the enclosing template is merged. Therefore, if an #include or #open refers to a template that doesn't exist, this won't be detected until the outer template is merged.

Macros are stored in the templates in which they are defined. When a template containing a macro definition changes, the macro definition is updated as well.

4.4  Threads

CamlTemplate provides optional support for multithreaded programs. If you need thread support, in addition to linking your program with the camlTemplate library, you must also link in camlTemplate_mt.cmo (for bytecode programs) or camlTemplate_mt.cmx (for native-code programs). This ensures that the following are true:

4.5  Error Handling

The get_template function raises Syntax_error if it cannot parse a template. It may also raise other exceptions if it fails to read template source code because of an I/O error.

If a template cannot be merged because of a run-time error (e.g. a wrong data type), the merge function raises Template_error.

If a Caml function called from a template is unable to complete successfully, it can raise Tfun_error; this causes merge to raise Template_error.


Previous Up Next