[2.0] Render controller action in view

734 views
Skip to first unread message

Leon Radley

unread,
Apr 5, 2012, 4:02:15 AM4/5/12
to play-fr...@googlegroups.com
In symfony2 I frequently use the possibility to render another controllers action in another view.

{% render "AcmeArticleBundle:Article:recentArticles" with {'max': 3} %}

It would be great if we also could call an action and have it included in the current view.
Since we can call other views, I think it would make sense to also be able to call other actions?

Pseudo code:
@controller.MyController.list(3)


Is it possible?





Julien Richard-Foy

unread,
Apr 5, 2012, 4:06:53 AM4/5/12
to play-fr...@googlegroups.com
I’m not sure it makes sense to call an action from a view. An action
is intended to respond to a HTTP request.
Nevertheless, you can write a controller method and call it from your
action as well as from your view.

Leon Radley

unread,
Apr 5, 2012, 4:09:50 AM4/5/12
to play-fr...@googlegroups.com
How would the syntax for calling it from my view look?

Since the toString of the action gets called, the only output I get is 
Action(parser=BodyParser((no name)))

Julien Richard-Foy

unread,
Apr 5, 2012, 4:17:00 AM4/5/12
to play-fr...@googlegroups.com
I think you don’t want to call an action. Maybe just a method.

Guillaume Bort

unread,
Apr 5, 2012, 5:13:16 AM4/5/12
to play-fr...@googlegroups.com
An Action takes a Request and returns a Result. It is surely not what
you want to call from a view since a Result is not something you can
embed in HTML (what about HTTP headers, status code, cookies, response
content if it is not HTML, etc.?)

On Thu, Apr 5, 2012 at 10:17 AM, Julien Richard-Foy <j...@zenexity.com> wrote:
> I think you don’t want to call an action. Maybe just a method.
>

> --
> You received this message because you are subscribed to the Google Groups "play-framework" group.
> To post to this group, send email to play-fr...@googlegroups.com.
> To unsubscribe from this group, send email to play-framewor...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/play-framework?hl=en.
>

--
Guillaume Bort

Mohamed Seifeddine

unread,
Apr 5, 2012, 7:29:23 AM4/5/12
to play-fr...@googlegroups.com
I would have to disagree with people suggesting it is not something desirable. 

Grails started to offer this at some version. 

The reason to why it is useful is that with todays ajax applications, you might want to preload content in a view, that is normally loaded through an ajax call. So (grails) <g:include controller=... .action=... /> would place the rendered text in that place. Some preprocessing and what not might occur, before the view gets rendered, so just rendering the view would not be an option. The option would be redundant code if this is not supported. 


Here comes my rant:
I also should discourage anyone from answering someones question by, "you shouldnt do this and that here and there". I personally loath such answers. The person asked a question, and is looking for an answer, not to give you an explanation to why they want to do this and that. 
When someone tries to decide for others how things should be done, just because there is a percieved notion of how things are done, which often is radical and flawed when taking account all scenarios, it is almost always the case that such frameworks fails in offering developers full simplicity. Th

