简体   繁体   中英

Grails: Asset Pipeline and GSP Templates

I've switched from using the Resources plugin to the new Asset Pipeline plugin. However, I've come across an issue that I'm not sure how to fix.

I use several templates (ie: _template.gsp) that are included via the g:render tag from other GSP files.

_template.gsp:

<%@ page contentType="text/html;charset=UTF-8" %>
<asset:stylesheet src="_template.css"/>
<asset:javascript src="_template.js"/>
<div>
...
</div>

other GSP files:

...
<g:render template="/template"/>
...

In my _template.gsp file I include several assets that are required for the code in the template to work and/or look right. When I used the resources plugin to accomplish this, things worked as expected. Any files included in templates were moved to the HEAD section of the resulting GSP file. However, with the Asset Pipeline plugin, they stay in the same location where the template was included in the calling GSP file. And to make things worse, they aren't processed correctly, so they aren't loaded correctly in the resulting HTML file.

For example, in debug the resulting HTML file looks like this

...
<link rel="stylesheet" href="/assets/_template.css?compile=false"/>
<script src="/assets/_template.js?compile=false" type="text/javascript"></script>
<div>
...
</div>
...

and everything works (although the file ideally should be loaded in the HEAD section like it used to when using the Resources plugin).

In production the resulting HTML file looks like:

...
<link rel="stylesheet" href="/assets/_template.css"/>
<script src="/assets/_template.js" type="text/javascript"></script>
<div>
...
</div>
...

however, in production all other included assets (files included in the actual GSP file) have longer filenames that look like styles-6a85c6fa983d13b6f58e12b475e9d35c.css. The _template.css and _template.js files from the template isn't being converted to one of these long filenames and if I try to access the /assets/styles.css path I simply get a blank page.

I was able to solve the first part of my problem (the assets not being in the HEAD) by creating the following tag library:

class TemplateAssetsTagLib
{
  // Define the namespace and encoding
  static namespace = 'tasset'
  static defaultEncodeAs = 'raw'

  // Tag called to move the content of this tag to where the assets tag is located (usually the HTML HEAD section)
  def head = { attrs, body ->
    // Get any existing asset blocks
    def assetBlocks = request.getAttribute('templateAssetBlocks')
    if(!assetBlocks)
      assetBlocks = []

    // Add the body of this tag to the asset blocks list
    assetBlocks << body()
    request.setAttribute('templateAssetBlocks', assetBlocks)
  }

  // Tag called to load any content that was saved using the head tag
  def assets = { attrs ->
    // Get all existing asset blocks
    def assetBlocks = request.getAttribute('templateAssetBlocks')
    if(!assetBlocks)
      return

    // Output the asset blocks
    assetBlocks.each { assetBlock ->
      out << assetBlock
    }
  }
}

It's mirrored after the Asset Pipeline deferred script functionality, but more generic.

And I've been able to solve the second problem by simply renaming the assets and removing the leading underscore. For some reason assets with a leading underscore don't get compiled during WAR creation and therefore aren't accessible in production mode.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM