Search code examples
grailsgroovygsp

Evaluating expression inside GSP tags


I am trying to evaluate an expression in a GSP tag. Crudely put,

<g:form ${true ? 'name=\"hello\"' : ''}>

But the error I'm getting is:

Class: org.codehaus.groovy.grails.web.taglib.exceptions.GrailsTagException
Message: Attribute value must be quoted (${true ? 'name=\"hello\"' : ''}).

In one of the other views, the following expression (which is similar to the above one) works fine.

<li ${controllerName == null ? ' class=active' : ''}>

But it does not work with the form tag. I am using Grails 2.3.5. Any idea what I'm doing wrong?

Edit: I am having similar problems with this expression too.

<g:form url="[${multiple ? '' : 'resource:xyzInstance, '}action:'update']" method="PUT" >

Here, multiple is a boolean value. It works fine with an <g:if> tag.

<g:if test="${multiple}">

Solution

  • In Groovy double quotes must not be escaped inside single quote strings. The opposite also applies: single quotes must not be escaped inside double quote strings (known as GStrings, by the way)

    Try

    <g:form ${true ? 'name="hello"' : ''}>
    

    or

    <g:form ${true ? "name=\"hello\"" : ''}>
    

    Both will work.

    For the second part of the updated question I would recommend to build the map separately as it is not only going to work but your code is going to be easier to read and maintain. Something like:

    <%
    def urlMap = [action: 'update']
    if(multiple)
    urlMap.put 'resource', 'xyzInstance'
    %>
    <g:form url="${urlMap}" method="PUT">
    

    Be careful also with the types you use as values on some attributes, this has caused me some troubles sometimes:

    • 'a String'
    • "a GString with a ${dynamicValue}"
    • "[a GString that looks like a list]"
    • "${[a, list]}"
    • "${[a: map]}"
    • "false" <- This will always be evaluated to true, as it's a non-empty non-null GString
    • "${false}" <- Solution to the problem of the line above

    I hope all this solve your problems. For simplicity's sake I'd always recommend to keep value expressions as simple as possible, and if they need complex logic put it in a block immediately before the tag it's gonna benefit from it.