I'm trying to build a common page layout with a main content div and a sidebar with the Play framework:
<html>
<head></head>
<body>
<div id="all">
<div id="content">the ususal doLayout stuff</div>
<div id="sidebar">
<div class="widget">Recent comments...</div>
<div class="widget">Recent posts...</div>
other Widgets...
</div>
</div>
</body>
</html>
Is it possible to render the widgets in the sidebar without preventive binding of the content of the widgets in each controller? Even if there is no such widget in the template, I would have to get all the data required.
I recently used the Lift Framework and could write just <div class="lift:someWidget.news">
. This calls the news
method in the someWidget
class to render the widget. It is possible to retrieve data from the database in that method, so there's no need for preventive binding. Is there something similar in Play to save unnecessary DB queries and unrelated code in the controller?
Yes. Here are my preferred two options. The right option depends on your particular use case.
Option 1 - Use the @before notation
By using the @before annotation, you can execute common processing on each action that is invoked. It will execute the method before the main action is executed, allowing you to store your data in the renderArgs
map, which is the available within the view.
This data in the view can then be access in your main template, and therefore available in all views.
Option 2 - Use AJAX
Put a few divs as placeholders as you have done in your example, and then use the JQuery load that will call an action on your serverside to generate a small piece of HTML just for the snippet that you require.
You can call a static controller method from a template. Note the @Util - Annotation to tell Play that this is not meant as a action - method:
@Util
public static List<Post> getPosts() {
...
}
Then call this from your template (perhaps a custom tag):
<div class="widget">
%{
def posts=controllers.Post.getPosts()
for(post in posts) {
}%
<h2>${post.header}</h2>
<p>${post.body}</p>
%{
}
}%
</div>
As this is violating the pure MVC-Pattern i would not recommend to use this heavily. But used wisely it can be a really pragmatic solution. And your use-case to build a sidebar in a general layout is perfectly valid usage (in my opinion) - if you later decide to provide a json representation of your data in the main content your layout sidebar is not used - and therefore the data is not fetched when using this pattern.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With