Mapping controller names to urls (with packages) - grails

Is it possible to configure grails to resolve controllers and actions using the package they are in as sub-folders?
For example, say I have the following directory structure:
/grails-app/controllers/HomeController.groovy (with action index)
/grails-app/controllers/security/UserController.groovy (with actions index, edit)
/grails-app/controllers/security/RoleController.groovy (with action index, edit)
I would like grails to generate the following url mappings automatically:
http://localhost:8080/myApp/ => HomeController.index
http://localhost:8080/myApp/security/user/ => UserController.index
http://localhost:8080/myApp/security/user/edit => UserController.edit
http://localhost:8080/myApp/security/role/ => RoleController.index
http://localhost:8080/myApp/security/role/edit => RoleController.edit

I would be a bit wary of mapping them directly to your package names. Doing that will make it very hard for you to refactor in the future, especially once your application is out in the wild. It's also going against the conventional nature of Grails.
However, you can still manually structure your URLs to map to different paths. For your question, here's an example:
// grails-app/conf/UrlMappings.groovy
'/security/user/$action?/$id?' (controller: 'user')
'/security/role/$action?/$id?' (controller: 'role')
// the rest of the default UrlMappings are below
'/$controller/$action?/$id?' {}
Since controllers are typically referenced by name, e.g. "user" in your case, it's not easy to go against this convention; it'd be trying to fight the framework instead of letting it do the work for you.
It's probably possible to do this based on package (maybe using Reflection, or something?), but not advisable.

I believe you are looking for Grails URLMapping constraint. Look here: Grails - URL mapping

Related

grails #Resource Annotation before Domain class

When I create a RESTful API in Grails, I add #Resource(uri='env',formats=['multipart/form-data'] before the domain class. And then use grails generate-all domain_name to generate the controller and view.
However, in Eclipse there is an Java problem like
The project was not built due to "RequestEnvironmentController$_on_closure51 [in [Working copy] RequestEnvironment.groovy [in test.environment.manager [in grails-app/domain [in restful-api-for-tem]]]] does not exist". Fix the problem, then try refreshing this project and building it since it may be inconsistent.
Then I get rid of the annotation and the error disappears and the post method still works. I am confused, is the annotation necessary or not? If it is necessary, how can I remove the Java error?
When you use the #Resource annotation there is no need to create a controller because this will be automatically generated as per documentation
Simply by adding the Resource transformation and specifying a URI,
your domain class will automatically be available as a REST resource
in either XML or JSON formats. The transformation will automatically
register the necessary RESTful URL mapping and create a controller
called BookController.

grails - subdomain based projects and links

I am trying to develop a grails application that has "root" content (www.mydomain.com/about for example) but will also support "projects" based upon the subdomain of the request; for example myproject.mydomain.com > www.mydomain.com/myproject. As a first pass, i have the URL configuration below:
"/$controller/$action?/$id?" {
...
}
"/$project/$controller/$action?/$id?" {
constraints {
}
}
The main drawback so far is that the $project variable must be injected manually into every link (tedious and not DRY):
<g:link controller="foo" action="bar" params="${[project: params.project]}">link</g:link>
Is there a way to automatically inject the $project parameter into all links if it is present, or is there a better way to approach this problem?
Basically you can create a grails plugin that will inject into the controller a new project param with a value based on a custom TagLib <g:project bean="myproject"/> (for instance)
It will force you to define this tagLib on each gsp page of your project but it is still DRYer than each link.
Hope it helps,
Fabien.
I can think of a couple of things.
a) You can place a proxy (Apache or something else) in front of your app-server and do some url-rewriting. Bonus: This would also allow you to do some caching of static resources.
b) This solution is a little more technically interesting. You can look up the project based on the http host header (the subdomain part). This will save you from rewriting all urls, all Grails conventions will still apply so you shouldn't run into any problems with third party plugins and so on.

Group Controllers to functional Packages in Grails

I'm developing a Grails App. I have about 20 Controllers right now and there will be more. Is there a way to Group the Controllers in functional Packages? I would like to have something like:
grails-app/administration/<controller classes>
grails-app/usercontent/<controller classes>
grails-app/publiccontent/<controller classes>
The best would be if the Package would not appear in the URL.
You can do something similar by putting your controllers into Java/Groovy packages:
package administration
class UserController { ... }
and placing the source code into corresponding sub-directories of grails-app/controllers/, eg. grails-app/controllers/administration/UserController.groovy. This won't change the default URL Mapping (ie. the package name is not included in the URL). Note however, that your controller names have to be unique even across different packages!
I'm not aware of any easy approach to achieve the directory layout you suggested (no controller/ in the path).

Urlmapping for camel case with more than one meaningful step

As we know, grails automatically maps MyController to [root]/my as expected, but if I have MyAnotherController it gets mapped to [root]/myAnother. I would like to get it mapped automatically to [root]/my/another.
Is there a way to do this without putting additional URL mapping directives to conf/UrlMappings.groovy?
There is an open JIRA related to this (placing controllers in sub folders/ packages). Go ahead and vote for it. I would love to see this implemented in Grails.
http://jira.codehaus.org/browse/GRAILS-1243

Multiple languages in an ASP.NET MVC application?

What is the best way to support multiple languages for the interface in an ASP.NET MVC application? I've seen people use resource files for other applications. Is this still the best way?
If you're using the default view engines, then local resources work in the views. However, if you need to grab resource strings within a controller action, you can't get local resources, and have to use global resources.
This makes sense when you think about it because local resources are local to an aspx page and in the controller, you haven't even selected your view.
I found this resource to be very helpful
Its a wrapper round the HttpContext.Current.GetGlobalResourceString and HttpContext.Current.GetLocalResourceString that allows you to call the resources like this...
// default global resource
Html.Resource("GlobalResource, ResourceName")
// global resource with optional arguments for formatting
Html.Resource("GlobalResource, ResourceName", "foo", "bar")
// default local resource
Html.Resource("ResourceName")
// local resource with optional arguments for formatting
Html.Resource("ResourceName", "foo", "bar")
The only problem I found is that controllers don't have access to local resouce strings.
Yes resources are still the best way to support multiple languages in the .NET environment. Because they are easy to reference and even easier to add new languages.
Site.resx
Site.en.resx
Site.en-US.resx
Site.fr.resx
etc...
So you are right still use the resource files.
The Orchard project uses a shortcut method called "T" to do all in-page string translations. So you'll see tags with a #T("A String to Translate").
I intend to look at how this is implemented behind the scenes and potentially use it in future projects. The short name keeps the code cleaner since it will be used a lot.
What I like about this approach is the original string (english, in this case) is still easily visible in the code, and doesnt require a lookup in a resource tool or some other location to decode what the actual string should be here.
See http://orchardproject.net for more info.
Some of the other solutions mentioned as answer do not work for the released version of MVC (they worked with previous versions of alpha/beta).
Here is a good article describing a way to implement localization that will be strongly-typed and will not break the unit testing of controllers and views: localization guide for MVC v1
This is another option, and you'll have access to the CurrentUICulture in the controller:
Check MVC3-multi-language

Resources