different mapping for the same url - url

I would like to use a different mapping for the same url http://localhost:8080/myapp/ when the user is logged in (session.user)
Actually, as default Im giving the path when the url is "/" to AppController and 'index' action... but if I try to redirect inside the index action when the user is logged to my UserController (also index action), the path changes to http://localhost:8080/myapp/user/index . Thats not what I`m looking for.
There is a plenty of website (twitter, facebook..) that apply this method, but couldn`t understand how can it be done in Grails, without using the same action for example (AppControlle>index) and render different views when user is active.
static mappings = {
"/"(controller:"app",action:"index")
"/$controller/$action?/$id?"{
constraints {
// apply constraints here
}
}
"500"(view:'/error')
"404"(view:'/notFound')
}

About your mention about twitter, facebook... I think it's possible that they use different mapping based on the request is POST or GET. In Grails, we can do that kind of mapping like this:
name home: "/" {
controller = [GET: "app", POST: "user"]
action = [GET: "index", POST: "userIndex"]
}

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 dynamic url mapping

I have a product list I'm trying to create SEO-friendly URLs for.
Example
domain.com/product/cell-phone-razor
"cell-phone-razor" is dynamic from the db
I have successfully achieved this behavior with the following code
"/product/$url"(controller: "product", action:"show")
However there becomes an issue when trying to map other actions non related to the page URL. Example I have an Ajax URL domain.com/product/setPrice which is being mapped to the show action.
I was able to work around this by adding the following to my urlmapping in addition to the previous mapping.
"/product/setPrice" {
controller = "product"
action = "setPrice"
}
Is there a better way to config my url mapping so that I don't need to add rules for every action mapping?
In our application we use the following approach - not saying the perfect one. Basically we're appending URL fragments (that are happily ignored by search engines) to the SEO parts of the URL.
name product: "/$productName-p$productId" {
controller = 'product'
action = 'show'
constraints {
productName matches: '.+'
productId matches: '^[0-9]+$'
}
}
In your case the url should look like domain.com/product/cell-phone-razor-p123455 where 123456 is the product id.
Although not as dynamic as I'd like, but this seems to be the best solution.
"/product/$url"(controller: "product", action:"show") {
constraints {
url(validator: {
return !(it in
['setPriceAction', 'setAnotherAction']
)
})
}
}

How to create canocical from controller in 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.

RESTful grails application: DRYing up UrlMapping

Let's say we have a grails web application exposing several resources.
tags
urls
users
The application has a classical web-interface which the users interact with and some administration.
We want to expose the resources from the application to clients via a RESTful API and we don't want that part of the app to clutter up the controllers and code we already have.
So we came up with the following:
If the web interface offers host/app_path/url/[list|show|create] we want the REST API to be at /host/app_path/rest/url.
So we ended up with the following UrlMappings file:
class UrlMappings {
static mappings = {
"/$controller/$action?/$id?"{
}
/* adding new urls and listing them */
"/rest/url"{
controller = "urlRest"
action = [POST: "save", PUT: "save", GET: "list", DELETE:"error"]
}
/* accessing a single url */
"/rest/url/$id"{
controller = "urlRest"
action = [POST: "update", PUT: "update", GET: "show", DELETE: "delete"]
}
/* non-crud stuff on urls */
"/rest/url/$action?/$id?"{
controller = "urlRest"
}
"/"(view:"/index")
"500"(view:'/error')
}
}
The problem is, that this isn't exactly the most DRY thing here. It gets worse as we add more resources such as tags. They would translate to yet another three blocks of very similar code...
The non-crud functions will be things like searching with specific criterions and such...
We tried generating the mapping closures with a loop, but without success. Are we completely on the wrong track here?
I would recommend the following mapping:
"/rest/url/$id?"(resource:"urlRest")
Below is the HTTP method to action mapping that this would create for the urlRestController:
GET show
PUT update
POST save
DELETE delete
I see why you might want to map /rest/url POST to save and /rest/url/id PUT to update, but that goes against the meaning of those verbs. A PUT should be the only way to add a new url and POST the only way to update a url. Doing it the way you have laid out would work and might be the best way if your constraint is to keep your current controller code untouched. However, my guess is that you controller might already be coded to handle the default mappings just fine (update/delete give error if no id, show redirects to list if no id, etc.).

How do you change the default homepage in a Grails application?

What is the configuration setting for modifying the default homepage in a Grails application to no longer be appName/index.gsp? Of course you can set that page to be a redirect but there must be a better way.
Add this in UrlMappings.groovy
"/" {
controller = "yourController"
action = "yourAction"
}
By configuring the URLMappings this way, the home-page of the app will be yourWebApp/yourController/yourAction.
(cut/pasted from IntelliGrape Blog)
You may try as follows
in the UrlMappings.groovy class which is inside the configuration folder:
class UrlMappings {
static mappings = {
"/$controller/$action?/$id?"{
constraints {
// apply constraints here
}
}
//"/"(view:"/index")
"/" ( controller:'Item', action:'index' ) // Here i have changed the desired action to show the desired page while running the application
"500"(view:'/error')
}
}
hope this helps,
Rubel
Edit UrlMappings.groovy
Add for example add this rule, to handle the root with a HomeController.
"/"(controller:'home')
Use controller, view and action parameter by the following syntax:
class UrlMappings {
static mappings = {
"/" (controller:'dashboard', view: 'index', action: 'index')
"500"(view:'/error')
}
}
Simple and Neat
Go to File: grails-app/conf/UrlMappings.groovy.
Replace the line : "/"(view:"/index") with
"/"(controller:'home', action:"/index").
Home is Your Controller to Run(Like in spring security you can use 'login' ) and action is the grails view page associated with your controller(In Spring Security '/auth').
Add redirection of pages as per your application needs.
All the answers are correct!
But let's imagine a scenario:
I mapped path "/" with the controller: "Home" and action: "index", so when i access "/app-name/" the controller Home gets executed, but if i type the path "/app-name/home/index", it will still be executed! so there are 2 paths for one resources. it would work until some one finds out "home/index" path.
another thing is if I have a form without any action attribute specified, so by default it will be POST to the same controller and action! so if the form is mapped to "/" path and no action attribute is specified then it will be submitted to the same controller, but this time the path will be "home/index" in your address-bar, not "/", because it's being submitted to the controller/action not to the URI.
To solve this problem what you have to do, is to remove or comment out these lines.
// "/$controller/$action?/$id?(.$format)?"{
// constraints {
// // apply constraints here
// }
// }
So now when you access "/", will work. but "home/index" will not. But there's a one flaw, now you have to map all the paths to the controllers manually by explicitly writing into URLMapping file. I guess this would help!
If anyone is looking for the answer for gails 3.x, they moved UrlMappings.groovy to grails-app/controllers/appname
As the below answers say, just ed it the line starting with "/".
In my case its:
"/"(controller:"dashboard", view:"/index")

Resources