JavaDev
JavaDev

Reputation: 442

Custom tag g.each conflicts each closure

I have a custom tag because I want to wrap g:each

def myEach = { attrs, body ->
    out << "${g.each(in:attrs.in, var:attrs.var, status:attrs.status) { 'test' }}"
}

But the each tag gets error because it is confused with the closure each. Any way I can do this? Worst case is I will output a gsp page that contains the each tag.

Upvotes: 2

Views: 387

Answers (3)

James Kleeh
James Kleeh

Reputation: 12228

You can absolutely register your own tag the same way Grails does:

import org.apache.commons.lang.StringUtils;
import org.codehaus.groovy.grails.web.taglib.GroovySyntaxTag;
import org.codehaus.groovy.grails.web.taglib.exceptions.GrailsTagException;

public class Whatever extends GroovySyntaxTag {

    public static final String TAG_NAME = "youreach";

    public void doStartTag() {
        String in = attributes.get(ATTRIBUTE_IN);
        if (StringUtils.isBlank(in)) {
            throw new GrailsTagException("Tag [" + TAG_NAME + "] missing required attribute [" + ATTRIBUTE_IN + "]", parser.getPageName(), parser.getCurrentOutputLineNumber());
        }

        doEachMethod(in);
    }

    public void doEndTag() {
        endEachMethod();
    }

    public String getName() {
        return TAG_NAME;
    }

    @Override
    public boolean isKeepPrecedingWhiteSpace() {
        return true;
    }

    @Override
    public boolean isAllowPrecedingContent() {
        return true;
    }
}

Then in Bootstrap.groovy, register this class as a tag.

    GrailsTagRegistry.instance.registerTag(Whatever.TAG_NAME, Whatever.class)

You can create your own class that extends GroovySyntaxTag to manipulate any methods there. Then have this class extend that instead.

Upvotes: 1

Igor Artamonov
Igor Artamonov

Reputation: 35951

UPDATE If you want to call standard tag, just try to call it, like:

  //ApplicationTagLib g

  def myEach = { attrs, body ->
    out << g.each([in:attrs.in, var:attrs.var, status:attrs.status]) {
      'test'
    }
  }

OLD

If you want to put a string into output, try to use standard String, not GroovyString. Not "${g.each....}", but '${g.each....}':

out << '${g.each(in:attrs.in, var:attrs.var, status:attrs.status) { \'test\' }}'

Or just escape $:

out << "\${g.each(in:attrs.in, var:attrs.var, status:attrs.status) { 'test' }}"

Upvotes: 1

user800014
user800014

Reputation:

It's possible that I'm missing something, but single quotes didn't help, example:

def myEach = { attrs, body ->
    out << "${g.'each'(in:attrs.in, var:attrs.var, status:attrs.status) { 'test' }}"
}

With that you will get the same error...

My solution is to use groovyPagesTemplateEngine bean. With that you can parse a String template:

def myEach = { attrs, body ->
    attrs.content = "test"
    String template = "<g:each in='${attrs.in}'>${attrs.content}</g:each>" 
    groovyPagesTemplateEngine.createTemplate(template, 'mytemplate').make([attrs:attrs]).writeTo(out)
}

Upvotes: 2

Related Questions