在Grails custom taglib中查找父标记

时间:2015-06-26 15:27:17

标签: grails groovy gsp taglib

我正在开发Grails中的自定义taglib,它应该知道父标记。所以如果我在GSP中有类似的东西:

<a href="#">
  <my:tag blabla="blabla"/>
</a>

然后我的:标签的实现应该能够发现它被包含在标签&#39; a&#39;而不是别的什么 这可能是:
1.找出哪个标签是父母?
2.更改父标签属性?

1 个答案:

答案 0 :(得分:0)

编辑 - 这里的答案没有回答问题。请参阅注释以获得解释。我将在这里留下答案,因为删除它会使所有其他评论难以理解,但这里的答案不是问题的有效答案。对不起,我很抱歉。

没有一种改变父标签属性的好方法,但无论如何这都不是一个好主意。几乎可以肯定有一种更好的方法可以实现让你想要做到的事情。但是,想要知道标记是否嵌套在另一个特定标记中是一件非常合理的事情,并且有简单的方法可以做到这一点。一种方法是您的父标记可以在pageScope中存储一些状态,并且子标记可以询问该值以确定它是否在父内部被调用。您可以使用布尔标志,但如果您担心多个嵌套级别,则会出现问题。计数器可以跟踪任意深度。

以下内容应该有效。

TagLib:

// grails-app/taglib/demo/DemoTagLib.groovy
package demo

class DemoTagLib {

    static namespace = 'demo'

    def someParentTag = { attrs, body ->
        def depthCounter = pageScope.someParentTagDepthCounter ?: 0
        pageScope.someParentTagDepthCounter = ++depthCounter

        out << body()

        pageScope.someParentTagDepthCounter = --depthCounter
    }

    def someChildTag = { attrs, body ->
        // This tag will only render its body if the tag invocation
        // is nested inside of a someParentTag parent.  This just
        // demonstrates one way that a tag can discover if it is
        // nested inside of some other specific tag.
        if(pageScope.someParentTagDepthCounter) {
            out << body()
        }
    }
}

单元测试:

// src/test/groovy/demo/DemoTagLibSpec.groovy
package demo

import grails.test.mixin.TestFor
import spock.lang.Specification

@TestFor(DemoTagLib)
class DemoTagLibSpec extends Specification {

    void "test something"() {
        expect: 'when someChildTag is not wrapped in someParentTag then the someChildTag body is not rendered'
        applyTemplate('Heading <demo:someChildTag>Body</demo:someChildTag>') == 'Heading '

        and: 'when someChildTag is wrapped in someParentTag then the someChildTag body is rendered'
        applyTemplate('Heading <demo:someParentTag><demo:someChildTag>Body</demo:someChildTag></demo:someParentTag>') == 'Heading Body'

        and: 'when multiple someChildTags are nested in multiple levels of someParentTags, their bodies are rendered'
        applyTemplate('Heading <demo:someParentTag><demo:someChildTag>First Child<demo:someParentTag> <demo:someChildTag>Second Child</demo:someChildTag></demo:someParentTag></demo:someChildTag></demo:someParentTag>') == 'Heading First Child Second Child'
    }
}

我希望有所帮助。