-
1. Re: Custom navigation region
johnnythehun Dec 3, 2008 4:56 PM (in response to johnnythehun)I have found the solution, but I would like to ask the Portal developers if there is a more elegant solution.
If not, will a later version of JBoss Portal support
- injecting default portlets into "special" regions (like the navigation region, but with real portlets)
- or support markup in layouts that specify portlets to be injected at the place of the markup, for example<p:injectPortlet instance="InjectMePortletInstance"> <parameters/> </p:injectPortlet>
And the solution for Injecting content to a custom region for the current version is:
1. Create a class Named
MyPageCustomizerInterceptor that extends ControllerInterceptor
2. Get JBoss source and copy the contents of:
org.jboss.portal.core.aspects.controller.PageCustomizerInterceptor
into your class code.
Import a bunch of JBoss libraries
3. there is a part in the code in the "invoke" method:if (tabbedNav != null) { .... }
instantly after this code insert the following (of course modified to your preferences). Modify the "BLAH2" and the "inject_region" strings to your needs.String toInject = "<h1>AT LAST! I have injected my custom stuff!</h1>"; Map windowProps = new HashMap(); windowProps.put(ThemeConstants.PORTAL_PROP_WINDOW_RENDERER, "emptyRenderer"); windowProps.put(ThemeConstants.PORTAL_PROP_DECORATION_RENDERER, "emptyRenderer"); windowProps.put(ThemeConstants.PORTAL_PROP_PORTLET_RENDERER, "emptyRenderer"); WindowResult res = new WindowResult("", toInject, Collections.EMPTY_MAP, windowProps, null, WindowState.NORMAL, Mode.VIEW); WindowContext blah = new WindowContext("BLAH2", "inject_region", "0", res); rendition.getPageResult().addWindowContext(blah); Region region = rendition.getPageResult().getRegion2("inject_region"); DynaRenderOptions.NO_AJAX.setOptions(region.getProperties());
3. Put your classes into a jar and put them under
JBOSS_HOME\server\default\lib\
4. Modify
JBOSS_HOME\server\default\deploy\jboss-portal.sar\META-INF\jboss-service.xml
replace org.jboss.portal.core.aspects.controller.PageCustomizerInterceptor in<mbean code="org.jboss.portal.core.aspects.controller.PageCustomizerInterceptor"
with the full classname of your class -
2. Re: Custom navigation region
johnnythehun Dec 4, 2008 4:55 AM (in response to johnnythehun)I have been thinking about this concept.
Wouldn't it be a more elegant solution if I would use a custom regionRenderer, that renders a specific portlet if it finds a
injectPortlet="MyPortletToInjectInstance"
property in a region?
But I don't know how to do this.
What I found, is that the
1. DivRegionRenderer iterates through RegionRendererContext.getWindows()
Of course this getWindows() function will not return a WindowRendererContext for the injected portlet since it is not configured via xml or the admin page.
2. For every WindowRendererContext it renders the window via RendererContext.render()
So I assume I need to create a WindowRendererContext for every injected portlet too and call the RendererContext.render() with them.
3. JBoss implements whis WindowRendererContext with the WindowContext class.
The constructor of this class is:
WindowContext(java.lang.String id, java.lang.String regionName, java.lang.String order, WindowResult result)
- What is the id?
- regionname I can handle
- what is the order?
I think the above parameters can be easily created, but for the last parameter - WindowResult - I have no idea what to write.
The constructor of WindowResult is:
WindowResult(java.lang.String title, java.lang.String content, java.util.Map actions, java.util.Map windowProperties, java.util.List<org.w3c.dom.Element> headerContent, org.jboss.portal.WindowState windowState, org.jboss.portal.Mode mode)
Can anyone help me on this? -
3. Re: Custom navigation region
johnnythehun Dec 4, 2008 5:24 AM (in response to johnnythehun)Ok, I don't get where the portlet markup get's created.
I see that the WindowContext already get's the markup via its String content parameter, so I need to create the portlet markup BEFORE instanciating a WindowContext
But how do I create the markup for a specific portlet instance?
What is the class that I can instanciate or the utility I can call to create the markup?
I looked at DivPortletRenderer which calls PortletRendererContext.getMarkup() to get the markup.
PortletRendererContext is implemented via PortletRendererContextImpl.
The getMarkup() function of PortletRendererContextImpl gets the markup from the WindowContext.
So now I'm in a circle - I have to create the markup before any XYContext comes into the picture. But I don't know what creates the markup for a Portlet instance.
The best would be to have some Class or Function like:
new PortletMarkupGenerator(String portletInstanceName).getMarkup();
I found some code in the injectTabbedNav of PageCustomizerInterceptor class:public String injectTabbedNav(PageCommand rpc) { ControllerContext controllerCtx = rpc.getControllerContext(); ControllerRequestDispatcher rd = controllerCtx.getRequestDispatcher(targetContextPath, tabsPath); // if (rd != null) { Page page = rpc.getPage(); PortalAuthorizationManager pam = portalAuthorizationManagerFactory.getManager(); PortalNodeImpl node = new PortalNodeImpl(pam, page); // rd.setAttribute("org.jboss.portal.api.PORTAL_NODE", node); rd.setAttribute("org.jboss.portal.api.PORTAL_RUNTIME_CONTEXT", Navigation.getPortalRuntimeContext()); // rd.include(); return rd.getMarkup(); } return null; }
The following lines are used to access the jsp to create the tabs:ControllerContext controllerCtx = rpc.getControllerContext(); ControllerRequestDispatcher rd = controllerCtx.getRequestDispatcher(targetContextPath, tabsPath);
1. This function renders a jsp file, it doesn't render a Portlet.
2. This function uses a PageCommand instance to create the markup. But I don't see that a RegionRenderer gets a PageCommand parameter
So the best would still be to have some Class or Function like:
new PortletMarkupGenerator(String portletInstanceName).getMarkup(); -
4. Re: Custom navigation region
psevestre Dec 5, 2008 8:42 AM (in response to johnnythehun)Hi,
I've faced a similar problem: A main menu with top-level pages and an accordion-style sidebar menu.
My solution:
1. In tabs.jsp, I always render both menus (ul/li structures)
2. In layout pages, I have two instances of the "navigation" region, using distinct "regionID" values.
3. In the theme CSS files, I show/hide the unwanted menu for each case, using the different regionIDs.
As an optimization, you can save the rendered markup on step 1 at session level when called from the first occurence of the nav region and use this cached data to render subsequent calls. -
5. How to implement custome navigation
nareshkumar.sanda Mar 17, 2009 5:26 PM (in response to johnnythehun)hai,
I have a portlet in that i have some links when i click that appropriate portlet should be displayed in the right side of the portal page.How can i implement these king of communication between the portlets.
Thanks
-naresh -
6. Re: Custom navigation region
soundspeace Apr 5, 2009 10:09 PM (in response to johnnythehun)all the problem that you want to resolve.
just need edit in CSS only.
make sure make another id css such as :-
#navigationFooter {
}
#navigationFooter #tabHeader{
}
#navigationFooter #tabHeader ul{
}
something like this la... just give idea