简体   繁体   中英

How do I tell free marker to skip a <sep> directive in a list iteration?

I am trying to iterate over a JSON object in a <#list> iteration in Freemarker and write out the same JSON in a different form. For some conditions, I'd like to skip over the iteration and not write out anything, but Freemakrer still writes out the comma because I use the separator directive: <#sep>,</#sep> .

For example

"<#list .data_model as key, value>" +
    "<#if key == 'someVal1' || key == 'someVal2' || value?is_hash>" + //do nothing for these
    "<#else>" +
        "\"${key}\":\"${value?json_string?json_string}\"<#sep>,</#sep>" +
    "</#if>" +
"</#list>"

The output is something like:

{"aval1":"1",,"aval2":["item"], ...}

Notice the duplicate commas.

In other places I have implemented some special logic where I write out a comma for the previous item, so long as the current item is not the first item. The logic works but seems weird to have to duplicate.

Are there any Freemarker built-ins for this kind of situation?

<#sep> (and ?has_next , ?index , etc.) assumes that you will render all the items in the value that you list. Specifically, #sep decides based on if there will be a next item, and not based on if there was a previous item. (Looking back doesn't work in general, as you can't always postpone printing the separator for the next iteration, like consider <#sep>,</#sep></span> .) So either you pre-filter that map in Java, or you will need a variable to keep track if an element was already printed, and then print the separator before the current item.

BTW, 2.3.29 (released within a week) has ?filter to address this kind of problem, however, that only supports filtering list-like values for now, not map-like values yet (maybe in 2.3.30). So even with 2.3.29 you had to list the keys, and then get the value by key in the filter expression and then inside the nested content... not very nice.

Found a way to work around:

"<#assign x=false><#list .data_model as key, value>" +
"<#if key == 'someVal1' || key == 'someVal2' || value?is_hash>" + //do nothing for these
"<#else>" +
    "<#if x>,</#if>\"${key}\":\"${value?json_string?json_string}\"<#assign x=true>" +
"</#if>" +
"</#list>"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM