Using grailsLinkGenerator to generate link to images in bootstrap.groovy - grails

I'm trying to create a link to an image resource in my bootsrap file using the underdocumented grailsLinkGenerator class in Grails 2.0.3
I have successfully injected the service using
...
LinkGenerator grailsLinkGenerator
...
But the url generated by the following code is not correct
grailsLinkGenerator.resource(dir:'images', file:'1.jpg')
There are no errorsm and the path generated almost looks correct, except it is missing 'static' in the url. Am I using this wrong? Is there an alternative way to access your static resources in bootstrap?

Looking at the ApplicationTagLib source, you can see that g:resource uses linkGenerator only when the resources plugin is not installed.
Closure resource = { attrs ->
if (!attrs.pluginContextPath && pageScope.pluginContextPath) {
attrs.pluginContextPath = pageScope.pluginContextPath
}
// Use resources plugin if present, but only if file is specified - resources require files
// But users often need to link to a folder just using dir
return ((hasResourceProcessor && attrs.file) ? r.resource(attrs) : linkGenerator.resource(attrs))
}
So this is probably the reason that your links don't have the static path.
I don't think that's a good option to store the full link to the thumbnail in the database. If you change something in the structure you will need to update all links. You can store the name of the thumbnail (or use a convention) and let the link be generated in a TagLib that will be responsible to show them.
In the TagLib you can just use g:resource that will create the correct url's.

Related

Generate URL of resources that are handled by Grails AssetPipeline

I need to access a local JSON file. Since Grails 2.4 implements the AssetPipeline plugin by default, I saved my local JSON file at:
/grails-app/assets/javascript/vendor/me/json/local.json
Now what I need is to generate a URL to this JSON file, to be used as a function parameter on my JavaScript's $.getJSON() . I've tried using:
var URL.local = ""${ raw(asset.assetPath(src: "local.json")) }";
but it generates an invalid link:
console.log(URL.local);
// prints /project/assets/local.json
// instead of /project/assets/vendor/me/json/local.json
I also encountered the same scenario with images that are handled by AssetPipeline1.9.9— that are supposed to be inserted dynamically on the page. How can I generate the URL pointing this resource? I know, I can always provide a static String for the URL, but it seems there would be a more proper solution.
EDIT
I was asked if I could move the local JSON file directly under the assets/javascript root directory instead of placing it under a subdirectory to for an easier solution. I prefer not to, for organization purposes.
Have you tried asset.assetPath(src: "/me/json/local.json")
The assets plugin looks in all of the immediate children of assets/. Your local.json file would need to be placed in /project/assets/foo/ for your current code to pick it up.
Check out the relevant documentation here which contains an example.
The first level deep within the assets folder is simply used for organization purposes and can contain folders of any name you wish. File types also don't need to be in any specific folder. These folders are omitted from the URL mappings and relative path calculations.

how to load html files within the application in javafx

i am using jdk1.7.0_45 for building javafx project,loads pre created html site from my application,found passing this url file:///E:/web/index.html
but which is not my requirement,need to load from my app,so please tell me anyone,the folder name need to place in javafx app.
thanks
I'm assuming that the question is that you want to package a static HTML file with your application and display it in a WebView.
You can do it with code like this (Scala syntax but the meaning should be clear):
val url = getClass getResource "index.html"
webView.getEngine load url.toString
In this example, the index.html file (and any related content) must reside in the same package as the class of the code. E.g. if the class is mypackage.myapp.MyApp, the file must be in the mypackage.myapp package.
If your build system provides an e.g. resources folder, it would be good practice to use that for static content such as this. I.e., for this example, create a package mypackage.myapp in the resources folder and place the html file there.

How to know if a grails plugin is running standalone or when the plugin is installed into the application

Basically I want to retrieve the same value provided by the "pluginContextPath" variable used in a gsp but in a groovy class.
class {
String pluginCtx = $pluginContextPath
byte[] logo = grailsApplication.getParentContext().servletContext.getResource("${pluginCtx}images/myImage.jpg").bytes;
}
I know that I cannot use the $pluginContextPath variable in a groovy class, but I tried using something suggested in post but it gives me the dir full path
GrailsPluginUtils.pluginInfos.find { it.name == pluginName }.pluginDir
but what i want is what the pluginContextPath variable does
"When you run the plugin in development mode the link to the resource will resolve to something like /js/mycode.js. However, when the plugin is installed into an application the path will automatically change to something like /plugin/example-0.1/js/mycode.js and Grails will deal with making sure the resources are in the right place."

Grails process dynamic javascript (output from gsp) as a resource

