Grails SEO friendly URLs - url

The standard way of creating URLs in grails is:
${news.title}
which generates the url: /news/show/102
I want more SEO friendly URLs like:
/news/102/this-is-the-hottest-news-today
What is the cleanest way to do this in Grails? I could use grails URLMapping to map /news/show/102 to /news/102, but how I do create the complete URL like above?

You could turn the headline into a parameter like this:
name story: "/news/$id/$headline" {
controller = "news"
action = "show"
}
That way you could create your urls with the headline in them and the mapping would still work. You of course don't actually have to use the headline parameter that will appear in your controller. The example above uses a named URL mapping so you can then say:
${createLink(mapping: "story", params: [id: 102, headline: 'this-is-the-hottest-news-today'])}
You may also be interested in this plugin for creating canonical urls - http://www.grails.org/plugin/canonical

Related

MVC5 internationalization of URLs

How can the URLs in an MVC application be localized.
So for example, I would have different URLs depending on the languate
EN: .../user/...
DE: .../Benutzer/...
I not only want this for nice URLs, but also generate my Breadcrumbs from this URLs, so this will genereate me something like:
EN: Home -> User -> ..
DE: Überischt -> Benutzer -> ....
I looked into the Routconfig, but didn't find any options for internationalization. Do I have to define a spezifice route for each internationalized URL?
As far as I know, there is no way to make localized URL that are convention-based beyond adding a localized variation for each route. Instead, you have to build a custom RouteBase that maps the URLs to route combinations based on the current culture. You can also make the reverse routes by overriding GetVirtualPath so that your ActionLink calls will build the correct URL according to the culture.
It works best to add the culture to the beginning of the URL, and use an initializer in the Application_BeginRequest event to set the culture based on the URL.
As for building breadcrumbs you could use MvcSiteMapProvider, which supports localization.
Full Disclosure: I am a major contributor of MvcSiteMapProvider.

Is there a simple way to map a single URL to another URL in ASP.NET MVC?

I have a working ASP.NET MVC application to which I would like to add a very simple URL which I would like to be redirected to another URL, without the Controller part of the path in it.
I.e. I want to be able to tell people to go to mySite.org/Hello and have it direct them to mySite.org/Whatever/WhateverElse?myfun=9, or whatever.
So I added a method in PublicController that redirects Hello to whatever, which works, except it requires me to tell people to go to mySite.org/PUBLIC/Hello, and we'd like to not have the extra word "public" in there.
Hours of confusing study later, I see that I could perhaps add a line in Global.asax.cs such as: routes.MapRoute(name: "Hello", url: "Public/Whatever"); ... or something... but that actually changes the way everything gets routed, and after trying various syntactical variations, nothing has seemed to just change one basic address to map to another basic address.
Is there a simple way to get mySite.org/Hello to map to another URL, without the virtual subdirectory for the public controller?
Create a custom route (it would need to be the first route in the table)
routes.MapRoute(
name: "Hello",
url: "Hello",
defaults: new { controller = "Whatever", action = "WhateverElse" }
);
then /Hello will redirect to /Whatever/WhateverElse

Generate a dynamic, traditional URL (i.e. not an Action/Controller route) using #Html.ActionLink

I need to create a dynamic tag with a url containing JSON values that will be posted to an external payment gateway. Eventually I want something like this:
Pay This Amount
So I figured I would do:
#Html.ActionLink("Pay This Amount", "https://xyz.com/PayNow?paymentData={'StoreID':'1964','Person':{'FirstName':'Joe','MiddleInitial':'A','LastName':'Smith'},'Item':{'1':{'Price':'250','Code':'TUITION'}}}")
But the resulting tag makes the URL in Action/Controller format:
MyWebSite/MyController/https://xyz.com/PayNow?paymentData={'StoreID':'1964','Person':{'FirstName':'Joe','MiddleInitial':'A','LastName':'Smith'},'Item':{'1':{'Price':'250','Code':'TUITION'}}}
...and of course it fails.
I want just a traditional URL not a route. I don't see an overload for a simple URL. Or is there another helper that I can use to create a non-MVC URL?
How do I do this? Thanks!
Thanks.
#Html.ActionLink is used to create an tag to a controller/action in your site. If you just want to create a link to another site just use plain ole HTML:
Pay Now
If you need to use properties from your model you can build the URL in code and then reference that in the tag:
#{
string url = "https://xyz.com?id=" + Model.Id;
}
Pay Now
or
Pay Now

Grails hyphenated URL converter issue with default index method

According to the Grails documentation, the default URL mapping (between controller actions and URLs) uses camel case. You can easily change the URL mapping to use hyphenated URLs:
grails.web.url.converter = 'hyphenated'
So for instance, HelloWorldController.showUsers would map to:
/hello-world/show-users
In Grails, you can have a default controller action which by convention is "index". So for instance, if you have a method named index(), the following URL will hit that method:
/hello-world
You can create an anchor tag which links to that URL like this:
<g:link controller="HelloWorld">Go!</g:link>
I noticed a strange bug where if my controller name prefix is only one "word" such as HelloController, then:
<g:link controller="Hello">Go!</g:link>
... will always generate URLs which point to:
/hello/index
... instead of:
/hello
I refactored and renamed it to other single word controllers and the problem persisted. I was using Grails 2.2.2 so I upgraded to Grails 2.3.4 and was surprised this bug still existed. Renaming the controller to any two word prefix, like HomePageController, HelloWorldController, OneTwoController, etc, is a workaround for now.
This is my first time really using GSP. Am I doing something wrong?
URLs are part of the user experience and should be clean, so the index problem is really annoying.
It's inconvenient, but you can eliminate the index part of the URL for single word controllers by mapping each page and omitting the action.
grails-app/config/UrlMappings.groovy
class UrlMappings {
static mappings = {
"/hello" (controller: "hello")
"/settings" (controller: "settings")
"/dashboard" (controller: "dashboard")
...

UrlEncode of link ids with ASP.NET MVC HtmlHelper extension methods

I have actions that take string id parameters that are based on a username which can include characters that require encoding, for instance "user?1"
If I use ActionLink() to generate the links, passing the string without encoding, it generates a link like this: http:\\localhost\controller\action\user?1, and the action gets passed "user" as the id.
If I UrlEncode() the string before passing it to ActionLink, then the link generated is: http:\\localhost\controller\action\user%253f1 as ActionLink will then encode the '%' character for you. Besides this looking ugly, it then also generates a HTTP Error 400 - Bad Request when following the link which I've not yet tracked down the cause of.
Is there any way that I can generate the url like: http:\\localhost\controller\action\user%3f1?
How about removing the ? character or replacing it with something else like a dash (-) or underscore (_) ?
You should look in the Global.asax.cs file
add another route for your convenience, in this case, the ff. might work:
routes.MapRoute(
null,
"{controller}/{action}/user/{id}",
new { controller = "Home", action = "Index" }
);
I guess this is what you want, to separate action for each users, but i suggest you use cookie for this purpose.
PS: Remember to put that one on top of your default route since routing is trying to match from top to bottom.
you can create a jquery plugin that check all the links and replace the char that you need to replace with the new value.
and after apply this plugin to all the ActionLinks

Resources