How to create canocical from controller in grails? - grails

In grails, I have a link like /myapp/questions/all
The all is a parameter (all, replied, ...) passed to my controller.
I have a form to search question depending of type : in all, in replied, ...
In the search form, I have an hidden field to pass parameter.
But the url displayed is /myapp/questions/ ans not /myapp/questions/all
So I tried with url : url="[action:'question', controller:'mycontroller', params:['monparam':'${mavariable}']]"
but it's not working.
Any idea ?
Thanks

You can do it like this:
class UrlMappings {
static mappings = {
name nameOfTheMapping: "/question/$para/" {
controller = "mycontroller"
action = "question"
}
...
Then you can access the mapping by:
<a href='${createLink(mapping: 'nameOfTheMapping', params: [para: para.encodeAsUrl()])}' title='test'>Test</a>
The above code is created in my taglib, so it maybe a little different if you want to use it in a view.

I don't completely understand your question, but it seems you are not following the grails convention. the url is of the form
/app/controller/action
so grails is interpreting the 'all' part of your url as the action to invoke on the questions controller (what I got from your 'link like /myapp/questions/all').
Where I got confused was with your url specification.
url="[action:'question', controller:'mycontroller', params:['monparam':'${mavariable}']]"
Based on that, you should have a controller called 'mycontroller', with an action called 'question' on it. The url you will see in the browser would be
/app/mycontroller/question?monparam:whatever
See here for details on controllers in general.

You need to edit grails-app/conf/UrlMappings.groovy and create a mapping to the controller that omits the action. (since you're handling this all within one action)
something like
"/questions/$question_type" (controller: 'questions', action: 'your_action')
where "your_action" is the name of the action that is processing these requests.
Then in QuestionsController.groovy:
def your_action = {
// use question_type as needed
def questions = Questions.findByQuestionType(params.question_type)
// etc.
}
You can do a variety of things to affect the mapping of urls to requests, check out the UrlMapping section in the Grails User Guide.

Related

Grails: URL mapping with .gsp extension/format

I have a url request like www.xyz.com/customer/list.gsp
When I try to map the url to remove .gsp:
"/customer/list.gsp"(controller: "customer") {
action = "list"
}
grails application won't recognize the url and is throwing 404 error. Am I missing something here?
If you want to remove .gsp from the url then you can use a mapping like this...
"/customer/list"(controller: "customer") {
action = "list"
}
You could also do this...
"/customer/list"(controller: "customer", action: "list")
If you want 1 mapping for all the actions in the controller, you could do this:
"/customer/$action"(controller: "customer")
The default generated mapping includes "/$controller/$action" which allows you map to any action in any controller.
With any of that, sending a request to /customer/list would work.
Update: apparently it is fine to map to GSPs. I still think that the info below may be helpful so I'm leaving the answer up, but perhaps I have misunderstood your question.
Original response:
You shouldn't be mapping to or requesting gsps at all. They're used to generate views, but are not viewable without rendering.
Instead, go to url like www.xyz.com/customer/list and map that like
"/customer/list" (controller: "customer") {
action = "list"
}
Or even better, you don't need a custom mapping for each endpoint. A default like this will work:
"/$controller/$action?/$id?" { }
Your CustomerController will render the list.gsp in the list action.

Grails: How do I map a URL to a controller inside a custom plugin?

I have a controller inside a plugin called TextController with an action called index
I then have a view inside the calling application called test-plugin.gsp with the following include tag:
<g:include controller="text" />
This works great. The problem is that the plugin's controller actually needs to identified by a package-like name, such as: com.foxbomb.fxportal3.components.text, and I need to reference it as such. So my thinking us to try and have a URL mapping for the plugin, such as:
"/components/com.foxbomb.fxportal3.components.text/" {
controller = "text"
action = "index"
}
I also don't know how to create an include in the calling application to try and call that URL, something like (I know you don't get a URL attribute):
<g:include url="/components/com.foxbomb.fxportal3.components.text"/>
In other words, I want to include a controller / action by its mapping as opposed to its controller / action name.
<g:include> doesn't allow a url attribute, which surprises me, but looking at the source of the <g:include> tag it should be possible to implement this in your own taglib fairly easily (untested):
import org.codehaus.groovy.grails.web.util.WebUtils
class IncludeTagLib {
def grailsUrlMappingsHolder
def includeUri = { attrs, body ->
def mapping = grailsUrlMappingsHolder.match(attrs.uri)
out << WebUtils.includeForUrlMappingInfo(request, response, mapping,
attrs.model ?: [:])?.content
}
}
You'd say <g:includeUri uri="/components/com.foxbomb.fxportal3.components.text"/> in your GSP.

Grails urlmappings, can one prefix urlmappings?

So for instance, say i have an API on a webapp, and i wish to use the same controllers and actions in the API as the rest of the webapp.
In my urlmappings file i have
"/api/$version/$apiKey/$controller/$acion/$id?"
and i also have a mapping like this:
"/blog/$year/$month/$day/$action" {
controller = 'blog'
}
Now the question is, can i somehow prefix the api urlmapping to the blog urlmapping so i can benefit from the $year, $month, $day variables? in such a way that a GET request to the following url would be valid:
GET /api/0.1/bs23mk4m2n4k/blog/2001/01/05/list
or am i forced to do the following request instead?
GET /api/0.1/bs23mk4m2n4k/blog/list?year=2004&month=01&day=05
Need help from an urlmappings GURU or a groovy runtime urlmappings maniuplation WIZARD :)
I want a solution that can reuse existing non-api urmappings, instead of having to redeclare them with the api path as a prefix.
You could have an ApiController strip off the api parameters, then redirect to the blog controller. For example:
"/api/$version/$apiKey/$rest**" {
controller:'api'
action:'default'
}
import org.codehaus.groovy.grails.web.util.WebUtils
class ApiController {
def grailsUrlMappingsHolder
def default = {
// validate apiKey, etc
WebUtils.forwardRequestForUrlMappingInfo(request, response, grailsUrlMappingsHolder.match("/${params.rest}"))
}
}
The API controller has access to the version and apiKey params, and passes on the rest of the params to be processed by the blog controller's UrlMapping.
I think you want to use embedded variables. Check the url mapping reference: http://grails.org/doc/latest/guide/single.html#6.4 URL Mappings
just add the following mapping:
static mappings = {
"/api/$version/$apiKey/$controller/$year/$month/$day/$action"()
}
now you can use this url for example:
http://localhost:8080/api/0.1/bs23mk4m2n4k/blog/2001/01/05/list
now you get redirected to the list action in the blog controller.
there you can use params to show the parameters from the url (as defined in the mapping).
ex.
params.version
I had somewhat the same problem, solved it using named url mapping: http://www.grails.org/doc/latest/guide/6.%20The%20Web%20Layer.html#6.4.9%20Named%20URL%20Mappings
Hope this helps!
in urlMapping:
name blogWithYear:"/api/$version/$apiKey/$controller/$year/$month/$day":{
controller = 'blog'
action = 'youraction'
}
<g:link mapping="blogWithYear" params="[$version:'0.1', ....., '$year: 2011']">
Show blog
</g:link>
With g:link you can now compile the url however you want, adding parameters.

another grails urlmapping question

ok, so i asked, and got an answer on how to make a single controller instance case-insensitive vis-a-vis urls. I can do
"/mycontroller/$action?/$id?"(controller: "myController")
so when an app outside tries to reference link in our app, their lowercase urls ( :( sigh ) will work.
I need to extend this to include actions as well. So the question is, following the above approach, do i need put a url mapping in for each action?
/mycontroller/methodone/(controller: "myController", action: methodOne)
/mycontroller/methodtwo/(controller: "myController", action: methodTwo)
Something like the above?
This is similar to the question below which I have answered and included source code
How to make my URL mapping case insensitive?
You can use a closure to calculate the action (or other parameters) programmatically:
"/mycontroller/$a?/$id?" {
controller = 'myController'
action = { params.a?.toLowerCase() }
}

URL Mapping prefix in Grails

Recently, I'm trying to migrating my application from CakePHP to Grails. So far it's been a smooth sailing, everything I can do with CakePHP, I can do it with much less code in Grails. However, I have one question :
In CakePHP, there's an URL Prefix feature that enables you to give prefix to a certain action url, for example, if I have these actions in my controller :
PostController
admin_add
admin_edit
admin_delete
I can simply access it from the URL :
mysite/admin/post/add
mysite/admin/post/edit/1
mysite/admin/post/delete/2
instead of:
mysite/post/admin_add
mysite/post/admin_edit/1
mysite/post/admin_delete/2
Is there anyway to do this in Grails, or at least alternative of doing this?
Grails URL Mappings documentation doesn't help you in this particular case (amra, next time try it yourself and post an answer only if it's any help). Daniel's solution was close, but wouldn't work, because:
the action part must be in a closure when created dynamically
all named parameters excluding "controller", "action" and "id" are accessible via the params object
A solution could look like this:
"/admin/$controller/$adminAction?/$param?"{
action = { "admin_${params.adminAction}" }
}
The key is NOT to name the parameter as "action", because it seems to be directly mapped to an action and can not be overriden.
I also tried a dynamic solution with generic prefixes and it seems to work as well:
"/$prefix/$controller/$adminAction?/$param?"{
action = { "${params.prefix}_${params.adminAction}" }
}
I didn't test it, but try this:
"mysite/$prefix/$controller/$method/$id?"{
action = "${prefix}_${method}"
}
It constructs the action name from the prefix and the method.
Just take a look on grails URL Mappings documentation part

Resources