This question has been asked of me, in various ways, in various places, at least a dozen times in the past year. In fact, I've probably manufactured 2 or 3 incarnations of Server API code to solve it. Since the last question came in the form of "can you blog about how you did that?"... here I am.
What do I mean by "a portlet by itself" ? How about an XML tag that renders a portlet when it's passed that portlet's object ID, or a page that renders a single portlet when passed that portlet's ID on the query string:
Figure 1 - The login portlet by itself on a page.
So what? Why in the world would anyone want this kind of capability? The better question is... why wouldn't anyone want this? What I'm really talking about is everybody's favorite Web 2.0 technology: the much ballyhooed mashup. Using the above, you could write your own drag and drop portlet interface, combine dynamic sets of information, and dramatically simplify it all by encapsulating display on remote servers or in portlet containers.
Don't worry, though, this sentence is the last one in which I'll use the words mashup or Google Maps. I promise.
How can I get cool functionality like this in my portal?
I'm glad you asked. You can start by reading this post. You can follow up by downloading the source at the end of the article (or you can cheat and click that link). Finally, you can do some of the cool things with it I may or may not have already done: create tags that display portlets, implement caching, and do all kinds of fun AJAX stuff on your portal pages.
Unfortunately for you .NET guys (I promise I will provide more .NET source in the future), I'm writing it in Java. Not to worry, though. Download your favorite zip editor, open the jar file and extract the .java files. They should be fairly simple to translate.
Breaking Down the 'How'
What I've done in the above screen shot is create a custom Activity Space in the portal. You can read about some of the basics of this process here. This space lets me do the following:
- Read in a query string containing some combination of portlet ID, page ID and community ID.
- Pass this information to a utility class called DisplayPortletUtility (I am not very creative in my naming conventions).
- Use the utility class to instantiate a "fake" portlet request through the back end portlet provider.
- Grab the resulting HTML markup from the fake request.
- Throw it back out on a page (Display Page, actually).
The real meat and bones of this entire project is the DisplayPortletUtility class. The code that does the heavy lifting has actually been hacked out of the com.plumtree.portalpages.browsing.portletpreview section of the UI source code distributed with the portal. Most of the work was in cleaning up and understanding what that section of code was doing. Now that I've done that, you can benefit by reading my simple, somewhat well commented, source =).
The second "hard" part of this process is instantiating the page and space itself. Unfortunately, the source distributed with the portal is not quite user friendly. I've done some of the heavy lifting for you by compacting and deleting large amounts of code, until you have what I've provided here.
To use this code, simply edit your CustomActivitySpaces.xml file and include the jar in your portal.war (or bin directory).
Finally, as I provide you a link to the source, I want to point out that the portlet requests made by this code are not cached (they don't respect the web service settings I blogged about earlier), which means you're on your own if you want to put this into production.
Happy mash... er.. portlet displaying!
Leave a comment