Skip navigation.
Downloads | Product Documentation | Support

Extending the Administration Console

# Adding Portlets and Navigation Controls

In the Administration Console, all content is contained within portlets, so even the most minimal extension must define a portlet (and content for the portlet). You can add your portlet directly to the desktop, but if you want the portlet to display as a tab or subtab in the `ContentBook`, you must define books or pages to contain it. Your extension can also add a node to the NavTreePortlet, which enables users to navigate to your portlet directly from the desktop.

This section describes how to add portlets, UI controls, and NavTreePortlet nodes to the Administration Console.

Figure 6-1 illustrates the process. The steps in the process, and the results of each are described in Table 6-1. Subsequent sections detail each step in the process.

Figure 6-1 Adding Portlets and Navigation Controls Development Overview

Table 6-1 Model MBean Development Tasks and Results

Step | Description | Result
--- | --- | ---
1. Define a Portlet. | Create an XML file to define a portlet that the portal framework can instantiate. A portlet definition includes instructions on which type of data to load: JSPs, Struts Actions, or Beehive Page Flows. The portal's Look and Feel determines whether the portlet provides borders and minimize/maximize controls. | A `.portlet` XML file.
2.Define UI Controls (Optional). | If you want your portlet to display in a tab, subtab, or in some other location within `ContentBook`, create an XML file that defines a page or book. | A `.pinc` XML file.
3. Specify a Location for Displaying Portlets or UI Controls. | Create an XML file that describes whether you want your portal to display next to a labeled UI control or to replace the control. | A `netuix-extension.xml` file.
4. Add Nodes to the NavTreePortlet (Optional). | You can create a link from the NavTreePortlet to any book or page in your extension. WebLogic Server provides default support for appending control names to the end of the existing navigation tree. If you want to insert nodes in specific locations, or if you want to create a node tree, you create your own Java classes that describe the node and node location. | Additional entries in the `.pinc` XML file. Optionally, Java classes that give you more control over the node that you are adding.
5. Archive and deploy the extension. | See Archiving and Deploying Console Extensions. | A JAR file that contains your extension.

# Define a Portlet

You define a portlet in an XML file. The portlet definition includes instructions on which type of data to load: JSPs, Struts Actions, or Beehive Page Flows. The following sections describe how to define a portlet:

- Define a JSP Portlet
- Define a Struts Portlet
- Define a Page Flow Portlet
- Displaying a Title Bar for a Portlet

For more information about portlet XML files, see the portlet entry in Portal Support Schema Reference.

## Define a JSP Portlet

To define a portlet that loads a JSP:

1. Copy the code from Listing 6-1 and paste it into a new text file in `root-dir``/portlets` (see Create a Directory Tree for the Extension).

Consider using the following naming convention:
`content-name``.portlet`

where `content-name` is the name of a JSP file that the portlet contains. For example, if the portlet contains a JSP file named `monitorEJB.jsp`, then name the portlet XML file `monitorEJB.portlet`.

2. Replace the values in Listing 6-1 as follows:

- `Label`. Provide a unique identifier that the portal framework uses to identify this portlet.
- (optional) `Title`. Provide a default title that this portlet displays if its title bar is visible. See Displaying a Title Bar for a Portlet.
- `URI`. Specifies the absolute path and file name of the JSP that the portlet contains starting from the root of the extension.

For example:
`/ext_jsp/monitorEJB.JSP`

Listing 6-1 Template for a Portlet XML File that Loads a JSP File

>     <?xml version="1.0" encoding="UTF-8"?>
>     <portal:root xmlns:html="http://www.w3.org/1999/xhtml-netuix-modified/1.0.0"
>        xmlns:portal="http://www.bea.com/servers/netuix/xsd/portal/support/1.0.0"
>        xmlns:netuix="http://www.bea.com/servers/netuix/xsd/controls/netuix/1.0.0"
>        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>        xsi:schemaLocation="http://www.bea.com/servers/netuix/xsd/portal/
>           support/1.0.0 portal-support-1_0_0.xsd">

>        <netuix:portlet definitionLabel="Label" title="Title" >
>           <netuix:content>
>              <netuix:jspContent contentUri="URI"/>
>           </netuix:content>
>        </netuix:portlet>

>     </portal:root>

## Define a Struts Portlet

Instead of encapsulating your extension's business logic and navigation logic in JSP files, you can use the Apache Struts framework. See Create Struts Artifacts for Tables and Forms.

To create a portlet that loads (forwards to) a Struts Action:

1. Copy the code from Listing 6-2 and paste it into a new text file in `root-dir``/portlets` (see Create a Directory Tree for the Extension).

Consider using the following naming convention:
`action-name``.portlet`

where `action-name` is the name of the Struts Action to which the portlet forwards.

2. Replace the values in Listing 6-2 as follows:

- `Label`. Provide a unique identifier that the portal framework uses to identify this portlet.
- (optional) `Title`. Provide a default title that this portlet displays if its title bar is visible. See Displaying a Title Bar for a Portlet.
- `Struts-module`. Specifies the Struts module that defines a Struts Action.

You must create your own Struts module to define the Actions and ActionForms that your Administration Console extension uses; the default Struts module is reserved for BEA Actions and ActionForms. Each module includes its own, uniquely named configuration file. For information about Struts modules, see the Apache Struts User Guide at http://struts.apache.org/struts-doc-1.2.x/userGuide/index.html.

For example, if you specify "`myModule`" for `Struts-module`, the Struts controller servlet looks in the following location for the action:
`root-dir``/WEB-INF/struts-auto-config-myModule.xml`

- `action-path`. Specifies the path to a Struts Action that is defined in your Struts module.
- `refresh-action-path`. Specifies the `Action` to invoke on subsequent requests for this portlet (for example, the user agent refreshes the document).

Note that this `.portlet` does not specify the name of a JSP. Instead, typically the Struts Action mapping forwards to a specific JSP upon successful operation.

Listing 6-2 Template for a Portlet XML File that Forwards to a Struts Action

>     <?xml version="1.0" encoding="UTF-8"?>
>     <portal:root xmlns:html="http://www.w3.org/1999/xhtml-netuix-modified/1.0.0"
>        xmlns:portal="http://www.bea.com/servers/netuix/xsd/portal/support/1.0.0"
>        xmlns:netuix="http://www.bea.com/servers/netuix/xsd/controls/netuix/1.0.0"
>        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>        xsi:schemaLocation="http://www.bea.com/servers/netuix/xsd/portal/
>           support/1.0.0 portal-support-1_0_0.xsd">

>        <netuix:portlet definitionLabel="Label" title="Title" >
>          <netuix:strutsContent module="Struts-module"
>               action="action-path"
>               refreshAction="refresh-action-path"/>
>        </netuix:portlet>
>     </portal:root>

## Define a Page Flow Portlet

To define a portlet that loads a Beehive Page Flow:

1. Copy the code from Listing 6-3 and paste it into a new text file in `root-dir``/portlets` (see Create a Directory Tree for the Extension).

Consider using the following naming convention:
`pageFlow-name``.portlet`

where `pageFlow-name` is the name of the Page Flow that the portlet loads (forwards to). For example, if the portlet forwards to a Page Flow named `myPageFlow.jpf`, then name the portlet XML file `myPageFlow.portlet`.

2. Replace the values in Listing 6-3 as follows:

- `Label`. Provide a unique identifier that the portal framework uses to identify this portlet.
- (optional) `Title`. Provide a default title that this portlet displays if its title bar is visible. See Displaying a Title Bar for a Portlet.
- `URI`. Specifies the absolute path and file name of the JPF file that defines the Page Flow. The URI must be absolute starting from the `root-dir``/WEB-INF/classes` directory.

For example, if your JPF file is `root-dir``/WEB-INF/classes/com/mycompany/extension/pageflows/myPageFlow.jpf`, specify the following value
`/com/mycompany/extension/pageflows/myPageFlow.jpf`

- `Action`. Specifies the absolute path and file name of the JPF file that defines the Page Flow.

Listing 6-3 Template for a Portlet XML File that Forwards to a Page Flow

>     <?xml version="1.0" encoding="UTF-8"?>
>     <portal:root xmlns:html="http://www.w3.org/1999/xhtml-netuix-modified/1.0.0"
>        xmlns:portal="http://www.bea.com/servers/netuix/xsd/portal/support/1.0.0"
>        xmlns:netuix="http://www.bea.com/servers/netuix/xsd/controls/netuix/1.0.0"
>        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>        xsi:schemaLocation="http://www.bea.com/servers/netuix/xsd/portal/
>           support/1.0.0 portal-support-1_0_0.xsd">

>        <netuix:portlet definitionLabel="Label" title="Title" >
>           <netuix:content>
>               <netuix:pageflowContent
>                      contentUri="URI"
>                      action="Action"/>
>                      refreshAction="refresh-Action"/>
>           </netuix:content>
>        </netuix:portlet>

>     </portal:root>

## Displaying a Title Bar for a Portlet

If you plan to locate a portlet on the Administration Console desktop (within a placeholder on the "`page`" page), configure the portlet to display a title bar. If you locate a portlet in the `ContentBook`, do not display a title bar.

To display a title bar:

1. In the portlet's `.portlet` XML file, provide a value for the `title` attribute of the `netuix:portlet` element. To display a localized value, see Localizing a Portlet Title.
2. Include the following element as a child of the `netuix:portlet` element:

`<netuix:titlebar/>`

To enable the portlet to be minimized and maximized, include the following stanza instead of the empty `<netuix:titlebar/>` element:

`<netuix:titlebar>
` `<netuix:minimize/>
` `<netuix:maximize/>
</netuix:titlebar>`

Listing 6-4 defines a portlet that displays a title bar. The portlet can be minimized or maximized and the title value comes from a message bundle.

Listing 6-4 Example: Portlet that Displays a Localized Title

>     <?xml version="1.0" encoding="UTF-8"?>
>     <portal:root xmlns:html="http://www.w3.org/1999/xhtml-netuix-modified/1.0.0"
>        xmlns:portal="http://www.bea.com/servers/netuix/xsd/portal/support/1.0.0"
>        xmlns:netuix="http://www.bea.com/servers/netuix/xsd/controls/netuix/1.0.0"
>        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>        xsi:schemaLocation="http://www.bea.com/servers/netuix/xsd/portal/
>           support/1.0.0 portal-support-1_0_0.xsd">