I argue that everything should be possible, from everywhere I as a developer choose to. The framework should not force developers to do things in a certain way because framework design flaws are always going to appear and frameworks will continue to be improved. Only by giving us as much freedom as possible can we choose better paths where the framework fails. This is especially important for plugin/module developers. With grails you can hook into almost any action that it performs itself, and almost all objects and methods are accessible from everywhere except a few places ( like the g library from a filter ( i might want to set/get a cookie or message using that taglib) which in my opinion needs to be added as well.

If this is not supported, then it should, and if called from a view it should ouput the response without all the headers if that is the case. 

// Moe

Julien Richard-Foy

unread,
Apr 5, 2012, 8:01:12 AM4/5/12
to play-fr...@googlegroups.com
You can call any controller method from a view. But calling an action
is probably not useful, as Guillaume said.
You’re free to write a method which renders a HTML fragment and call
this method from your ajax action and from your view.

Mohamed Seifeddine

unread,
Apr 5, 2012, 8:10:55 AM4/5/12
to play-fr...@googlegroups.com
On Thu, Apr 5, 2012 at 2:01 PM, Julien Richard-Foy <j...@zenexity.com> wrote:
You can call any controller method from a view. But calling an action
is probably not useful, as Guillaume said.

Probably is not good enough. As I said, it is useful. Some sites load their page, then onload they perform ajax calls to load variuos default things, which will cost them lots of unnessary cost of additional requests. This is not recommended but not uncommon ... 

You shouldn't have to have a second method either, but for now, it might be good enough, although ideal way would be to go through the same path as a normal request usually does, through filters/interceptors and what not before arriving to the action method... I am guessing the suggested way wont?




 
 
You’re free to write a method which renders a HTML fragment and call
this method from your ajax action and from your view.

Guillaume Bort

unread,
Apr 5, 2012, 9:02:51 AM4/5/12
to play-fr...@googlegroups.com
> You shouldn't have to have a second method either, but for now, it might be
> good enough, although ideal way would be to go through the same path as a
> normal request usually does, through filters/interceptors and what not
> before arriving to the action method... I am guessing the suggested way
> wont?

For Scala Action it will, since there is no magic and all filters are
applied by clean function composition. For Java Action it won't since
composition is expressed via Annotations and is applied at runtime by
the framework.

I still don't see how we could embed a Result in an HTML page. What
about the response headers? What if the result is asynchronous
(meaning a promise of Result, only available in 10 seconds)? What if
it a stream? And non 2xx response?

To summarize what if the result is something else than a 200 OK,
Content-Type: text/html without any cookie header?

You talk about simplicity, but allowing that would just add huge
complexity: no one could predict the result of calling an Action from
another Action.

--
Guillaume Bort

Mohamed Seifeddine

unread,
Apr 5, 2012, 9:50:14 AM4/5/12
to play-fr...@googlegroups.com
What if the result is just text? 

I mean when you render  a template, you expect the result to be text, when including the response from an action, why not hand over the responsibility to the developer to know that it is stupid not to render a byte stream in an html page. 

And how come Grails offers this?

Text is the most common response as well. If Json, the developer should probably use that response in an intelligent way.

If there are cases where this is useful, why should it not be possible?

Guillaume Bort

unread,
Apr 5, 2012, 10:03:46 AM4/5/12
to play-fr...@googlegroups.com
It is possible. It is the developer's responsibility to organize its
code properly for that. For example:

// This is an action
public static Result index() {
return ok(
views.html.index(
anHtmlPartialFragment()
)
);
}

// This is an action
public static Result ajaxCall() {
return ok(anHtmlPartialFragment());
}

public static Html anHtmlPartialFragment() {
Items items = // retrieve some values from the database
return views.html.partial(items);
}

Here you get the index action rendering the whole page with the HTML
fragment pre-rendered, and still you can write a ajax action rendering
only the HTML fragment without any code duplication.

The current design we have, with a clear separation between the
template rendering and the HTTP response representation, allow to do
that without any magic or hack. We don't need to introduce something
new.

Mohamed Seifeddine

unread,
Apr 5, 2012, 10:30:42 AM4/5/12
to play-fr...@googlegroups.com
You also mentioned earlier that it was supported for Scala but not Java, when it came to the interceptors/filterrs and preproccessing of an action.

Plus, that was three methods where it could have been just one, multiply that with 10 other actions, and you have 30 method declarations. 

It is not a big thing for me personally, I am just saying that rather than performing an ajax call at the client that returns text, json or xml, one could do the call at the server already and keep the controller intact with no modifications.

Aleksandr Fedorov

unread,
Apr 13, 2012, 10:28:35 AM4/13/12
to play-fr...@googlegroups.com
I think it's very useful thing, I did it by the following code:

public class Application extends Controller {

  public static String nav() {
    return nav.render(Category.all()).body();
  }
}

In view:

@Html(Application.nav())
Reply all
Reply to author
Forward
Message has been deleted
0 new messages