seethrough

A simple XML/XHTML templating system for Erlang

Please note: while the examples below still hold, seethrough has progressed quite a bit in the last months. Watch this space for updated docs.

Input


<html xmlns="http://www.w3.org/1999/xhtml" 
      xmlns:e="http://hyperstruct.net/seethrough">
  <head>

    <title e:content="title"/>
  </head>
  <body>
    <h1 e:content="title"/>

    <h2>
      <e:attr name="style">font-weight: bold;</e:attr>

      <e:attr name="align"><span e:replace="alignment"/></e:attr>
      <e:attr name="bgcolor" value="background_color"/>
      <span e:replace="subtitle"/>
    </h2>

    <div e:condition="error">

      There was an error processing this directive.
    </div>

    <table>
      <thead>
        <tr>
          <th>Address</th>

          <th>Name</th>
        </tr>
      </thead>
      <tbody>
        <tr e:repeat="crew">

          <td e:content="address"/>
          <td e:content="name"/>
        </tr>
      </tbody>
    </table>
  </body>

</html>

Processing


test() ->
    io:format(
      seethrough:apply_template("test.html", 
          [{title, "Space"},
           {alignment, "center"},
           {subtitle, {?MODULE, get_subtitle, []}},
           {background_color, "blue_skies"},
           {crew, {? MODULE, get_crew, []}}])).

get_subtitle() ->
    "The final frontier...".

get_crew() ->

    [[{address, "kirk@enterprise.glx"},
      {name, "Jim"}],
     [{address, "spock@enterprise.glx"},
      {name, "Spock"}],
     [{address, "mccoy@enterprise.glx"},
      {name, "Doc"}]].

Output


<?xml version="1.0"?>
<html xmlns:e="http://dev.hyperstruct.net/seethrough" xmlns="http://www.w3.org/1999/xhtml">
  <head>

    <title>Space</title>
  </head>
  <body>
    <h1>Space</h1>

    <h2 style="font-weight: bold;" align="center" bgcolor="blue_skies">

      The last frontier...
    </h2>

    <table>
      <thead>
        <tr>

          <th>Address</th>
          <th>Name</th>
        </tr>
      </thead>
      <tbody>

        <tr>
          <td>kirk@enterprise.glx</td>
          <td>Jim</td>
        </tr><tr>

          <td>spock@enterprise.glx</td>
          <td>Spock</td>
        </tr><tr>
          <td>mccoy@enterprise.glx</td>

          <td>Doc</td>
        </tr>
      </tbody>
    </table>
  </body>

</html>

Caching

If you are going to render the same template within multiple environments, you’ll want to do the parse/compile step only once, keep the result around, and use that for rendering.


%% Parsing
{XMLTree, _Misc} = xmerl_scan:file(File),
Intermediate = seethrough:visit(XMLTree),

%% Rendering intermediate form within Env1
Render1 = seethrough:render(Intermediate, Env1),
xmerl:export_simple(lists:flatten([Render1]), xmerl_xml,
                    [#xmlAttribute{name = prolog, value = ""}]).

%% More rendering, but within Env2
Render2 = seethrough:render(Intermediate, Env2),
xmerl:export_simple(lists:flatten([Render2]), xmerl_xml,
                    [#xmlAttribute{name = prolog, value = ""}]).

%% Yet more rendering, within Env3
Render3 = seethrough:render(Intermediate, Env3),
xmerl:export_simple(lists:flatten([Render3]), xmerl_xml,
                    [#xmlAttribute{name = prolog, value = ""}]).



Supported tags

  • e:attr
  • e:include

Supported attributes

  • e:content
  • e:replace
  • e:repeat
  • e:condition

Source

Notes

seethrough does not depend on any framework, just plain old result = fn(args), so it should be very easy to use it in any context you want.

At less than 200 lines of actual code, it should also be pretty hackable.

seethrough is released under the BSD license.

Syndicate content