I've got two grails projects (admin backend and frontend) using the same domain classes from a local plugin.
I need to have different views in the frontend and the backend. E.g. there's a domain class Event. In each of the projects I use GenerateViews. Then I modify the generated gsps. As an example take the list.gsp. In frontend I remove the actions to create a new event from the view and the Controller, in the backend I keep them. That's because in the frontend the users should be only able to see the list of events, while in the backend the admin creates and modifies what is displayed in the frontend. This is the structure I get:
project domain
domain/grails-app/domain/myapp/Event.groovy
project frontend (grails.plugin.location.'domain' = "../domain")
frontend/grails-app/controllers/myapp/frontend/EventController.groovy
frontend/grails-app/views/event/list.gsp (no links to edit / create action)
project backend (grails.plugin.location.'domain' = "../domain")
backend/grails-app/controllers/myapp/backend/EventController.groovy
backend/grails-app/views/event/list.gsp (links to edit/create...)
But when I run my frontend application using run-app, and go to list, the controller is called:
def listEvents(Integer max) {
params.max = Math.min(max ?: 10, 100)
[eventInstanceList: Event.list(params), eventInstanceTotal: Event.count()]
}
and as a result backend/grails-app/views/event/list.gsp is rendered instead of frontend/grails-app/views/event/list.gsp.
The confusion already begins when I'm generating the views. So when I generate views for domain/grails-app/domain/myapp/Event.groovy inside the backend project everything is fine. The views get created inside my backend projectand work as intended.
Then I move ober to the frontend project and generate views for domain/grails-app/domain/myapp/Event.groovy. This time grails will tell me that there already are views, and asks if I want to replace them. If I say yes, it doesn't replace anything, but create the views in my frontend project. Really weird.
I found that there is an older bug report related to this, and I created a new one (http://jira.grails.org/browse/GRAILS-9920).
In the meantime, what should I do to work around this? I could rename my controllers' methods and the views, but I hope that there's a better way. It seems odd, that a view by the same name may override a view in a separate project. Or does something like that only happen when using run-app?
I'm new to Grails, so maybe I missed something obvious, but this really scares me, since it looks like I might accidentally expose actions in one project by modifying the other.
Related
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.
in my project i have about 20 html forms with many different <input>'s. This <input>'s are unique in every form and they don't repeated between them. For each form there is a script which get data from form, generate specific file, and push it to the browser. and that's it. no databases, admin, logins/passwords and other usual web-app stuff.
so for example in php, project structure can be something like this:
forms/
------->form1/
--------------->index.html
--------------->script/
----------------------->index.php
------->form2/
--------------->index.html
--------------->script/
----------------------->index.php
and so on. It's quite clear and it makes pretty urls like:
www.website.com/forms/form1
but in Ruby-on-Rails there is a MVC pattern. And i have no idea how to organize structure with project like that. How to make it right? I should not to make 20 different controllers after all, right?
Yes you do make 20 controllers. In much the same way as you have 20 script/index.php files in your PHP structure. The rails structure would look something like this.
app/
controllers/
form1s_controller
form2s_controller
.....
formns_controller
view/
form1/
new.html.erb
form2/
new.html.erb
......
formn/
new.html.erb
layouts/
application.html.erb
Where the controllers have a method for each action that you want to perform e.g. new, edit etc
The layouts/application.html.erb file will contain all of the markup that is consistent across all of your pages.
Finally, don't try and fight the structure. It is there to enable minimal code because of convention, if you try and create your own structures you will create a world of pain.
Since there is no database backend for the forms, i would create one FormsController, with 20 methods (form1, form2, form3, ...).
Your urls would then look almost the same \forms\form1, \forms\form2 ...
Even if you would use 20 controllers, there are many ways in ruby to remove duplicate code. So even in a normal MVC, i have had applications with 140 models, and likewise as many controllers, most of these controllers had only one line and the views were completely generic.
Just because a certain solution seemed simple in PHP, it doesn't mean better solutions don't exist. Like for instance MVC. It might seem to induce more code, more files, more work, but the structure is there for good reason, it seperates the concerns cleanly, and each file in itself becomes more clear and easier to understand.
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.
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
I need to implement a web app, but instead of using relational database I need to use different SOAP Web Services as a back-end. An important part of application only calls web services and displays the result. Since Web Services are clearly defined in form of Operation: In parameters and Return Type it seems to me that basic GUI could be easily constructed just like in the case of scaffolding based on Domain Entities.
For example in case of SearchProducts web service operation I need to enter search parameters as input, so the search page can be constructed. Operation will return a list of products, so I need a page that will display this list in some kind of table.
Is there already some library in grails that let you achieve this. If not, how would you go about creating one?
Probably the easiest approach is to use wsimport on the WSDL files to generate the client-side stubs. Then you can call methods in the stubs from Groovy just as you would have called them from Java.
For example, consider the WSDL file for Microsoft's TerraServer, located at http://terraservice.net/TerraService.asmx?wsdl . Then you run something like
wsimport -d src -keep http://terraservice.net/TerraService.asmx?WSDL
which puts all the compiled stubs in the src directory. Then you can write Groovy code like
import com.terraserver_usa.terraserver.*;
TerraServiceSoap sei = new TerraService().getTerraServiceSoap()
Place home = new Place(city:'Boston',state:'MA',country:'US')
def pt = sei.convertPlaceToLonLatPt(home)
println "$pt.lat, $pt.lon"
assert Math.abs(pt.lat - 42.360000) < 0.001
assert Math.abs(pt.lon - -71.05000) < 0.001
If you want to access a lot of web services, generate the stubs for all of them. Or you can use dynamic proxies instead.
The bottom line, though, is to let Java do what it already does well, and use Groovy where it makes your life easier.
You should be able to use XFire or CXF Plugins. For automatic scaffolding, modify your Controller.groovy template in scaffolding templates so it auto-generates methods you need.