In Grails 3.0 how do you map a URL to a file under the assets
folder?
For example:
http://localhost:8080/favicon.ico
--> grails-app/assets/images/bookmark.ico
I've tried a few test mappings, such as:
grails-app/controllers/UrlMappings.groovy
class UrlMappings {
static mappings = {
...
"/t1.png" (uri: "/assets/images/test.png")
"/t2.png" (uri: "/assets/test.png")
"/t3.png" (uri: "/images/test.png")
"/t4.png" (dir: "assets/images", file: "test.png")
...
}
}
...but they all result in a 500 server error.
If you are not using the Asset-Pipeline you can map static resources to URLs by following the steps laid out in the Grails Documentation. However your question is asking how to map a single resource to a single URL with the Asset-Pipeline plugin.
Burt Beckwith provided insight on the Grails forum a few years ago about Grail's role in serving static resources.
Grails doesn't serve static resources, the container does. So there's no way to directly configure a mapping - you need to serve it through a controller or configure a proxy as Eric suggests.
Burt
This answer may be unsatisfying. But if you must serve a static resource and absolutely do not want to use a controller or proxy you can try the following.
Create a view called image.gsp. The view will only contain an asset tag. Using your examples above,
<asset:image src="t1.png"/>
Then configure your URL mappings to point to the image.gsp
page.
class UrlMappings {
static mappings = {
...
"/t1.png" (view: "image")
...
}
}
I recognize this may not be the exact method you were hoping to use. But I think that understanding the role Grails plays vs. the container running Grails will help inform a decision to properly serve a resource to the user.
I know this may seem unrelated but if you want to create a page that lists the contents of a directory check out this post by CodePanda. His code can be used as a template to create a controller to serve a single file and he explains how to update the view, controller, and groovy.config.
I think you need to map the URL to AssetController of the Asset Plugin, like this (not tested):
class UrlMappings {
static mappings = {
...
"/files/$id" (controller :"AssetController", action:"index")
...
}
}
HTH
Here is what I used to serve up swfobject.js
at a specific URI:
Add a url mapping:
"/swf/swfobject.js" (controller:"facerecorder", action:"swfobject")
Add an action to the controller that locates the resource and serves it. Note that the assetResourceLocator
, which is part of the asset pipeline, is injected into the controller.
class FacerecorderController {
def assetResourceLocator
def swfobject() {
def resource = assetResourceLocator.findAssetForURI('swf/swfobject.js')
render file: resource.inputStream, contentType: 'text/javascript'
}
}
It's definitely not ideal, but it works. Tested using Grails 3.0.17
Using "/favicon.ico"(uri: "/assets/favicon.ico")
works for me.
Conceptually, it appears that Asset Pipeline flattens the assets (so that you do not need to specity images
, javascripts
, stylesheets
for the uri
)
Grails: 3.2.11
AssetPipeline: 2.14.6