>        <netuix:portlet definitionLabel="medrecEAR.Monitor.Portlet"
>            title="medrecMBean.myPortlet.title"
>            backingFile="com.bea.medrec.extension.utils.DesktopViewBacking">
>           <netuix:titlebar>
>               <netuix:minimize/>
>               <netuix:maximize/>
>           </netuix:titlebar>
>           <netuix:content>
>              <netuix:strutsContent module="/medrecMBean"
>                   action="RetrieveCustomMBeansAction"
>                    refreshAction="RetrieveCustomMBeansAction"/>
>           </netuix:content>
>        </netuix:portlet>
>     </portal:root>

### Localizing a Portlet Title

By default, the portlet displays the literal value that you enter in the <netuix:portlet> element's `title` attribute. To enable this title to be localized:

1. Create a Java class that retrieves the value of the `title` attribute, scans a property file for a key that matches the `title` attribute value, and returns the value of the property key.

For example, if you specify `title="myPortlet.title"`, the Java class looks through your message bundle for `myPortlet.title=MyCompany's Portlet` and returns `MyCompany's Portlet` as the text to be displayed.

See Create a Backing Class for Localizing Portlet Titles.

2. In the `.portlet` file, include the following attributes in the <netuix:portlet> element:

- `title`. Specify the key for a property that you have defined in your message bundle.
- `backingFile`. Specify the fully-qualified name of a Java class that you created in the previous step.

For example:
`<netuix:portlet definitionLabel="myPortlet" title="myPortlet.title"
backingFile="com.mycompany.extension.utils.MyPortletBacking">`

#### Create a Backing Class for Localizing Portlet Titles

A backing class is a Java class that interacts directly with the portal framework APIs. To create a backing class that retrieves localized portlet titles:

1. Extend
   `com.bea.netuix.servlets.controls.content.backing.AbstractJspBacking`.
2. Implement the `AbstractJspBacking.preRender(HttpServletRequest request, HttpServletResponse response)` method.

See `AbstractJspBacking.preRender()` in the WebLogic Portal API Reference.

In your implementation of this method:

1. Get the locale from the `HttpServletRequest` object.

Use the following API:
`javax.servlet.http.HttpServletRequest.getSession().getAttribute( "org.apache.struts.action.LOCALE")`

2. Get the message bundle.

Use the following API:
`org.apache.struts.util.MessageResources.getMessageResources(
"``myBundle``");`
where `myBundle` is the name of your message bundle. (See Creating a Message Bundle.)

3. Get the value of the portlet's `title` property.

Use the following APIs:
`PortletBackingContext bctx =
PortletBackingContext.getPortletBackingContext(
HttpServletRequest req);
MessageResources.getMessage(``locale``, bctx.getTitle());`

where `locale` is the locale that you retrieved from the `HttpServletRequest` object.

4. Reset the value of the portlet's `title` property to the localized value that you retrieved in the previous step.

Use the following API:
`PortletBackingContext.getTitle(String` `title``)`
where `title` is the value that you retrieved from the message bundle.

Listing 6-5 Example: Backing Class for Localizing a Portlet Title

>     package com.bea.medrec.extension.utils;

>     import java.util.Locale;

>     import javax.servlet.http.HttpServletRequest;
>     import javax.servlet.http.HttpServletResponse;

>     import org.apache.struts.util.MessageResources;

>     import com.bea.netuix.servlets.controls.content.backing.AbstractJspBacking;
>     import com.bea.netuix.servlets.controls.portlet.backing.PortletBackingContext;

>     public class DesktopViewBacking extends AbstractJspBacking {
>        public boolean preRender(HttpServletRequest req, HttpServletResponse res) {
>           // Get the PortletBackingContext for current portlet. The
>           // PortletBackingContext contains properties and methods
>           // for the current portlet.
>           PortletBackingContext bctx =
>              PortletBackingContext.getPortletBackingContext(req);

>           if (bctx != null) {
>              // If title does not contain a period, assume it's preLocalized
>              // or follow the format for a key
>              if (bctx.getTitle().indexOf(".")!=-1){
>                 // Get the locale from the HTTPServletRequest
>                 Locale locale = (Locale) req.getSession().getAttribute(
>                    "org.apache.struts.action.LOCALE");
>                 // Find the message bundle named "medrecMBean"
>                 MessageResources messages =
>                    MessageResources.getMessageResources("medrecMBean");
>                 // Get the value of the portlet's "title" property
>                 String msg = messages.getMessage(locale, bctx.getTitle());
>                 // Reset the value of the "title" property with the
>                 // localized value.
>                 bctx.setTitle(msg);
>              }
>           }
>           return true;
>        }
>     }

# Define UI Controls (Optional)

If you want to add tabs or subtabs to the Administration Console, you must define a book or page UI control that conforms to the existing hierarchy:

- To create a top-level tab (such as a sibling of Domains: Configuration), you create a book that contains one or more pages. Each page contains a portlet.
- To create a subtab of an existing tab (such as a sibling of Domains: Configuration: General), you create a page that contains a portlet.

Save the definitions of your books and pages in one or more portal include (`.pinc`) files. Create one `.pinc` file for each hierarchical grouping of controls. For example, create one `.pinc` file for a book that creates a top-level tab and its subtabs. Create another `.pinc` file for a page that adds a subtab to an existing WebLogic Server tab. The root element of a`.pinc` file (`portal:root`) can have only one direct child element; the child element can have multiple children.

