Grails 5 change: how to inject taglib into Controller
You can inject a taglib using its bean name like any other bean but there is no good reason to do that. The technique you show in the question is the recommended approach. We effectively add a namespace variable to your controllers which allow you to invoke tag lib implementations as if they were methods. That approach makes more sense than injecting a taglib.
See the project at https://github.com/jeffbrown/treblataglib.
https://github.com/jeffbrown/treblataglib/blob/8f6d46aa2d227ddb34dfa6adfa50d03b270ddd70/app/grails-app/controllers/app/DemoController.groovy
package app
class DemoController {
def index() {
render someNamespace.sometag()
}
}
https://github.com/jeffbrown/treblataglib/blob/8f6d46aa2d227ddb34dfa6adfa50d03b270ddd70/helper/grails-app/taglib/helper/HelperTagLib.groovy
package helper
class HelperTagLib {
static namespace = 'someNamespace'
def sometag = { attrs ->
out << 'This came from HelperTagLib.someTagLib'
}
}
That appears to work:
~ $ mkdir working
~ $
~ $ cd working
working $
working $ git clone git@github.com:jeffbrown/treblataglib.git
Cloning into 'treblataglib'...
remote: Enumerating objects: 145, done.
remote: Counting objects: 100% (145/145), done.
remote: Compressing objects: 100% (98/98), done.
remote: Total 145 (delta 23), reused 145 (delta 23), pack-reused 0
Receiving objects: 100% (145/145), 860.12 KiB | 3.41 MiB/s, done.
Resolving deltas: 100% (23/23), done.
working $
working $ cd treblataglib
treblataglib (main)$
treblataglib (main)$ ./gradlew app:bootRun
> Task :app:bootRun
Grails application running at http://localhost:8080 in environment: development
<============-> 95% EXECUTING [26s]
> :app:bootRun
Output:
~ $ http :8080/demo
HTTP/1.1 200
Connection: keep-alive
Content-Type: text/html;charset=utf-8
Date: Mon, 08 Aug 2022 18:05:14 GMT
Keep-Alive: timeout=60
Transfer-Encoding: chunked
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
This came from HelperTagLib.someTagLib
EDIT:
A comment below indicates that the problem manifests when a plugin is using a namespaced taglib from another plugin. I have updated the linked project to represent that (https://github.com/jeffbrown/treblataglib/commit/53de85ef7073b8f428ccf0e785097509ed966376).
app
depends on another-helper
, another-helper
depends on helper
. helper
provides a namespaced taglib. DemoController
in another-helper
uses that namespaced plugin.
When run the app using Gradle it seems to work. When I build the war, that seems to work as well.