Announcement Announcement Module
Collapse
No announcement yet.
Unfortunate freemarker/spring integration problem Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Unfortunate freemarker/spring integration problem

    I am in the process of moving from Velocity to Freemarker and have just come across a problem.

    Freemarker only allows hash-keys of type String. Spring however, uses hash-maps to hold the data being passed to the formSingleSelect macro (and others) It is fairly common then, to have a set of options that have been pulled from a database with the ID as key and other data as the value. For example you may have a list of countries in the database:

    Code:
    (key -> value)
    
    97 -> 'Finland'
    98 -> 'United Kingdom'
    99 -> 'United States'
    However, if you then try to pull a value in your FTL template:

    Code:
    ${countries[97]}
    You'll get an error. Equally, trying to use the spring macros will produce an error as it tries to do the same internally.

    Does anyone know if there is a workaround or fix for this problem. I have been able to workaround Maps that are produced by the web-tier by using a string representation of the integer as keys for the map, but when objects (in particular - complex object trees) are pulled back from the middleware it can cause some real problems.

    I am using Spring 1.2.1 and Freemarker 2.3.2

    Any help gratefully appreciated!
    Matt

  • #2
    Edit spring.ftl's checkSelected

    Its a little verbose, but this change will properly compare a "12" (string) to 12 (number):

    Code:
    <#macro checkSelected value>
            <#if stringStatusValue?is_string && value?is_number && stringStatusValue?number == value       >selected="selected"</#if>
            <#if stringStatusValue?is_number && value?is_string && stringStatusValue        == value?number>selected="selected"</#if>
            <#if stringStatusValue?is_string && value?is_number && stringStatusValue?number == value       >selected="selected"</#if>
            <#if stringStatusValue?is_number && value?is_string && stringStatusValue        == value?number>selected="selected"</#if>
    </#macro>
    I also went down into the formRadioButtons macro and updated the
    Code:
    <#if stringStatusValue == value>checked="checked"</#if>
    to look utilize that method:
    Code:
     <@checkSelected value/>
    In order to use this new spring.ftl file I named it "spring2.ftl" and changed all my calls to spring.ftl to the new name. If it works for you I'll submit it as a patch to spring.ftl.

    Comment


    • #3
      Didn't address your problem of non-string keys though

      I was manually setting my maps in the HTML like so:
      Code:
      <@spring.formSingleSelect "command.hours", &#123; "12"&#58;12, "24"&#58;24 &#125;, "<br/>"/>
      Whereas you're getting the values out of the database.

      You can probably get around this Freemarker behavior by subclassing the view.FreeMarkerView spring class and overriding the processTemplate method such that you muck around with the model by changing all Integer keys to Strings before you render the view. Then just update your spring configuration telling the FreeMarkerViewResolver to use your new class instead of the default FreeMarkerView.

      Comment


      • #4
        Re: Edit spring.ftl's checkSelected

        Originally posted by cwilkes
        Its a little verbose, but this change will properly compare a "12" (string) to 12 (number)
        Thanks very much for looking at this. It seems however, that the change to the checkSelected macro isn't required.

        I tried making a form that uses a command object with an int property named myOption. In the SimpleFormController's referenceData method I create a map named optionsMap containing a series of String keys ("1", "2", "3" etc.) and some arbitrary values ("Something 1", "Something 2" ...)

        In the form I use

        Code:
        <@spring.formSingleSelect path="command.myOption" options="optionsMap"/>
        The int property gets converted to and from a String for use within the form without problems - the Spring macros all seem to work fine just as they are.

        The problem is when having non-String keys in the Map as I stated before. I've a nasty feeling the only way this will change is if Freemarker's SimpleHashMap starts to support non-String keys. Everything else about Freemarker seems great so far.

        Comment


        • #5
          I think the problem is specific to spring.ftl's formRadioButtons

          unlike the formSingleSelect, it uses:
          <#if stringStatusValue == value>checked="checked"</#if> ${attributes}

          whereas formSingleSelect uses the nice checkSelected.

          <option value="${value}"<@checkSelected value/>>${options[value]}</option>



          In my code that uses radio's I create my own macro to get around this:
          <#macro radioCheckSelected value>
          <#if spring.stringStatusValue?is_number && spring.stringStatusValue == value?number>checked</#if>
          <#if spring.stringStatusValue?is_string && spring.stringStatusValue == value>checked</#if>
          </#macro>
          <#macro myFormRadioButtons path options separator attributes="">
          <@spring.bind path/>
          <#list options?keys as value>
          <input type="radio" id="${spring.status.expression}" name="${spring.status.expression}" value="${value}"
          <@radioCheckSelected value/> ${attributes}
          <@spring.closeTag/>
          ${options[value]}${separator}
          </#list>
          </#macro>
          Last edited by jdwyah; Apr 17th, 2006, 07:01 PM.

          Comment

          Working...
          X