The following sections describe creating books and pages:

- Create a Tab That Does Not Contain a Subtab
- Create a Tab That Contains Subtabs
- Create a Subtab
- Create a Control Without Tabs or Subtabs

## Create a Tab That Does Not Contain a Subtab

To create a portal include (`.pinc`) XML file that defines a tab and no subtabs (such as Domains: Notes):

1. Copy the code from Listing 6-6 and paste it into a new text file.

For example, `root-dir``/controls/MyApp.pinc`
where `root-dir` is your development directory. For more information, see Setting Up a Development Environment.

2. Replace the values in Listing 6-6 as follows:

- `Page-Label`. Provide a unique identifier that the portal framework and WebLogic Server JSP tags use to forward requests to the page.
- `Page-Title`. Provide either the text that users see as the name of the tab or a key in a message bundle that you have created.

If the value that you specify contains a "." (period), the Administration Console assumes that this value is a key and attempts to look up the value from your message bundle. For example, if you specify `My.Tab`, the Administration Console looks up the value of a property whose key is `My.Tab`. If it cannot find such a value, it displays `null` as the tab name. If you specify `My Tab` as the value, then the Administration Console displays `My Tab`.

- `Bundle`. Specify the name of a message bundle that you have created. This bundle is used only if the value of the `title` attribute in the `netuix:page` element contains a ".". See Create and Use a Message Bundle in Your JSPs.
- `Portlet-Instance-Label`. Provide a unique identifier that the portal framework and WebLogic Server JSP tags use to forward requests to the portlet instance.
- `Portlet-URI`. Specify the path and file name of a portlet file that you created (see Define a Portlet). The path must be relative to the root of the portal Web application.

For example:
`/portlets/monitorEJB.portlet`

Note that Listing 6-6 defines a page, not a book, so the Administration Console Look and Feel will render the page as a tab with no subtabs.

Listing 6-6 Template .pinc File that Creates a Tab with No Subtabs

>     <?xml version="1.0" encoding="UTF-8"?>
>     <portal:root
>        xmlns:netuix="http://www.bea.com/servers/netuix/xsd/controls/netuix/1.0.0"
>        xmlns:html="http://www.w3.org/1999/xhtml-netuix-modified/1.0.0"
>        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>        xmlns:portal="http://www.bea.com/servers/netuix/xsd/portal/support/1.0.0"
>        xsi:schemaLocation="http://www.bea.com/servers/netuix/xsd/portal/support
>           /1.0.0 portal-support-1_0_0.xsd">
>        <netuix:page markupName="page" markupType="Page"
>           definitionLabel="Page-Label" title="Page-Title"
>           skeletonUri="/framework/skeletons/default/wlsworkspace/
>              page_content.jsp">
>              <netuix:meta name="skeleton-resource-bundle" content="Bundle"/>
>              <netuix:content>
>                 <netuix:gridLayout columns="1" markupType="Layout"
>                    markupName="singleColumnLayout">
>                 <netuix:placeholder flow="vertical" markupType="Placeholder"
>                    markupName="singleColumn_columnOne">
>                    <netuix:portletInstance markupType="Portlet"
>                       instanceLabel="Portlet-Instance-Label"
>                       contentUri="Portlet-URI"/>
>                 </netuix:placeholder>
>              </netuix:gridLayout>
>           </netuix:content>
>        </netuix:page>
>     </portal:root>

## Create a Tab That Contains Subtabs

To create a portal include (`.pinc`) XML file that defines a tab and one or more subtabs:

1. Copy the code from Listing 6-7 and paste it into a new text file. Save the file in a directory below `root-dir`.

For example, `root-dir``/controls//MyApp.pinc`
where `root-dir` is your development directory. For more information, see Setting Up a Development Environment.

2. To define the tab, replace the values in Listing 6-7 as follows:

- `Book-Label`. Provide a unique identifier that the portal framework and WebLogic Server JSP tags use to forward requests to the book. This is the same type of label that WebLogic Server provides for many of its UI controls. See Extension Points in the Administration Console.
- `Book-Title`. Provide either the text that users see as the name of the tab or a key in a message bundle that you have created.

If the value that you specify contains a "." (period), the Administration Console assumes that this value is a key and attempts to look up the value from your message bundle. For example, if you specify `My.Tab`, the Administration Console looks up the value of a property whose key is `My.Tab`. If it cannot find such a value, it displays `null` as the tab name. If you specify `My Tab` as the value, then the Administration Console displays `My Tab`.

- `Bundle`. Specify the name of a message bundle that you have created. This bundle is used only if the value of the `title` attribute in the `netuix:book` element contains a ".". See Create and Use a Message Bundle in Your JSPs.

3. To define the first subtab, replace the values in Listing 6-7 as follows:

- `Page-Label`. Provide a unique identifier that the portal framework and WebLogic Server JSP tags use to forward requests to the page.
- `Page-Title`. Provide either the text that users see as the name of the subtab or a key in a message bundle that you have created.

If the value that you specify contains a "." (period), the Administration Console assumes that this value is a key and attempts to look up the value from your message bundle.

- (optional) `Metadata-Type` and `Metadata-ID`. If you want to use the Administration Console's `<wl:column-dispatch>` JSP tag to create a hypertext link that forwards to this page, include a `<netuix:meta>` element and supply values for `Metadata-Type` and `Metadata-ID`. See Create a Table Column for Navigating to Other Pages.
- `Portlet-Instance-Label`. Provide a unique identifier that the portal framework and WebLogic Server JSP tags use to forward requests to the portlet instance.
- `Portlet-URI`. Specify the path and file name of a portlet file that you created (see Define a Portlet). The path must be relative to the root of the portal Web application.

For example:
`/portlets/monitorEJB.portlet`

4. To create additional subtabs, add `netuix:page` elements as siblings to the `netuix:page` element in Listing 6-7.

For more information about portal include XML files, see the Portal Support Schema Reference.

Note the use of the following elements in the `.pinc` file:

- `netuix:singleLevelMenu` renders one subtab for each page in the book. The book's parent UI control (which Listing 6-7 assumes is provided by WebLogic Server) is responsible for generating a top-level tab for the book.
- `netuix:meta name="breadcrumb-context" content="handle"` adds the page's title to the history of visited pages (breadcrumbs) after a user has visited the page. The breadcrumbs display on the desktop above `ContentBook`.

Listing 6-7 Template for a .pinc File That Defines a Top-Level Tab with Subtabs

>     <?xml version="1.0" encoding="UTF-8"?>
>     <portal:root
>        xmlns:netuix="http://www.bea.com/servers/netuix/xsd/controls/netuix/1.0.0"
>        xmlns:html="http://www.w3.org/1999/xhtml-netuix-modified/1.0.0"
>        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>        xmlns:portal="http://www.bea.com/servers/netuix/xsd/portal/support/1.0.0"
>        xsi:schemaLocation="http://www.bea.com/servers/netuix/xsd/portal/support
>           /1.0.0 portal-support-1_0_0.xsd">

>        <netuix:book markupName="book" markupType="Book"
>           definitionLabel="Book-Label" title="Book-Title">
>           <netuix:singleLevelMenu markupType="Menu" markupName="singleLevelMenu"
>              skeletonUri="singlelevelmenu_children.jsp"/>
>           <netuix:meta name="skeleton-resource-bundle" content="Bundle"/>
>           <netuix:content>
>              <netuix:page markupName="page" markupType="Page"
>                 definitionLabel="Page-Label" title="Page-Title"
>                 skeletonUri="/framework/skeletons/default/wlsworkspace/
>                    page_content.jsp">
>                 <netuix:meta name="Metadata-Type" content="Metadata-ID"/>
>                 <netuix:meta name="breadcrumb-context" content="handle"/>
>                 <netuix:meta name="skeleton-resource-bundle" content="Bundle"/>
>                 <netuix:content>
>                    <netuix:gridLayout columns="1" markupType="Layout"
>                       markupName="singleColumnLayout">
>                       <netuix:placeholder flow="vertical" markupType="Placeholder"
>                          markupName="singleColumn_columnOne">
>                          <netuix:portletInstance markupType="Portlet"
>                             instanceLabel="Portlet-Instance-Label"
>                             contentUri="Portlet-URI"/>
>                       </netuix:placeholder>
>                    </netuix:gridLayout>
>                 </netuix:content>
>              </netuix:page>
>              <!-- Add additional netuix:page elements here -->
>           </netuix:content>
>        </netuix:book>
>     </portal:root>

## Create a Subtab

To create a subtab that you can add to an existing WebLogic Server tab:

1. Create a `.pinc` file that defines a page UI control. See Listing 6-6.
2. In your `netuix-extension.xml` file, specify the WebLogic Server book UI control that you want to contain your subtab. See Add a Tab or Subtab to ContentBook.

## Create a Control Without Tabs or Subtabs

There is no requirement for books and pages in `ContentBook` to be accessible by tab or subtab. Many WebLogic Server pages that display summary tables are accessible from the NavTreePortlet but not from the tabbed interface (see Figure 2-5).

Any of the code listings in the previous sections can be located in a parent control that does not render tabs or subtabs for its children. See Specify a Location for Displaying Portlets or UI Controls.

# Specify a Location for Displaying Portlets or UI Controls

All locations for displaying your portlets or UI controls must be specified as relative to existing controls in the Administration Console. For example, you can specify that your portlet displays on the desktop below the System Status portlet.

To specify a location for displaying a portlet or UI control:

1. Create an XML file named `netuix-extension.xml` and save it in
   `root-dir``/WEB-INF`
   where `root-dir` is your development directory. For more information, see Setting Up a Development Environment.

A NetUI Extension XML file (`netuix-extension.xml`) is the deployment descriptor for your extension. It declares each parent UI control in your extension and the location in which you want it to display (see Listing 6-8). For more information, see the NetUI Extensions Schema Reference.

2. Create a `<weblogic-portal-extension>` root element.
3. (Optional) Create a `<provider-info>` element to describe your extension.

This element is for your information only. The portal framework does not use the data in this element.

4. Add the following element:
   `<portal-file>/console.portal</portal-file>`

This required element specifies the name and relative location of the Administration Console's `.portal` file, which is the portal that you are extending.

5. Do one of the following:

- Add a Portlet to the Desktop
- Add a Tab or Subtab to ContentBook

## Add a Portlet to the Desktop

To add a portlet to the Administration Console desktop, create the following stanza in your `netuix-extension.xml` file (see Listing 6-8):

`<page-extension>
<page-location>
<parent-label-location label="page"/>
<page-insertion-point layout-location="`layout`"
placeholder-position="0"/>
</page-location>
<portlet-content
content-uri="`portlet-URI`" title="`title`"
orientation="top" default-minimized="false"
instance-label="`portlet-instance-label`"/>
</page-extension>`

where:

- layout is one of the following values:

- `0` (zero) if you want the portlet to display in the left side of the Administration Console.

Extension portlets always display at the top of the left column.

- `1` (one) if you want the portlet to display in the right side.

Extension portlets always display at the bottom of the right column.

- portlet-URI is the path and file name of your `.portlet` file. The path must be relative to the root of the portal Web application.
- title is the title that displays in the portlet's title bar. If you specify a null value, the portal framework uses the title that you defined in the `.portlet` file.
- portlet-instance-label is a unique identifier that the portal framework and WebLogic Server JSP tags use to forward requests to the portlet instance.

## Add a Tab or Subtab to ContentBook

To add a control that renders a tab, create the following stanza in your `netuix-extension.xml` file (see Listing 6-8):

`<book-extension>
<book-location>
<parent-label-location label="`Admin-Console-Book-Label`"/>
<book-insertion-point action="append"/>
</book-location>
<book-content content-uri="`pinc-URI`"/>
</book-extension>`

where:

- Admin-Console-Book-Label is the `definitionLabel` of an Administration Console book control that renders tabs for its child books.
- pinc-URI is the path and file name of your `.pinc` file that defines the book control for your tab (and optional subtabs). The path must be relative to the root of the portal Web application.

To add a control that renders a subtab in an existing tab, create the same stanza as the previous step, where:

- Admin-Console-Book-Label is the `definitionLabel` of an Administration Console book control that renders subtabs for its child pages.
- pinc-URI is the path and file name of your `.pinc` file that defines the page control for your subtab. The path must be relative to the root of the portal Web application.

## Example: Specifying Locations for Portlets and UI Controls

Listing 6-8 is a `netuix-extension.xml` file that adds a portlet to the console desktop, a tab to the WebLogic Sever Domain tabs, and subtab to the Domain: Configuration tab.

Listing 6-8 Example netuix-extension.xml File

>     <?xml version="1.0" encoding="UTF-8"?>
>     <weblogic-portal-extension
>        xmlns="http://www.bea.com/servers/portal/weblogic-portal/8.0"
>        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>        xsi:schemaLocation="http://www.bea.com/servers/portal/weblogic-portal/
>           8.0 netuix-extension-1_0_0.xsd">
>        <provider-info>
>           <title>My Extension</title>
>           <version>1.0</version>
>           <description>Inserts a portlet on the desktop, a tab next to
>                Domains:Configuration, and a subtab under Domains: Configuration.
>           </description>
>           <author>Me</author>
>           <last-modified>02/03/2005</last-modified>
>           <support-url>http://www.mycompany/support/index.jsp</support-url>
>        </provider-info>

>        <portal-file>/console.portal</portal-file>

>        <!--Adds a portlet to the console desktop -->
>        <page-extension>
>           <page-location>
>              <parent-label-location label="page"/>
>              <page-insertion-point layout-location="0" placeholder-position="0"/>
>           </page-location>
>           <portlet-content content-uri="/portlets/desktop/desktop_view.portlet"
>              title="My App Status" orientation="top" default-minimized="false"
>               instance-label="PortletExtensionInstanceLabel"
>           />
>        </page-extension>

>        <!--Adds a tab to the Domain tabs -->
>        <book-extension>
>           <book-location>
>              <parent-label-location label="CoreDomainConfigGeneralBook"/>
>              <book-insertion-point action="append"/>
>           </book-location>
>           <book-content content-uri="/controls/page.pinc"/>
>        </book-extension>

>     <!-- Adds a subtab to the Domain: Configuration tab-->
>        <book-extension>
>           <book-location>
>              <parent-label-location label="DomainconfigTabPage"/>
>              <book-insertion-point action="append"/>
>           </book-location>
>           <page-content content-uri="/controls/notespage.pinc"/>
>        </book-extension>

>     </weblogic-portal-extension>

# Add Nodes to the NavTreePortlet (Optional)

The Domain Structure portlet (NavTreePortlet) contains a tree control that you can use to navigate to content in the Administration Console. Each node in the tree is a link to a UI page control. Nodes can also contain subnodes.

Your extension can add a single node at any location in the tree. It can also add a node that contains other nodes (node tree) at any location. For example, your extension can add a node or a node tree to the root of the existing navigation tree. In addition (or instead), it can add a node or node tree to the Environments node. (See Figure 6-2.)

Figure 6-2 Example: Adding Nodes or Node Trees

The following sections describe adding nodes to the NavTreePortlet:

- Append a Single Node to the Root of the Existing Tree
- Append or Insert Nodes or Node Trees

## Append a Single Node to the Root of the Existing Tree

To append a node that links to one of your page controls, add the following attribute and attribute value to the `netuix:page` element in the control's `.pinc` file:
`backingFile="com.bea.console.utils.NavTreeExtensionBacking"`

For example, if you want to add a link to a page that you have created, in the `.pinc` file that defines your page, add the `backingFile` attribute:

`<netuix:page definitionLabel="MyAppTableBook" title="My Page"
markupName="page"
markupType="Page"
backingFile="com.bea.console.utils.NavTreeExtensionBacking"
>`

The NavTreePortlet displays the value of the page element's `title` attribute as the link text. See Figure 6-3.

If the `title` attribute value is a key in your message bundle, the NavTreePortlet displays the localized value mapped to the key.

Figure 6-3 Append a Node to the Root of the Existing Tree

## Append or Insert Nodes or Node Trees

If you want to control the location in which your node is added to the NavTreePortlet, or if you want to add a node tree, implement your own `NavTreeExtensionBacking` backing class.

The following sections describe appending or inserting nodes or node trees:

- Create a NavTreeBacking Class
- Invoke the NavTreeBacking Class
- Example: How a NavTreeExtensionBacking Class Adds a Node Tree to the NavTreePortlet

### Create a NavTreeBacking Class

To create a `NavTreeBacking` class (see Listing 6-9):

1. Extend `com.bea.console.utils.NavTreeExtensionBacking`.

This class is already available in the WebLogic Server runtime environment. However, for support in your development and compiling environment, you must add the following JARs to your environment's classpath:
`WL_HOME``/server/lib/consoleapp/webapp/WEB-INF/lib/console.jar`
`WL_HOME``/server/lib/consoleapp/webapp/WEB-INF/lib/netuix_servlet.jar`

where `WL_HOME` is the location in which you installed WebLogic Server.

2. Override the `NavTreeExtensionBacking.getTreeExtension(
   PageBackingContext ppCtx, String extensionUrl)` method.

In your implementation of this method:

1. Construct a `com.bea.jsptools.tree.TreeNode` object for the parent node.

Use the following constructor:
`TreeNode(String` `nodeId``, String` `nodeName``, String` `nodeUrl``)
`where:

`nodeId` is the value of the control's `definitionLabel`. You can use `PageBackingContext.getDefinitionLabel()` to get this value. Alternatively, you can enter the `definitionLabel` value that is in the control's `.pinc` file.

`nodeName` is the text that you want to display in the NavTreePortlet. You can create a `String` object that contains the text or use `PageBackingContext.getTitle()` to get this value from the page's `.pinc` file.

Note: The `PageBackingContext.getTitle()` method returns the literal value of the `title` attribute in the `.pinc` file; it never assumes that this value is a key and therefore never attempts to look up the value from a message bundle. If your `NavTreeExtensionBacking` class needs to support localization, include logic in your class to look up the locale, use the `PageBackingContext.getTitle()` method to get the `title` value, and then look up the corresponding value from the message bundle. For an example of such logic, see Listing 6-5, which localizes a portlet title (instead of a page title).

`nodeURL` is a URL to the control. Supply `extensionUrl` as the value of this parameter.

2. If you want to add a tree of nodes, construct additional `TreeNode` objects as children of the parent `TreeNode`.

For each child node, use the following constructor:
`TreeNode(String` `nodeId``, String` `nodeName``,
String` `nodeUrl,` `TreeNode` `parent``)
`where:

`nodeId` is the value of the control's `definitionLabel`. You can not use `PageBackingContext.getDefinitionLabel()` to get this value because the `PageBackingContext` available to this method is for the parent node. Instead, you must enter the `definitionLabel` value that is in the control's `.pinc` file.

`nodeName` is the text that you want to display in the NavTreePortlet.

`nodeURL` is a URL to the control. Supply the following value:
`/console/console.portal?_nfpb=true&_pageLabel=`definitionLabel
where `definitionLabel` is the `definitionLabel` of the page to which you want to link.

`parent` is any `TreeNode` that you have constructed. You can create multiple levels in your node tree by specifying a parent that is a child of node higher up in the hierarchy.

3. Pass the parent `TreeNode` object to the constructor for `com.bea.console.utils.NavTreeExtensionEvent`.

Use the following constructor:
`NavTreeExtensionEvent(String` `pageLabel``, String` `url``,
String` `parentPath``, TreeNode` `node``, int ACTION)`
where:

`pageLabel` is the same `nodeID` value that you used when constructing the `TreeNode` object for the parent node.

`url` is the same `nodeURL` value that you used when constructing the `TreeNode` object for the parent node.

`parentPath` is the name of the node under which you want your node to display. Use `/` (slash) to represent the root of the navigation tree in the NavTreePortlet.

For example, if you want your node or node tree to display at the top level, specify `/`. If you want your node to display as a child of Environments, specify `/Environments`.

`node` is the parent TreeNode that you created in step a.

`ACTION` is `NavTreeExtensionEvent.APPEND_ACTION`. For information about other possible actions, see `NavTreeExtensionEvent` in the WebLogic Server Administration Console API Reference.

4. Return the `NavTreeExtensionEvent` object that you constructed.

3. Save the compiled class in a package structure under your extension's `WEB-INF/classes` directory.

Listing 6-9 Example NavTreeExtensionBacking Class

>     package com.mycompany.consoleext;

>     import com.bea.netuix.servlets.controls.page.PageBackingContext;
>     import com.bea.jsptools.tree.TreeNode;
>     import com.bea.console.utils.NavTreeExtensionBacking;
>     import com.bea.console.utils.NavTreeExtensionEvent;

>     public class CustomNavTreeExtension extends NavTreeExtensionBacking {

>        public NavTreeExtensionEvent getTreeExtension(PageBackingContext ppCtx,
>           String extensionUrl){
>          /*
>           * Construct a TreeNode for the control that has invoked this method.
>           */
>           TreeNode node = new TreeNode(ppCtx.getDefinitionLabel(),
>              ppCtx.getTitle(),extensionUrl);

>          /*
>           * Construct a child TreeNode.
>           */
>           TreeNode node1 = new TreeNode("MyAppGeneralTabPage",
>              "MyApp General",
>              "/console/console.portal?_nfpb=true&_pageLabel=MyAppGeneralTabPage",
>                node);

>          /*
>           * Add the parent node (which includes its child) below the
>           * Environment node in the NavTreePortlet.
>           */
>           NavTreeExtensionEvent evt =
>             new NavTreeExtensionEvent(ppCtx.getDefinitionLabel(),extensionUrl,
>             "/Environment",node);

>           return evt;
>        }
>     }

### Invoke the NavTreeBacking Class

To invoke the NavTreeBacking class and start the process described in Example: How a NavTreeExtensionBacking Class Adds a Node Tree to the NavTreePortlet:

1. Determine which UI page control you want to add as the parent node.

Only page controls can be added as nodes to the NavTreePortlet.

2. Add the following attribute and attribute value to the control's `netuix:page` element in the control's `.pinc` file:
   `backingFile="``your-NavTreeBacking-class``"`

where `your-NavTreeBacking-class` is the fully-qualified name of the class you created in step 1.

### Example: How a NavTreeExtensionBacking Class Adds a Node Tree to the NavTreePortlet

The following example describes how a `NavTreeExtensionBacking` class adds the node tree illustrated in Figure 6-4:

1. As the portal framework loads your extension, it parses your extension's `.pinc` files and finds a `netuix:page` element.

For example:

`<netuix:page definitionLabel="MyAppTablePage" title="My App"
markupName="page"
markupType="Page"
backingFile="com.mycompany.utils.MyNavTreeExtension"
>`

2. The portal framework instantiates a `com.bea.netuix.servlets.controls.page.PageBackingContext` object, which is an in-memory representation of the page UI control. The object contains properties that describe the page control's `title` and `definitionLabel` among other data.
3. When the portal framework encounters the `backingFile` attribute in the `netuix:page` element, it initializes the specified class (`MyNavTreeExtension`) and passes your page's `PageBackingContext` object to the class constructor. It also passes a `String` object that contains the page control's URI.
4. The `MyNavTreeExtension` class does the following:

1. It retrieves the `title` and `definitionLabel` values from the `PageBackingContext` object.
2. It constructs a `com.bea.jsptools.tree.TreeNode` object and passes the `title` and `definitionLabel` values along with the page control's URI to the constructor.
3. It constructs two additional `TreeNode` objects for two pages whose titles are "Monitor EJBs" and "Log Messages."

Because there is no way to retrieve the `PageBackingContext` objects or the URIs for these two pages, the values must be hard-coded in the `MyNavTreeExtension` class.

To make the pages into child nodes of the "My App" page node, the `MyNavTreeExtension` class uses a form of the `TreeNode` constructor that accepts the name of a parent node. For example:

TreeNode childnode1 = new TreeNode("MyAppMonitorEJB",
"Monitor EJBs",
"/console/console.portal?_nfpb=true&_pageLabel=MyAppMonitorEJB",
node);

4. It constructs and returns a `com.bea.console.utils.NavTreeExtensionEvent` object.

The `NavTreeExtensionEvent` object describes the `TreeNode` objects that you constructed and indicates the location in the existing navigation tree at which you want to append your node tree.

5. The NavTreePortlet listens for `NavTreeExtensionEvent` objects. As the portlet initializes its tree, it appends nodes as specified by any `NavTreeExtensionEvent` objects that are broadcast.

Figure 6-4 Example: Adding a Node Tree to the NavTreePortlet

# Navigating to a Custom Security Provider Page

If you created a custom security provider and used WebLogic MBeanMaker to create MBeans to manage your provider, the Administration Console automatically generates pages to display the provider's configuration data. It also generates a link to your provider pages from the Security: Providers table.

However, you can create your own pages to customize this display. If you create your own pages, you need to redirect the link in the Security: Providers table from the pages that the Administration Console generates to your custom pages.

To redirect the link, include the following element as a child of your page's `<netuix:page>` element:

`<netuix:meta type="configuration" content="``MBean-class-name``"/>`

where `MBean-class-name` is the fully qualified name of your provider's MBean class.

For example:

`<netuix:page markupName="page" markupType="Page"
definitionLabel="SimpleSampleAuthorizerAuthorizerConfigCommonTabPage"
title="tab.common.label"
skeletonUri="/framework/skeletons/default/wlsworkspace
/page_content.jsp">
` `<netuix:meta name="configuration"
content="examples.security.providers.authorization.simple.
SimpleSampleAuthorizerMBean"/>
``<netuix:content>
...`