PageRenderer in Controller - grails

Can we implement PageRender in controller (grails 3.2.8)? I tried in a service and it worked perfectly as expected.
But when I tried in a controller, I am not getting the expected results.
Controller:
class TestcontrollerController {
def RenderService
def gsp= "grails"
PageRenderer groovyPageRenderer
def index(String gsp) {
render creategsp()
}
def creategsp() {
groovyPageRenderer.render view: '/email/confirm', model: [gsp: findgsp()]
}
def findgsp() {
'<g:select from="${18..65}" value="${age}" />'
}
}
index.gsp:
<g:render template="/test/samplePage" />
samplePage.gsp:
<g:render template="/email/welcome" />
_display.gsp:
Hi ,{username} <br>
PageRenderer is not rendering any of the custom tags or grails tags.
Any suggestions?

Yes this is completely possible. Just define it at the top of your controller:
PageRenderer groovyPageRenderer
Note that you need to strongly type this, and not just "def" it.
Then when you use it, it will render pages to strings:
String renderViewResult = groovyPageRenderer.render(view: "/myViewName", model: renderModel)
If you update your question with more details like what you did, and what isn't working, possibly someone can help you more, but big picture: yep, it works!

Related

Grails display data from database

I'm creating a Grails app following this tutorial: http://grails.asia/grails-tutorial-for-beginners-display-data-from-the-database
When I try to display data from database though, nothing happens. Below is my controller code:
def index(){
def users = User.list();
[users:users]
}
def displayUsers(){
if(User.count()==0){
render 'User list is empty!';
}else {
render(view: 'userlist.gsp');
//a little test
println User.list().size();
println User.count();
for(User u : User.list()){
println u.username;
}
}
}
The User.count() is working, because I can see the usernames in console and userlist.gsp renders every time, but it seems that my view code doesn't see the list. Here's the userlist.gsp code:
<body>
userlist.gsp
<g:each in="${users}" var="user" status="i">
<h3>${i+1}. ${user.username}</h3>
</g:each>
</body>
What can be wrong with this code? I've been making precisely the same steps as in the tutorial above in my analogical app, but it doesn't seem to work. This is especially weird, since I've found a similar question under this link: grails: show list of elements from database in gsp
and it's been marked as accepted answer. Why does exacly the same way not work in my app?
render gsp view as follows (pass data as a model).
render(view: "userlist", model: [userList : User.list()])
Now get model data in gsp as follows.
<body>
userlist.gsp
<g:each in="${userList}" var="user" status="i">
<h3>${i+1}. ${user.username}</h3>
</g:each>
</body>
You can do with many options:
rename your gsp action in controller from def index() to def userlist()
or rename index.gsp file to userlist.gsp
you can redirect to userlist.gsp with ${users} object
So change in controller def index() action
[users:users] to redirect(action: "userlist", params: ["users": users])
Note: 2nd method will show parameters in url.
Refer Grails Doc
You can use chain
e.g. chain(action: "userlist", model: ["users": users])
Refer Grails Doc
every gsp action (page) needs to be injected

How can I connect GSP Template Engines in a Controller with my Domain in Grails?

I did this tutorial to use the GSP Template Engine in a Controller to generate a view. Now I want to access to my database inside the html that I have in my controller, but I don't find the good way to do it. I want to access to my column name and template that I have in my domain.
I need to do it of this way, I know that I can do the same with the gsp file.
Controller:
class SendEmailController {
def groovyPagesTemplateEngine
def emailTemplate = {
def templateText = '''\
<html>
<body>
<h1 align="center">Hello</h1>
<p align="center">This is my text</p>
</body>
</html>
'''
def output = new StringWriter()
groovyPagesTemplateEngine.createTemplate(templateText, 'sample').make([show: true]).writeTo(output)
render output.toString()
}
}
DOMAIN
class SendEmail {
String name
String template
static constraints = {
}
}
You can retrieve a domain object in your controller by calling get() (passing in the id of the record you want to retrieve from the database) on the domain object class.
def emailTemplate = SendEmail.get(id).template
There are some other retrieval methods as well. Look at the GORM documentation for more information: https://grails.github.io/grails-doc/latest/guide/GORM.html.

grails how do I call one controllers action and embed the resulting view in another controller

Say I have controllers Author and Book like this:
class Author{
def show(Integer authorId){
//code
render view:'show',model:[author:author]
}
}
class Book{
def list(Integer authorId){
//code
render view:'list', model:[books:books]
}
}
Now when render show page of an author I want to show the list of books the author wrote,and I want to do it just by calling the Book's controller list action by passing the authorId.
Is it possible to do so? if yes how?
simple!
With in show.gsp of Author do this:
<g:include controller = "book" action="list" id="${authorInstance?.id}" />
For detail here

