Is it possible to have freemarker's <#spring.showErrors to display errors in a div instead of span - validation

Code:
<#spring.formInput 'myForm.spouseEmail' 'id="spouseEmail" class="text"'/>
<#spring.showErrors ', ' 'error'/>
Output:
<span class="error">not a well-formed email address</span>
What I want:
<div class="error">not a well-formed email address</div>

#Mike: it seems you have troubles understanding the nature of macros. They are already-written freemarker script to make your life easier. You can always write a customed one.
Some people think it obvious, but I myself find that it's not easy to know how to view the spring-freemarker macros source code. You can navigate to package org/springframework/spring-webmvc-3.0.5.jar/org/springframework/web/servlet/view/freemarker/spring.ftl in Eclipse's "Referenced Libraries".
Here's the macro "showErrors" gotten from "spring.ftl":
<#macro showErrors separator classOrStyle="">
<#list status.errorMessages as error>
<#if classOrStyle == "">
<b>${error}</b>
<#else>
<#if classOrStyle?index_of(":") == -1><#assign attr="class"><#else><#assign attr="style"></#if>
<span ${attr}="${classOrStyle}">${error}</span>
</#if>
<#if error_has_next>${separator}</#if>
</#list>
</#macro>
To achieve your goal, it's very simple: just write a custom macro which is exactly like the code above, replace span by div

No, but you can easily write your own macro to do whatever you want. Get your inspiration from spring.showErrors itself.

Related

Check if FreeMarker #nested directive is empty

I want to output tags around a <#nested> directive in a macro, but only if it would actually output something. The actual use case is more complicated, this is just the broken down version.
How do I check for existence of <#nested> content?
<#macro opt tagname>
<#if (#nested)??> <-- what do I need to put here
<${tagname}>
<#nested>
</${tagname}>
</#if>
</#macro>
Example 1
Template: <#opt hello />
Output: (empty)
Example 2
Template: <#opt hello>goodbye</#opt>
Output: <hello>goodbye</hello>
You have to capture the nested content, and then print it if necessary. Like this (this assumes auto-escaping on):
<#macro opt tagname>
<#local nestedContent><#nested></#local>
<#if nestedContent?has_content>
<${tagname}>${nestedContent}</${tagname}>
</#if>
</#macro>
Without auto-escaping the #if changes to just <#if nestedContent != ''>.

Spring Freemarker Form Bind : Problem with Exponent Value

I have Spring bind form with freemarker. But large number show Exponent value. How to show value without Exponent.
For small numeber...
<#spring.formInput 'CaseMaster.year' 'placeholder="e.g. 2013" ' 'number'/>
For large number...
<#spring.formInput 'CaseMaster.suitValue' 'placeholder="e.g. Suit Value" ' />
HTML View:
I wnat to show value like 80000000 or 80000000.00 or like 8,00,00,000.00 in the second field.
I've dug down into the macro and it looks like you have no control over the formatting to the populated value. Perhaps there's a more elegant solution, but at this point, you might try creating your own macro that gives you formatting control. (This is untested.)
<#macro numberInput path attributes="">
<#spring.bind path/>
<input type="text"
id="${status.expression?replace('[','')?replace(']','')}"
name="${status.expression}" value="status.value?c" ${attributes}<#closeTag/>
</#macro>
You would call it like this:
<#numberInput 'CaseMaster.suitValue' 'placeholder="e.g. Suit Value" ' />

How to DUMP object in freemarker ( .ftl )

is there a way how to dump whole object and write it somewhere?
Like:
var_dump() in php
console.log in JS
I found something like list, so I try something like this below:
<#list calculation as c>
${c}
</#list>
But template fall with error. I appriciate any advise!
It depends on the type of object you are iterating through. You can check the type of data your variable is and then output it appropriate (Reference: http://freemarker.incubator.apache.org/docs/ref_builtins_expert.html#ref_builtin_isType)
Here are some examples:
<#if calculation?is_sequence>
<#list calculation as c>
${c}
</#list>
<#elseif calculation?is_hash_ex>
<#list calculation?keys as key>
${key} - ${calculation[key]}
</#list>
<#elseif calculation?is_string>
${calculation}
</#if>
Take a look at https://github.com/ratherblue/freemarker-debugger/blob/master/debugger.ftl for more examples on dumping data

does freemarker support show all variable in data-model?

I want to see all variables in freemarker data-model, just like struts2 debug tag to show value stack.
Is there a way for freemarker to do this ?
There's no universal solution possible for that, but you can try
<#list .data_model?keys as key>
${key}
</#list>
This works if the data-model is just a usual Map or JavaBean, but for more sophisticated data-models it's up to the data-model implementation if it supports ?keys and if it indeed returns everything.
You also have the variables that you set in the templates, which can be listed like above, only instead of .data_model use .globals, .namespace (which means the current template namespace) and .locals.
You may also have Configuration-level shared variables, and there's no way to list those purely from FTL (you could write a custom TemplateMethodModel for it that reads Configuration.getSharedVariableNames() though, and call it from the template).
Of course, ideally, FreeMarker should have a <#show_variables> directive or something, that does a best effort to show all this... but sadly there is no such thing yet.
An even more detailed way would be this macro:
<#macro dump_object object debug=false>
<#compress>
<#if object??>
<#attempt>
<#if object?is_node>
<#if object?node_type == "text">${object?html}
<#else><${object?node_name}<#if object?node_type=="element" && object.##?has_content><#list object.## as attr>
${attr?node_name}="${attr?html}"</#list></#if>>
<#if object?children?has_content><#list object?children as item>
<#dump_object object=item/></#list><#else>${object}</#if> </${object?node_name}></#if>
<#elseif object?is_method>
#method
<#elseif object?is_sequence>
[<#list object as item><#dump_object object=item/><#if !item?is_last>, </#if></#list>]
<#elseif object?is_hash_ex>
{<#list object as key, item>${key?html}=<#dump_object object=item/><#if !item?is_last>, </#if></#list>}
<#else>
"${object?string?html}"
</#if>
<#recover>
<#if !debug><!-- </#if>LOG: Could not parse object <#if debug><pre>${.error}</pre><#else>--></#if>
</#attempt>
<#else>
null
</#if>
</#compress>
</#macro>
<#dump_object object=.data_model/>
This gives you a full dump of your data model.
Here is #lemhannes macro definition modified to emit JSON. Lightly tested on a fairly simple datamodel
<#macro dump_object object debug=false>
<#compress>
<#if object??>
<#attempt>
<#if object?is_node>
<#if object?node_type == "text">${object?json_string}
<#else>${object?node_name}<#if object?node_type=="element" && object.##?has_content><#list object.## as attr>
"${attr?node_name}":"${attr?json_string}"</#list></#if>
<#if object?children?has_content><#list object?children as item>
<#dump_object object=item/></#list><#else>${object}</#if>"${object?node_name}"</#if>
<#elseif object?is_method>
"#method"
<#elseif object?is_sequence>
[<#list object as item><#dump_object object=item/><#if !item?is_last>, </#if></#list>]
<#elseif object?is_hash_ex>
{<#list object as key, item>"${key?json_string}":<#dump_object object=item/><#if !item?is_last>, </#if></#list>}
<#else>
"${object?string?json_string}"
</#if>
<#recover>
<#if !debug>"<!-- </#if>LOG: Could not parse object <#if debug><pre>${.error}</pre><#else>-->"</#if>
</#attempt>
<#else>
null
</#if>
</#compress>
</#macro>

Add spring macro as parameter to Freemarker macro

I have the code snippet below, and want to give the output from <#spring.message "name"/> as paraneter to the macro (the placeholder parameter).
Providing it directly as I tried doing below didnt't work, anyone knows how I should do it?
<td class="rightCell"><b><#spring.message "name"/>:</b></td>
<td class="leftCell"><#createUserInputItemModifiedv2 "name", "name", "text", #spring.message "name" /></td>
<#macro createUserInputItemModifiedv2 attributeName, errorMessageName, inputType, placeholder>
<input class="edit" type="${inputType}" id="${attributeName}" name="${attributeName}" placeholder="${placeholder}" value="${user[attributeName]!}"/><br/>
<#if validationErrors?? && validationErrors[attributeName]??>
<div class="errorMessage" id="${errorMessageName}Error">
${validationErrors[attributeName]!}
</div>
</#if>
</#macro>
That's because spring.message should also be a FreeMarker function, not just a FreeMarker macro. Macros has no return value (they might directly print to the output writer as a side-effect) so you can't call them where an expression is expected. Anyway... how to work this around right now. Looking at the source code of Spring, maybe this will work:
<#function message code><#return springMacroRequestContext.getMessage(code)></#function>
You could create a utils.ftl or something, (auto-)#import it as u, and then you can do <#createUserInputItemModifiedv2 ..., u.message("name")> in your templates. (Actually, it could be made more convenient, so that you can just write msg.name or like, but let's not go into that here.)
However, I'm not sure if there's any backward compatibility guarantee regarding springMacroRequestContext or its content. So ultimately this should be fixed in Spring.

Resources