Grails

Portlet Support

Details

  • Type: New Feature New Feature
  • Status: Closed Closed
  • Priority: Minor Minor
  • Resolution: Fixed
  • Affects Version/s: None
  • Fix Version/s: 1.1
  • Component/s: Scaffolding
  • Labels:
    None
  • Environment:
    all

Description

would be great to have JSR-168 portlet support using Spring MVC Portlet - which is new in Spring 2.0

Issue Links

Activity

Hide
Graeme Rocher added a comment -

Hi Lee, are you doing this as a plug-in? otherwise it should go in post 1.0

Show
Graeme Rocher added a comment - Hi Lee, are you doing this as a plug-in? otherwise it should go in post 1.0
Hide
Lee Butts added a comment -

Hi Graeme,

yes, it's a plugin - you may have noticed me sneaking a few things into grails core to help it along though

cheers

Lee

Show
Lee Butts added a comment - Hi Graeme, yes, it's a plugin - you may have noticed me sneaking a few things into grails core to help it along though cheers Lee
Hide
Charles Kalleppally added a comment -

Hi Lee,
I have some time (grails newbie) and I am interested in writing a small portlet-bridge plugin. Are you still working on the portlet plug-in?

Show
Charles Kalleppally added a comment - Hi Lee, I have some time (grails newbie) and I am interested in writing a small portlet-bridge plugin. Are you still working on the portlet plug-in?
Hide
Lee Butts added a comment - - edited

Hi Charles,

where I got to is checked into https://svn.codehaus.org/grails-plugins/grails-portlets/trunk

It currently generates the portlet.xml for you and adds the servlets required for Pluto 1.4 to run when you run grails run-app (your portlets are added to the front tab for easy testing).

I don't have anytime to work on it at the moment so feel free to take a look at it. There's no doco unfortunately but basically it looks for *Portlet.groovy in the grails-app/controllers folder and configures portlet.xml based on property name conventions. e.g.

class HelloWorldPortlet{
	def title = 'The Hello World Portlet'
	def description = 'A simple test portlet'
	def displayName = 'Grails Hello World'
	def supports = ['view']

	def count = 0
	
	def doAction = {
		if(params.increment){
			def count = session.getAttribute("counter")
			if(count == null) count = 0
			count += new Integer(params.increment)
			session.setAttribute("counter",count)
		}
	
	}	
	
	def doRender = {
		def val = session.getAttribute("counter")
		if(val == null) val = 0
			[count:val]
	}
}

and

import javax.portlet.*

class PreferencesPortlet{
	def portletService
	def displayName = 'Preferences Example'
	def title = "My Preferences"
	def preferences = [timezone:'GMT+10',cities:['Christchurch', 'Brisbane', 'Gold Coast']]
	
	def supports = ['view','edit']
	
	def doAction = {
		service.setValue(-1)
	}
	
	def doRender = {
		println "#### ${windowState}"
		if(windowState == WindowState.MINIMIZED){
			render('')
		}else{
			return [someVar:"Count from service is ${portletService.getValue()}",
			'mode':mode, state:windowState, portletName:portletConfig.getPortletName(),
			prefs:preferences]
		}
	}

}

the views use a convention similar to the normal grails controllers whereby the view used to render the HelloWorld portlet is found in grails-app/views/helloworld/render.gsp

Show
Lee Butts added a comment - - edited Hi Charles, where I got to is checked into https://svn.codehaus.org/grails-plugins/grails-portlets/trunk It currently generates the portlet.xml for you and adds the servlets required for Pluto 1.4 to run when you run grails run-app (your portlets are added to the front tab for easy testing). I don't have anytime to work on it at the moment so feel free to take a look at it. There's no doco unfortunately but basically it looks for *Portlet.groovy in the grails-app/controllers folder and configures portlet.xml based on property name conventions. e.g.
class HelloWorldPortlet{
	def title = 'The Hello World Portlet'
	def description = 'A simple test portlet'
	def displayName = 'Grails Hello World'
	def supports = ['view']

	def count = 0
	
	def doAction = {
		if(params.increment){
			def count = session.getAttribute("counter")
			if(count == null) count = 0
			count += new Integer(params.increment)
			session.setAttribute("counter",count)
		}
	
	}	
	
	def doRender = {
		def val = session.getAttribute("counter")
		if(val == null) val = 0
			[count:val]
	}
}
and
import javax.portlet.*

class PreferencesPortlet{
	def portletService
	def displayName = 'Preferences Example'
	def title = "My Preferences"
	def preferences = [timezone:'GMT+10',cities:['Christchurch', 'Brisbane', 'Gold Coast']]
	