I have a JS file that is included in my GSP template as follows:
<r:script type="text/javascript">
<g:render template="/javascript/common"/>
</r:script>
The /javascript/common outputs some dynamic JS e.g. pre-populates lists client side. It's dynamic per server restart i.e. it doesn't need to be generated per request, but rather more commonly on redeployment.
I'm wondering how I can process it as a resource using the resource plugin and get the ability to minify it and compress it etc.
There may be times where it would need to be refreshed. Is it possible to support refreshing it in a similar fashion to other resources i.e. when the underlying file is modified the plugin reloads it.
thanks ...
The best way to ensure it cooperates with the resource plugin would be to create a custom ResourceMapper
Oversimplified version:
Create a file with ResourceMapper.groovy as the file suffix, in the grails-app/resourceMappers folder.
Decorate the class using def phase = MapperPhase.GENERATION
Implement def map(resource, config) {} to generate your resource when requested.
Your custom mapper will run once per deployment, then use the static generated file. All of the minify/compress, you're using will, of course, run after the GENERATION phase.
UPDATE: It does look like the Gsp Resources plugin #Ruben suggested would do what you're looking for. You can see the source for its custom mapper.

load images from javascript

In my Grails app, I have a dir web-app/images/carousel/slides that contains files such as:
foo.png
foo.thumbnail.png
bar.png
bar.thumbnail.png
My app is using the resources Grails plugin, and the main images are loaded in a GSP using one of it's tags:
<r:img file="carousel/slides/foo.png"/>
which generates:
<img src="/myapp/static/images/carousel/slides/foo.png">
I attempt to load the thumbnail images from JavaScript by constucting a path such as /myapp/static/images/carousel/slides/foo.thumbnail.png. But when I attempt to display one of these images, I get a 404.
Similarly, if enter the following path in the browser's address bar
http://localhost:8080/myapp/static/images/carousel/slides/foo.png
the image displays correctly, but if I enter
http://localhost:8080/myapp/static/images/carousel/slides/foo.thumbnail.png
I get a 404. Why are my thumbnail images not available at the same path at runtime, given that they're in the same source directory? I suspect the answer has something to do with the fact that the main images are loaded using the resources framework whereas I attempt to load the thumbnails from JavaScript.
You mostly answered your own question: if you don't reference the images using resources in some way, then they don't get processed.
Your best bet is to create a resources module that contains a list of all the images. The add this resource to the page.
// grails-app/conf/CarouselResource.groovy
modules = {
carousel {
resource url:'/images/carousel/foo.jpg'
resource url:'/images/carousel/foo.thumbnail.jpg'
...
}
}
then in your GSP
<r:require module="carousel"/>
Now, the module description is a DSL, so you might be able to use some sort of file loop to automatically add all the files, but I'm not 100% sure how. You also might try something like '/images/carousel/**', but the docs don't say if that would work or not.
Also, I should mention, if you use any of the caching-based resources plugins, this won't help. You will then need to manually call r.img() and set it within your JavaScript, something like this (if it works):
<r:script>
var images = [
'${r.img(...)}'
];
</r:script>
This is because the URLs generated using, for example, cached-resources, are often hashes of the file content to allow for long-term caching. They usually are only indirectly related to the original filename.
Update based on comment below:
To load a common JS remotely, but include the images, you could do something like this. Realize, I don't know your carousel code, and you will almost certainly have to modify the carousel library to handle these changes.
<r:script>
window.carouselImages = [
{
image: '${r.external(url:'images/carousel/image1.jpg'}.encodeAsJavaScript();}',
thumbnail: '${r.external(url:'images/carousel/image1.thumbnail.jpg'}.encodeAsJavaScript();}'
},
...
];
</r:script>
<r:resource url="js/carousel.js"/>
Then in carousel.js you reference window.carouselImages to get your array of images. It also should be possible it flip the order, and use some method within carousel.js to add images, like this:
<r:script>
carousel.addImage('${r.external(url:'images/carousel/image1.jpg'}.encodeAsJavaScript();}', '${r.external(url:'images/carousel/image1.thumbnail.jpg'}.encodeAsJavaScript();}');
...
</r:script>
You can improve this by looping over the file list instead of encoding each image explicitly (and example was given in the JIRA I posted below).
Finally, if you aren't going to use any of the caching or file manipulation plugins (so the files always end up at the same URL), you could just simply loop over the files from within the controller or a service method, calling r.img() on each one. This would ensure that they are copied to the static directory. The return value from r.img() can be ignored.
You can use HTML5's data-* Attribute
<element data-*="somevalue">
Here is an example if your image is located at /grails-app/assets/images:
In page (i.e. index.gsp) you have to add the following:
And from the javascript all you have to do is:
<script>
var calImg = document.getElementById('calendar-icon').getAttribute('data-calendaricon');
</script>
Pretty straightforward, moreover it is a clean approach :)

Resources