Search code examples
collectionsfilteringstringtemplate

Filtering a multivalued attribute in StringTemplate


I have a template which uses the same multivalued attribute in various places. I often find myself in a situation where I would like to filter the attribute before a template is applied to the individual values.

I can do this:

<#col:{c|<if(cond)><# c.Attribute2 #><endif>};separator=\",\"#>

but that is not what I want, because then there are separators in the output separating "skipped" entries, like:

2,4,,,6,,4,5,,

I can modify it to

<#col:{c|<if(c.Attribute1)><# c.Attribute2 #>,<endif>};separator=\"\"#>

Which is almost OK, but I get an additional separator after the last number, which sometimes does not matter (usually when the separator is whitespace), but sometimes does:

2,4,6,4,5,

I sometimes end up doing:

<#first(col):{c|<if(cond)><# c.Attribute2 #><endif>};separator=\"\"#>
<#rest(col):{c|<if(cond)>,<# c.Attribute2 #><endif>};separator=\"\"#>

But this approach fails if the first member does not satisfy the condition, then there is an extra separator in the beginning:

,2,4,6,4,5

Can someone give me a better solution?


Solution

  • First, let me point out that I think you are trying to do logic inside your template. Any time you hear things like "filter my list according to some condition based upon the data" it might be time to compute that filtered list in the model and then push it in. That said something like this might work where we filter the list first:

    <col:{c | <if(c.cond)>c<endif>}:{c2 | <c2.c.attribute>}>
    

    c2.c accesses the c parameter from the first application