	def supports = ['view','edit']
	
	def doAction = {
		service.setValue(-1)
	}
	
	def doRender = {
		println "#### ${windowState}"
		if(windowState == WindowState.MINIMIZED){
			render('')
		}else{
			return [someVar:"Count from service is ${portletService.getValue()}",
			'mode':mode, state:windowState, portletName:portletConfig.getPortletName(),
			prefs:preferences]
		}
	}

}
the views use a convention similar to the normal grails controllers whereby the view used to render the HelloWorld portlet is found in grails-app/views/helloworld/render.gsp
Hide
Andreas Brunnert added a comment -

Hi Lee,

Thanks for your fast response! I'm working with Charles on a concept for a portlet specification 2.0 - grails integration and your work will help us a lot to start this work! I hope we can contact you in case we have any specific questions regarding the current state of this project ? I'm also new to grails, is this the portlet integration project that has been announced in the Grails Roadmap for Grails version 1.1 : http://docs.codehaus.org/display/GRAILS/Roadmap ?

Thanks a lot!

Best Regards,
Andreas

Show
Andreas Brunnert added a comment - Hi Lee, Thanks for your fast response! I'm working with Charles on a concept for a portlet specification 2.0 - grails integration and your work will help us a lot to start this work! I hope we can contact you in case we have any specific questions regarding the current state of this project ? I'm also new to grails, is this the portlet integration project that has been announced in the Grails Roadmap for Grails version 1.1 : http://docs.codehaus.org/display/GRAILS/Roadmap ? Thanks a lot! Best Regards, Andreas
Hide
Lee Butts added a comment -

Hi Andreas,

yes, my work so far will hopefully be the base for the Portlet Support. This issue is the one to use to track it's progress.

Feel free to contact me if you need any help - leebutts<a t>gmail<d o t>com

cheers

Lee

Show
Lee Butts added a comment - Hi Andreas, yes, my work so far will hopefully be the base for the Portlet Support. This issue is the one to use to track it's progress. Feel free to contact me if you need any help - leebutts<a t>gmail<d o t>com cheers Lee
Hide
Lee Butts added a comment -

Just a quick update that I will be getting back into development of this in the next couple of weeks now that JSP support is in the 1.1 branch (awesome work Graeme!)

cheers

Lee

Show
Lee Butts added a comment - Just a quick update that I will be getting back into development of this in the next couple of weeks now that JSP support is in the 1.1 branch (awesome work Graeme!) cheers Lee
Hide
Lee Butts added a comment - - edited

I've started on the plugin doco here: http://www.grails.org/Portlets+Plugin

Sample code and tutorials to come soon.

One thing I haven't quite decided on is the action closure convention. One option is to simply have doAction and doRender, the other is to have doRender<portletMode>, doAction<portletMode> e.g. doRenderView, doActionEdit, doActionView and then fall back to doAction/doRender if mode specific closures aren't found.

Does that sound useful to anyone?

cheers

Lee

Show
Lee Butts added a comment - - edited I've started on the plugin doco here: http://www.grails.org/Portlets+Plugin Sample code and tutorials to come soon. One thing I haven't quite decided on is the action closure convention. One option is to simply have doAction and doRender, the other is to have doRender<portletMode>, doAction<portletMode> e.g. doRenderView, doActionEdit, doActionView and then fall back to doAction/doRender if mode specific closures aren't found. Does that sound useful to anyone? cheers Lee
Hide
Maarten Winkels added a comment -

Hi Lee,

Is there any progress on this issue?

I'm investigating the possibility to use Grails for Portlets. The project I'm targetting will start in a few weeks, so we cannot wait for the 1.1 release, therefor I'm trying to run the plugin on 1.0.4.

I'm trying to make it run on JBoss Portal first, because that is the target platform for this client. The main problem I'm running into is that, looking at the plugin code, the Pluto implementation uses a PortletRequest implementation that is also a HttpServletRequest implementation (same for response). Unfortunately in the JBoss implementation this is not the case: The PortletRequest is wrapped around the original HttpServletRequest. I've adapted the GrailsPortletHandlerInterceptor to check for the JBoss case (very ugly though) and then unwrap the original HttpServletRequest/Response.

The next problem I run into is that in the render phase, the controller is not bound as a request attribute. If I read the code correctly, the controller is add as an attribute to the PortletRequest. In the Pluto case this will work, because the PortletRequest IS the ServletRequest that is later passed on to the ViewServlet per include. In the JBoss case, since the two requests are different, the attribute gets lost.

This is as far as I got now.

Cheers,

-Maarten Winkels

Show
Maarten Winkels added a comment - Hi Lee, Is there any progress on this issue? I'm investigating the possibility to use Grails for Portlets. The project I'm targetting will start in a few weeks, so we cannot wait for the 1.1 release, therefor I'm trying to run the plugin on 1.0.4. I'm trying to make it run on JBoss Portal first, because that is the target platform for this client. The main problem I'm running into is that, looking at the plugin code, the Pluto implementation uses a PortletRequest implementation that is also a HttpServletRequest implementation (same for response). Unfortunately in the JBoss implementation this is not the case: The PortletRequest is wrapped around the original HttpServletRequest. I've adapted the GrailsPortletHandlerInterceptor to check for the JBoss case (very ugly though) and then unwrap the original HttpServletRequest/Response. The next problem I run into is that in the render phase, the controller is not bound as a request attribute. If I read the code correctly, the controller is add as an attribute to the PortletRequest. In the Pluto case this will work, because the PortletRequest IS the ServletRequest that is later passed on to the ViewServlet per include. In the JBoss case, since the two requests are different, the attribute gets lost. This is as far as I got now. Cheers, -Maarten Winkels
Hide
Lee Butts added a comment -

Hi Maarten,

I haven't tried the plugin with JBoss but I do recall commenting some code with '// This may only work in Pluto"

The plugin might be ok in 1.0.4 as long as you don't want to post any forms. To be able to get a portlet posting you need to use the portlet API taglib provided by the Portal. This can only be done in 1.1 due to the need to call a JSP tag from GSP.

Alternatively, you could write your views in JSP but I haven't tried that.

If you want to arrange a chat on skype/gmail/whatever about this, send me an email (leebutts <at> gmail <dot> com. I live in GMT+10 timezone so it might require some scheduling.

cheers

Lee

Show
Lee Butts added a comment - Hi Maarten, I haven't tried the plugin with JBoss but I do recall commenting some code with '// This may only work in Pluto" The plugin might be ok in 1.0.4 as long as you don't want to post any forms. To be able to get a portlet posting you need to use the portlet API taglib provided by the Portal. This can only be done in 1.1 due to the need to call a JSP tag from GSP. Alternatively, you could write your views in JSP but I haven't tried that. If you want to arrange a chat on skype/gmail/whatever about this, send me an email (leebutts <at> gmail <dot> com. I live in GMT+10 timezone so it might require some scheduling. cheers Lee
Hide
Graeme Rocher added a comment -

Moving non-critical issues that aren't going to make it into 1.1 to 1.2

Show
Graeme Rocher added a comment - Moving non-critical issues that aren't going to make it into 1.1 to 1.2
Hide
Aaron Fuleki added a comment -

What's necessary to get this working, or at least get something cut such that you can install the plugin?

Show
Aaron Fuleki added a comment - What's necessary to get this working, or at least get something cut such that you can install the plugin?
Hide
Lee Butts added a comment -

You can check it out from SVN, build it and install it via install-plugin <zip file>.

I don't think anyone has had any luck getting it to deploy to Liferay or JBoss but I did get it running on Jetspeed. It usable for readonly/very simple use cases but not complex flows as the action conventions are not right (IMO).

I like Marcels suggestion to start again and split it into two plugins - one that generates the portlet.xml for you and provides some nice convention around Spring Portlet MVC and one (or more) portal plugins which will start when you call run-app and auto deploy your portlets (retaining Grails' reloading functionality) for rapid development and testing.

cheers

Lee

Show
Lee Butts added a comment - You can check it out from SVN, build it and install it via install-plugin <zip file>. I don't think anyone has had any luck getting it to deploy to Liferay or JBoss but I did get it running on Jetspeed. It usable for readonly/very simple use cases but not complex flows as the action conventions are not right (IMO). I like Marcels suggestion to start again and split it into two plugins - one that generates the portlet.xml for you and provides some nice convention around Spring Portlet MVC and one (or more) portal plugins which will start when you call run-app and auto deploy your portlets (retaining Grails' reloading functionality) for rapid development and testing. cheers Lee
Hide
Lee Butts added a comment -

I'm going to resolve this issue now that the Portlet plugin(s) are released and maintained by Kenji.

cheers

Lee

Show
Lee Butts added a comment - I'm going to resolve this issue now that the Portlet plugin(s) are released and maintained by Kenji. cheers Lee

People

Vote (25)
Watch (25)

Dates

  • Created:
    Updated:
    Resolved: