Urlmapping for camel case with more than one meaningful step - grails

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

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.

Zend Framework 2 Hierarchy Semantics?

I've been searching and trying to learn for ages but it just doesn't stick. There seems to be only 1 tutorial on Zend 2, and it's not very smart. Here we have a sample structure (and the tutorial proceeds with this application) http://framework.zend.com/manual/2.0/en/user-guide/modules.html :
zf2-tutorial/
/module
/Album
/config
/src
/Album
/Controller
/Form
/Model
/view
/album
/album
That's not cool - how do I know which album is which? In Zend 1 it made a lot of sense - you have modules, then you have controllers, and those controllers have actions.
Now I have a module called Album. is the src/Album/... a "single controller"? Would:
zend1application/modules/album/albumcontroller.php map to zend2application/modules/album/src/album/controller/albumcontroller.php? In that case, why are there 3 albums now? Like what happens if I change albumcontroller.php to indexcontroller.php? (I have been testing but there are so many changes it never sticks - I finally thought I should ask someone and if I know why I'll remember.
If I look at it a different way it seems the Album in module/Album and module/Album/src/Album should be the same - then why would we have it twice? Doesn't that just make room for error? Like why have a src/album folder? Why not put Controller, Form, and Model under module/Album?
Why is there a folder called Controller? There used to be a folder called controllers (plural, why singular now?) in a module before, that makes sense. But why is/are controller(s) inside a src/Album folder now?
Thank you for your time. I have tried to research but I think it's just too big absorb when (in my opinion) it seems so sparsely documented. Or, if someone could point me to a book like http://survivethedeepend.com/ but for ZF2, it'd be greatly apprecated.
Zend Framework 2 follows PHPfigs PSR-0 Standards. This means that the directory structure directly relates to the classname. But before i come close to that, let me explain the basic architecture.
First you have the ModuleNAME. Since the Module name needs to be unique, it only makes sense to map the Modulename to the Namespace of your model.
Inside the modules folder you have three sub-folders. One folder for configuration items named config. One folder for source-code files named src and one additional folder for the view files view
This separation is simply for overview. You separate configuration, view and sourcecode from another. It makes no sense to bunch them together and i guess you'd agree. This pretty much has been the same for ZF1, too.
The interesting part is the source-folder src. Earlier i mentioned about the PSR-0 Standard. And this is the place where it comes into effect. By default the source-files for each module will be looked upon from the source-folder src. So whenever you have a class, it will be using PSR-0 Standards based off of the source-folder. Mewning: My\Funky\Class would be found within src\My\Funky\Class.php
And that's basically all there is to it. Controllers usually have a FQCN like Mymodule\Controller\SomeController so you will find this class inside src\Mymodule\Controller\SomeController.php
The main question arising could be: Why are the folders sometimes all lowercase and sometimes ucfirst. The answer, once again, is PSR-Standards. Classnames and/or Namespaces are supposed to begin with an upperchar character. And since path-names are case-sensitive, the folders need to match the classnames exactly!
EDIT Another nice read i've just stumbled upon is Rob Allens latest blogpost: Thoughts on module directory structure. He explains how you can change the default setup quite easily to your likings.

IntelliJ Idea auto-complete for my own grails domain meta class methods?

I'm using IntelliJ Idea 10 IDE for my grails development and while it's great at working out the "standard" meta class methods on, for example, domain classes (save, findBy etc), it (obviously) can't pick up methods added by plugins or my own code.
While I don't expect the IDE to be able to pick these up automatically, I'm optimistically wondering if there's a way to tell IntelliJ that, for example, "myMethod" is added to all domain objects, and that it takes a map and returns "myType".
It's a long shot I know, but does anyone know how this might be done in config, a plugin, or by some smoke-and-mirrors so I can a) stop missing simple, stupid typos and b) get some auto-complete?
I think you're looking for the GroovyDSL scripting framework
http://confluence.jetbrains.net/display/GRVY/Scripting+IDE+for+DSL+awareness
its possible to save a *.gdsl file somethere in src dir, with content:
contributor(context()) {
def scope = com.intellij.psi.search.GlobalSearchScope.allScope(project);
delegatesTo(com.intellij.psi.JavaPsiFacade.getInstance(project).findClass('org.grails.datastore.gorm.GormStaticApi', scope)) delegatesTo(com.intellij.psi.JavaPsiFacade.getInstance(project).findClass('org.grails.datastore.gorm.GormEntity', scope))}

Mapping controller names to urls (with packages)

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

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.

Resources