Question

Anybody who already have implemented something similar using Grails could tell me please which are the good pratices (if there are any) to create user profile URLs with the format "http://www.myservice.com/username", as in Facebook, Twitter, Linkedin?

I'm trying to implement it through the UrlMappings and appears to me I'll need to break with the code conventions, at least for the Controllers.

So, any suggestions are welcome, thanks.

UPDATE 1

When I mentioned my concern about breaking the code conventions, what I'm saying is that I want to show the user profile using this mapping, but I do have other objects in my application which I would like to access using the default mapping:

"/$controller/$action?/$id?"()

SOLUTION

Thanks to the great contributions I've received here, I've camed up with this solution, which solves my problem.

As was pointed out, to do this kind of mapping, I'll need to control more closely how my requests are handled. That means I'll need to tell to Grails which controllers I don't want to be mapped to the "username" rule.

Since that will be a very tedious task (because I have several controllers), I did this to automate it:

UrlMappings.groovy

static mappings = {
     getGrailsApplication().controllerClasses.each{ controllerClass ->
     "/${controllerClass.logicalPropertyName}/$action?/$id?"(controller: controllerClass.logicalPropertyName)
     }
     "/$username/$action?"(controller: "user", action: "profile")
     }
     ...
 }

And of course, I'll need to do something similar in my user registration process to avoid usernames to be equal to some controller name.

That's it, thank you all.

Was it helpful?

Solution

Assuming you have a UserController and you are going to map any domain.com/username to the show action of user controller, your url mapping could be something like this : In my example, name will become a parameter in your params. for further details refer to here

Hope this helps.

static mappings = {
    "/$name"(controller: "user", action: "show")

    ...
}

OTHER TIPS

Given your requirements, everything after http://yourdomain.com/ can be a username or one of your other controllers, which can have undesired effects depending on which url mapping is defined first (e.g. user controller vs nonuser controller). But most likely the nonuser controller list will be the smaller list, so you should place that first and filter against it, then treat all other url mappings as user mappings.

Here is an example:

static mapping = {
  "/$controller/$action?/$id?" {
    constraints {
      controller inList: ['nonUserController1', 'nonUserController2',...]
    }
  }

  //this should work for /username and /username/whateveraction
  "/$username/$action?"(controller: 'user')
}

Some things to note here:

  • you need to place the non user controller url mapping first, since everything else after http://yourdomain.com/ may be a username - correct?
  • second you need to place a constraint to catch all the non user controllers, while ignore the user url mappings
  • also you need to prevent a user from signing up with a username that matches one of your non user controllers
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top