Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I access images from Javascript using Grails Asset-Pipeline plugin?

I have just upgraded to Grails 2.4 and am using the Asset-Pipeline1.8.7 plugin. I am wondering how to access the images from Javascript. I am using the Google Maps Javascript V3 API and need to set some marker icons in Javascript. Is there a way to create some Javascript vars on a GSP using the tag and then access the file in my app.js code? If that is not possible, how do a reference the compiled images in assets?

like image 964
Scott Griz Avatar asked Jun 04 '14 22:06

Scott Griz


3 Answers

I don't know what the ideal solution is in your case but a solution might be:

  1. Use relative paths like '../assets/use-control.png' in your js code.
  2. Add the img in your dom and reference it from your js code.
  3. Add a data-imgpath="${asset.assetPath(src: 'use-control.png')}" attribute on an appropriate element in your dom and use this link.
like image 112
jgeerts Avatar answered Nov 18 '22 04:11

jgeerts


You could define a globally available object that holds the root-path to your assets dir and use this to build-up URLs to your assets. Add this snippet to your layouts head-section

<g:javascript>
    window.grailsSupport = {
        assetsRoot : '${ raw(asset.assetPath(src: '')) }'
    };
</g:javascript>

Then use it elsewhere like this:

<g:javascript>
    var pathToMyImg = window.grailsSupport.assetsRoot + 'images/google_maps_marker.png';
</g:javascript>

Update 2015-08-06

While checking the release notes of the asset-pipeline plugin I noticed that non-digest versions of assets are no longer stored in the WAR-file. This would mean that my proposed solution breaks when the application is deployed as a WAR:

May 31, 2015 2.2.3 Release - No longer storing non digest versions in war file, cutting overhead in half. Also removed Commons i/o dependency. Faster byte stream.

This means that you have to explicitly define all your images beforehand and are no longer able to construct the path dynamically in your scripts:

<g:javascript>
    window.grailsSupport = {
        myImage1 : '${assetPath(src: 'myImage1.jpg')}',
        myImage2 : '${assetPath(src: 'myImage2.jpg')}'
    };
</g:javascript>    

Update 2016-05-25

It is now possible to configure if non-digest versions of the assets are included in the built war-file by setting grails.assets.skipNonDigests (default is false):

It is normally not necessary to turn off 'skipNonDigests'. Tomcat will automatically still serve files by non digest name and will copy them out using storagePath via the manifest.properties alias map. This simply cuts storage in half. However, if you are attempting to do things like upload to a cdn outside of the cdn-asset-pipeline plugin and via the contents of 'target/assets'. This may still be useful.

Note that you still might use the proposed solution to define all required images beforehand to work around caching issues in the browser (as the digest-version of the asset has its content-hash in the filename).

like image 36
Clemens Sum Avatar answered Nov 18 '22 04:11

Clemens Sum


Yes you can by putting a ${assetPath(src: 'img.png')} in your gsp

like image 10
davydotcom Avatar answered Nov 18 '22 03:11

davydotcom