Grails case insensitive URL Mapping of predefined URL? - grails

I have the following url mapping:
"/Some-Name".toLowerCase() {
controller ="user"
action = "show"
id = "f274b72e1309467e70"
}
Note this is not a duplicate of this: How to make my URL mapping case insensitive? It is a different case.
How can I make this URL mapping case insensitive?

Maybe you can try to use custom validator in constraint section. Please note that code below is not tested.
"/$path" {
controller ="user"
action = "show"
id = "f274b72e1309467e70"
constraints {
path((validator: { return it.equalsIgnoreCase("Some-Name") })
}
}

Related

Parameter 'id' to be query string in Grails redirection

From Grails controller, I want to redirect to this (using query string):
/mycontroller/myaction?id=3
I wrote this code:
def a = 3;
redirect (controller:"mycontroller",action:"myaction",params:[id:a])
This code will produces:
/mycontroller/myaction/3
I know that 'id' is special parameter. It will be url not query string. I try another parameter
def name = "John";
redirect (controller:"mycontroller",action:"myaction",params:[name:name])
will produces:
/mycontroller/myaction?name=John
Your described behavior is a result of your UrlMappings configuration.
If you use the default mapping, the id parameter will be put in the at the described position $id?:
class UrlMappings {
static mappings = {
"/$controller/$action?/$id?"{
constraints {
// apply constraints here
}
}
"/"(view:"/index")
"500"(view:'/error')
}
}
In general this is no problem. You could also use the id parameter as if it was set as query string:
def myaction() {
def idFromParams = params.id
}
Or you simply rewrite your UrlMappings.

How to Rewrite hardcoded url in yii?

How to Rewrite hardcoded url in yii?
I have made a url as follows,
CHtml::link($visit->health_institute_name, array('hospitals_single', 'id'=>$visit->health_institute_id));
It redireceted to the url as follow,
http://abc.com/hospital?name=yyy&id=14#ad-image-0
I Just want the url to be as follows,
http://abc.com/yyy
ie: i need to remove hospital?name= and &id=14#ad-image-0 from the url...
Can any one help?
In your urlManager rules, add this after all other rules:
'<name>' => 'hospital/view',
assuming view is the action you want to call - replace it with your action name
Then your link as follows:
CHtml::link($visit->health_institute_name, Yii::app()->getBaseUrl(true).'/'.$visit->name);
if you want to make a user friendly and seo-friendly like http://abc.com/hospital/yyy
You can use this:
class CarUrlRule extends CBaseUrlRule
{
public $connectionID = 'db';
public function createUrl($manager,$route,$params,$ampersand)
{
if ($route==='car/index')
{
if (isset($params['manufacturer'], $params['model']))
return $params['manufacturer'] . '/' . $params['model'];
else if (isset($params['manufacturer']))
return $params['manufacturer'];
}
return false; // this rule does not apply
}
public function parseUrl($manager,$request,$pathInfo,$rawPathInfo)
{
if (preg_match('%^(\w+)(/(\w+))?$%', $pathInfo, $matches))
{
// check $matches[1] and $matches[3] to see
// if they match a manufacturer and a model in the database
// If so, set $_GET['manufacturer'] and/or $_GET['model']
// and return 'car/index'
}
return false; // this rule does not apply
}
}
More informatino there !
http://www.yiiframework.com/doc/guide/1.1/fr/topics.url#using-custom-url-rule-classes

Grails UrlMapping route to fixed controller and action

I made the following rule in my UrlMapping file and now all my controllers are matching to the ("/$username") mapping, not the first one ("/$controller/$action?/$id?").
The idea here was to list all public items from an user using a short url. It works but it breaks all others controllers.
static mappings = {
"/$controller/$action?/$id?"{
constraints {
// apply constraints here
}
}
"/$username" {
controller = 'user'
action = 'publicItens'
}
"/"(controller:'usuario', action: 'index' )
"500"(view:'/error')
}
How can I map it correctly?
solved!
I just wrote some code in the UrlMappings to create rules automatically for each controller in the application. Using this approach when the user types /appname/controllerName then the rule created automatically is considered in place of the "$/username" rule.
The critical point is that the use of ApplicationHolder which is deprecated. That can fixed writing your own ApplicationHolder.
static mappings = {
//creates one mapping rule for each controller in the application
ApplicationHolder.application.controllerClasses*.logicalPropertyName.each { cName ->
"/$cName" {
controller = cName
}
}
"/$controller/$action?/$id?"{
}
"/$username" {
controller = 'usuario'
action = 'itensPublicos'
}
"/"(controller:'usuario', action: 'index' )
"500"(view:'/error')
}
Just add /users/$username to the URL mapping. This is the simplest way how to achieve your goals.
"/users/$username" {
controller = 'user'
action = 'publicItens'
}
You could probably also exclude the user and usario controllers in the first url mapping constraints(notEqual)
http://www.grails.org/doc/latest/ref/Constraints/notEqual.html

Setting up the filter without controllers

I have a running tomcat at localost.
I wish to write a grails filter such that when ever user goes to localhost/filter/ intercept the call and do some processing. I created a filter which is inside conf folder
class TestFilters {
def filters = {
filter(uri:'/filter') {
before = {
}
after = {
}
afterView = {
}
}
}
}
after setting this up when I go to localhost/filter/ I get only 404 error.
Where I'm making the mistake?
Thanks in advance
If you have no FilterController the url localhost/filter has no ressource to show - so you get a 404 error. You have to adapt your UrlMappings so that localhost/filter is a valid url of application.
Add the following to UrlMappings.groovy:
"/filter" (controller: "yourController", action:"yourAction")
Now - the url localhost/filter points to yourAction in yourController and the filter should be applied.

Advanced Routing Behaviour with ASP.NET MVC Routing

Given a url that follows the following pattern:
firstcolor={value1}/secondcolor={value2}
where value1 and value2 can vary and an action method like:
ProcessColors(string color1, string color2) in say a controller called ColorController.
I want the following route evaluation:
URL '/firstcolor=red' results in a call like ProcessColors("red", null)
URL '/secondcolor=blue'results in a call like ProcessColors(null, "blue")
URL 'firstcolor=red/secondcolor=blue' ends up in a call like ProcessColors("red", "blue")
Now from I think this can be achieved with a few routes, something like this
route.MapRoute(null,
"firstcolor={color1}/secondcolor={color2}",
new { controller=ColorController, action = ProcessColors })
route.MapRoute(null,
"firstcolor={color1}}",
new { controller=ColorController, action = ProcessColors, color2 = (string)null })
route.MapRoute(null,
"secondcolor={color2}}",
new { controller=ColorController, action = ProcessColors, color1 = (string)null })
This is sufficient for just 2 colors, but as far as I can tell we'll end up with a proliferation of routes if we wanted to have, say 4 colors and be able to have URL's like this:
'/firstcolor=blue/secondcolor=red/thirdcolor=green/fourthcolor=black'
'/firstcolor=blue/thirdcolour=red'
'/thirdcolour=red/fourthcolour=black'
and so on, i.e. we need to cater for any combination given that firstcolor will always be before 2nd, 2nd will always be before 3rd and so on.
Ignoring my ridiculous example, is there any nice way to deal with this sort of situation that doesn't involve lots of routes and action methods needing to be created?
First of all, if you are going to use that key=value format, then I suggest using QueryString instead of the URL.
But if not, you can do this :
//register this route
routes.MapRoute("color", "colors/processcolors/{*q}",
new { controller = "Color", action ="ProcessColors" });
Then in your ColorController :
public ActionResult ProcessColors(string q) {
string[] colors = GetColors(q);
return View();
}
private string[] GetColors(string q) {
if (String.IsNullOrEmpty(q)) {
return null;
}
return q.Split("/".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
}
In this case your URLs will be like this :
site.com/colors/processcolors/red
site.com/colors/processcolors/red/green
In the case that we use the wildcard mapping I suppose we lose the ability to use Html.ActionLink to build our URL's for us?

Resources