Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing a List of Objects to Freemarker and then Looping

I've been acquainting myself with FreeMarker, a template engine for Java.

I got to the point where I am able to pass an object to the template engine through a Hash Map. That works alright. But as soon as I try to pass any sort of set of multiple objects to FreeMarker it gives me a freemarker.template.TemplateException and complains that it "Expected collection or sequence. jobs evaluated instead to freemarker.template.SimpleHash".

From what I understand from reading up on this in the various resources, this is to be expected.

Now, I have done much of the leg work and found a number of people commenting on how to get around this. But, quite frankly, (a) for many of the examples it was unclear as to how exactly their advice applies in my case--even though I've known Java basics for quite a while I'm pretty new to some of the architecture pertaining to Java web apps and (b) I'm confused as to which of the approaches was the best approach.

All I want to do, at the most simplified level, is basically this:

  1. I have a simple Servlet.

  2. I have a simple class (for this example named Invoice) with a few methods and properties.

  3. I want to have my servlet (in some fashion) present a list/array/sequence/hashmap of instances of these objects (or views of those objects) via FreeMarker's process method.

  4. I want to have my .ftl template do a loop through the list/array/sequence/hashmap and display method results, something like this:

< # list invoices as invoice>  Invoice note: ${invoice.getNote()}, Invoice Amount:${invoice.getAmount()}  < / # list> 

Now, I'm not necessarily looking for the quick & dirty solution to this. I'm new to FreeMarker, but I want to do this in the proper way that is elegant and good design. So I'm open to completely rethinking this approach. Can someone help me see what I need to do to get something like this to work?

like image 371
Mark Nenadov Avatar asked May 12 '11 16:05

Mark Nenadov


People also ask

How do you create a list on FreeMarker?

FreeMarker doesn't support modifying collections. But if you really want to do this in FreeMarker (as opposed to in Java), you can use sequence concatenation: <#assign myList = myList + [newItem]> . Here you create a new sequence that wraps the two other sequences.

What is velocity and FreeMarker?

Velocity and FreeMarker are two templating languages that can both be used as view technologies within Spring MVC applications. The languages are quite similar and serve similar needs and so are considered together in this section.

What is C in FreeMarker?

c (when used with numerical value) This built-in converts a number to string for a "computer language" as opposed to for human audience. That is, it formats with the rules that programming languages used to use, which is independent of all the locale and number format settings of FreeMarker.


1 Answers

Is "jobs" really a collection? Please post a snippet of code where you are creating and processing your template.

I just wrote a quick test to check:

public void testFreeMarker() throws Exception {      List<Invoice> invoices = Arrays.asList(        new Invoice( "note1", "amount1" ),         new Invoice( "note2", "amount2" ) );     Map<String, Object> root = new HashMap<String, Object>();     root.put( "invoices", invoices );     StringWriter out = new StringWriter();      Configuration cfg = new Configuration();     cfg.setClassForTemplateLoading( FreemarkerUtils.class, "/templates" );     cfg.setObjectWrapper( new DefaultObjectWrapper() );     Template temp = cfg.getTemplate( "listTest.ftl" );     temp.process( root, out );      System.out.println( out.getBuffer().toString() ); } 

The template is just:

<#list invoices as invoice>  Item: ${invoice.note} - ${invoice.amount} </#list> 

The result is as expected:

Item: note1 - amount1 Item: note2 - amount2 
like image 123
st.never Avatar answered Sep 17 '22 20:09

st.never