Search code examples
grailsgsp

r:external added via taglib is not processed as link in grails gsp


I am trying to add the r:external via taglib for dynamic resources to be included in GSP page.

tablib is included as given below in the GSP page

<html>
<head>
<g:layoutHead/>
<r:layoutResources />
<r:external uri="/css/mycss.css" type="css" />
<g:customStylesheetIncludes/>
</head>
<body>
<g:layoutBody/>
<r:layoutResources />
</body>
</html>

And my TabLib is as given below.

class MyResourcesTagLib {

    def customStylesheetIncludes = { attrs ->
        def controller = attrs.controller ?: controllerName
        def action = attrs.action ?: actionName

        writeCssIfExists( out, "css/my-custom.css" )

        // Determine the current page
        writeCssIfExists( out, "css/views/$controller/${action}-custom.css" )
    }

    private resourceExists( resPath ) {
        return grailsApplication.parentContext.getResource( resPath ).file.exists()
    }

    private writeCssIfExists( writer, css ) {
        if (resourceExists(css)) {
            def baseUri = grailsAttributes.getApplicationUri(request)

            writer << '<r:external uri="'
            writer << baseUri << (baseUri.endsWith('/') ? '' : '/')
            writer << css
            writer << '" type="css" />\n'
        }
    }
}

When I view the source of the rendered html page..

<link href="/ResourceApp/css/mycss.css" type="text/css" rel="stylesheet" media="screen, projection" />
<r:external uri="/ResourceApp/css/my-custom.css" type="css" />

Hardcoded r:external is converted to link but not the one that is added via tablib.


Solution

  • The issue you are having here is that you aren't calling the other tag library correctly from yours. You are simply writing out text to the output stream.

    For example the following lines:

     def baseUri = grailsAttributes.getApplicationUri(request)
    
     writer << '<r:external uri="'
     writer << baseUri << (baseUri.endsWith('/') ? '' : '/')
     writer << css
     writer << '" type="css" />\n'
    

    The above lines are simply appending text to the output stream. This text will not be processed any further by the server and will be sent to the client exactly as they appear.

    The solution is to call the other tag library and append the output of that call to the output stream.

    For example:

    def baseUri = grailsAttributes.getApplicationUri(request)
    baseUri += (baseUri.endsWith('/') ? '' : '/')
    
    writer << r.external(uri: baseUri, type: 'css')