Controller is there, but showing "Error code 404 page not found" in grails

new.gsp:
<html>
<head>
</head>
<body>
<g:form name="myForm" controller="New" action="index" params="username:username">
<div>
<fieldset class="form">
<label for="name">Name:</label>
<div>
<g:textField name="username" value="${params.userName}"/>
</div>
</fieldset>
</div>
<g:submitButton name="Submit" value="Submit" />
</g:form>
</body>
<html>
NewController.groovy:
package sample
import com.sun.org.apache.bcel.internal.generic.NEW;
class NewController {
def index = {
if($params.userName){
render(view:"/login.gsp")
}
}
}
login.gsp is a simple page, having a simple welcome note.
if some body the solution please reply,
thanks in advance.
by prasanth
Change your controller name to "new" instead of New in
It will work.
Or else you can modify your "save" action in controller, so that when you click on save button new page will be rendered.
There are a few issues in the posted code that will cause you problems:
You're accessing the parameters with $params instead of params. The $ character is only necessary when you are in a GString. e.g. def foo = "your username is ${params.userName}"
Your view is named new.gsp but your action is named index. Grails will by default look for a view matching the action name in a directory named for the controller. In other words, since you don't tell it explicitly to render /new.gsp grails will look for /new/index.gsp. You can either rename the view to /new/index.gsp or tell grails to render the view new in the index action.
When attempting to render your logged in page, you're calling render(view: 'login.gsp'). The gsp extension is not necessary when calling the render tag. You're intended to use the grails view name, not the filename. render(view: 'login')
If you're using a recent version of grails (>2.0) you should be using controller methods rather than closures. e.g. def actionName() { } as apposed to def actionName() = { }. The reasoning is in the grails documentation.
Here's what it could look like with all the issues addressed:
rename new.gsp to /new/index.gsp. rename login.gsp to /new/loggedIn.gsp.
controller:
class NewController {
def index() {
if (params.userName) {
forward action: 'loggedIn'
return // render and forward don't end flow control
}
}
def loggedIn() {} // no logic, automatically renders '/new/loggedIn.gsp'
}
Add a handler to your controller named login.
def login = {}
If the view file is new.gsp then you need your action to also be new or else have a URL mapping (in UrlMappings.groovy) to do something like:
"/new" {
controller = 'new'
action = 'new'
}
Or you can set
static defaultAction = 'new'
...in your NewController.
Then Grails will find the appropriate action on your controller.
if your action is called index, you can acces the page on
localhost:8080/webapp/NewController

Unable to decode the urlMapping in Grails application

Problem:
I am able to execute the default action(listLatest) of my Controller(ReviewMetricsController). But, I am not able to explicitly invoke other action(index) with form submission.
I am using Grails 2.0.4 and running my application in development mode from Eclipse IDE with Grails plugin installed.
Detail:
I have a form in my gsp as shown below
<g:form name="queryForm"
url="[controller:'reviewMetrics', action:'index']">
<g:actionSubmit value="submit" />
</g:form>
When I submit the above form, I get 404 error
The requested resource (/reviewmetricsapp/reviewMetrics/index) is not available
My Controller(reviewMetricsController.groovy) looks as shown below
package reviewmetricsapp
class ReviewMetricsController {
static scope = "session"
static defaultAction = "listLatest"
def gatherMetricsService
def grailsApplication
def latestMetrics
def index() {
render(view:"dashboard", model: [model: latestMetrics])
}
def listLatest(){
println grailsApplication.config.metricsapp.perlScript.loc
latestMetrics = gatherMetricsService.getLastWeekMetrics()
println "printing ${latestMetrics}"
render(view:"showMetrics", model: [metrics: latestMetrics])
}
}
And my urlMappings.groovy looks as shown below
class UrlMappings {
static mappings = {
"/$controller/$action?/$id?"{ constraints {
// apply constraints here
} }
"/reviewMetrics/index"{
controller="reviewMetrics"
action="index"
}
"/"(view:"/index")
"500"(view:'/error')
}
}
Any help is appreciated
You do not need to change the URLMappings-file for your use-case. (remove the special case handling for reviewMetrics/index - its handled from the first rule)
Please use the following form definition:
<g:form name="queryForm"
controller="reviewMetrics"
action="index">
[..]
</g:form>
Please double check that your action is not accessed - simply put a plain index.gsp and do not care inside the controller. I guess the error is somewhere else.

Resources