Search code examples
templateserlangchicagoboss

Show some html in loop for each N element


I'm just learning Erlang with Chicago Boss and would like to know how could I do something similar to this (in pseudocode):

foreach (items as item)
    if (i % 10 == 0)
        <tr>
    endif
    <td>...</td>
    if (i++ % 10 == 0)
        </tr>
    endif
endforeach

in my template?


Solution

  • Erlang is functional language so idiomatic way is do it in functional way. We prepare function which will tabular your data first:

    -module(tabify).
    
    -export([tabify/2]).
    
    tabify(N, L) when is_list(L), is_integer(N), N > 0 ->
      tabify_(N, L).
    
    tabify_(_, []) -> [];
    tabify_(N, L) ->
      {Row, Rest} = row(L, N),
      [Row|tabify_(N, Rest)].
    
    row(L, N) ->
      row(L, N, []).
    
    row([], _, Accu) -> {lists:reverse(Accu), []};
    row(Rest, 0, Accu) -> {lists:reverse(Accu), Rest};
    row([H|T], N, Accu) -> row(T, N-1, [H|Accu]).
    

    And now we can use it in way:

    1> c(tabify).
    {ok,tabify}
    2> Data = [integer_to_list(X) || X <- lists:seq(1,100)].
    ["1","2","3","4","5","6","7","8","9","10","11","12","13",
     "14","15","16","17","18","19","20","21","22","23","24","25",
     "26","27","28",
     [...]|...]
    3> Table = tabify:tabify(10,Data).
    [["1","2","3","4","5","6","7","8","9","10"],
     ["11","12","13","14","15","16","17","18","19","20"],
     ["21","22","23","24","25","26","27","28","29","30"],
     ["31","32","33","34","35","36","37","38","39","40"],
     ["41","42","43","44","45","46","47","48","49","50"],
     ["51","52","53","54","55","56","57","58","59","60"],
     ["61","62","63","64","65","66","67","68","69","70"],
     ["71","72","73","74","75","76","77","78","79","80"],
     ["81","82","83","84","85","86","87","88","89","90"],
     ["91","92","93","94","95","96","97","98","99","100"]]
    4> T = [["<tr>", [["<td>", Item, "</td>"] || Item <- Row ], "</tr>"]|| Row <- Table].
    [["<tr>",
      [["<td>","1","</td>"],
       ["<td>","2","</td>"],
       ...
    

    And than let io subsystem do the rest. The structure above is well known as iolist and if you put it in any io it will be serialized properly in same way as:

    6> iolist_to_binary(T).
    <<"<tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td>9</td><td>10</td></tr><tr><t"...>>
    

    If you have thousands of items in table and efficiency is crucial for you can turn all lists constants into binary. You can also turn into binary data in Data. As last resort you can rewrite tabify/2 and formatting in more efficient but less readable way.