How Portal Components Are Rendered

With the look & feel and shell selected for a portal desktop, the rendering service has the basic information it needs to convert a .portal XML file into a final HTML file.

This topic shows the rendering lifecycle, step by step, for a single portal component. The same rendering principles apply for all other portal components.

This topic includes the following sections:

Overview

Single File vs. Streamed Rendering

Rendering Lifecycle of a Book

Summary

Overview

There are three basic stages in the portal rendering process—a process that ultimately results in a portal desktop being displayed in a browser:

  1. Building a portal in XML - In the portal development process, you use the Portal and Portlet designers in WebLogic Workshop to build .portal and .portlet files. Both types are XML files. As you build portals and portlets in WebLogic Workshop, the XML elements and attributes are automatically built under the surface.

    The previous topics, How Look & Feel Determines Rendering and How the Shell Determines Header and Footer Content, described part of the XML-building process: how the look & feel and shell XML files are added to the portal XML file to provide rendering instructions.
  2. Portal XML elements mapped to JSP skeleton files - The portal framework maps specific XML elements to specific JSP skeleton files. They are called skeleton files because they are used to render the physical boundaries and structure—the skeleton—of their portal components. For example, a portlet titlebar in a portlet XML file uses an element called <netuix:titlebar>. The portal framework knows to use the titlebar.jsp skeleton file to render the portlet titlebar.
  3. JSP skeleton files and skin.properties are rendered as HTML - Each skeleton JSP file performs its own processing, such as retrieving property values you set in the WebLogic Workshop Property Editor (and were automatically added to the portal XML file), and generates the appropriate HTML for the portal component. The skin.properties and optional skin_custom.properties files for the selected look & feel are converted to image path entries, CSS file entries, and script file entries in the HTML <head> area.

The following figure is a simplified illustration of the rendering process.

This topic will expand on these three stages using the rendering lifecycle of a single portal component as an example.

Before going into greater detail on the rendering process, it is important to understand the difference between viewing a portal in the development environment (WebLogic Workshop) and viewing it in the administration/end user environment (WebLogic Administration Portal/browser). The three-stage rendering process occurs in slightly different ways in the two different environments. The following section describes the basic principles of each.

Single File vs. Streamed Rendering

The .portal file you create in WebLogic Workshop is a template. In this template you create books, pages and portlets and define defaults for them. When you view the .portal file with your browser the portal is rendered in "single file mode," meaning that you are viewing the portal from your file system as opposed to a database. The .portal file's XML is parsed and the rendered portal is returned to the browser. The creation and use of a .portal is intended for development purposes, but you can access a .portal file in production. Because there is no database involved you cannot take advantage of features such as user customization or entitlements.

Once you have created a .portal file you can use it to create desktops for a production environment.

A desktop is a particular view of a portal that visitors access. A portal can be made up of multiple desktops, making the portal a container for desktops. A desktop contains all the portlets, content, shells, layouts, and look and feel elements necessary to create individual user views of a portal.

When you create a desktop based on the .portal file in the WebLogic Administration Portal, the .portal and its resources are placed into the database. The settings in the .portal file, such as the look & feel, serve as defaults to the desktop. Once a new desktop is created from a .portal template, the desktop is decoupled from the template, and modifications to either the .portal file do not affect the desktop, and vice versa. For example, when you change a desktop's look & feel in the WebLogic Administration Portal, the change is made only to the desktop, not to the original .portal file. When you view a desktop with a browser it is rendered in "streaming mode" (from the database). Now that a database is involved, desktop customizations can be saved and delegated administration and entitlements can be set on portal resources.

Rendering Lifecycle of a Book

This section illustrates the rendering lifecycle of a book, which will help you understand the rendering lifecycle of other portal components, such as pages and portlets.

This section contains the following topics:

1. Building a portal in XML

2. Portal XML elements mapped to JSP skeleton files

3. JSP skeleton files and skin.properties are rendered as HTML

1. Building a portal in XML

This section describes steps that populate and configure the .portal XML file.

Selecting Look & Feel

When you select the look & feel for a desktop, the look & feel file determines which skin and skeleton is used to render all desktop components. In the following example, the "avitek" look & feel has been selected, which points uses the "avitek" skin and the "default" skeleton. The look & feel XML is added to the .portal XML file.

<netuix:markup>
    <netuix:lookAndFeel
        definitionLabel="avitek" title="avitek"
        description="The avitek look and feel"
        skin="avitek" skinPath="/framework/skins/"
        skeleton="default" skeletonPath="/framework/skeletons/"
        markupType="LookAndFeel" markupName="avitek"/>
</netuix:markup>

The skin and skeleton come into play later in the rendering process, when the desktop is viewed with a browser. Before that happens, the book that will be used to illustrate the rendering process will be added to the portal.

Adding a Book to a Portal

In this section a book is added to the desktop in the .portal file and configured. Books can also be added by portal administrators in the WebLogic Administration Portal, which adds the book directly to the database.

The following figure shows a book control being dragged onto the desktop.

After the book is added to the desktop, the book title is changed from "New Book" to "My Book," and the navigation style is set to Multi Level Menu, as shown in the following figure.

Navigation controls the way a book's sub-books and pages are accessed. The single-level menu provides text links/tabs to sub-books and pages, and the multi-level menu provides a drop-down menu to access sub-books and pages. (Books must be added to books rather than to pages inside books for drop-down navigation to work. So in the following example, for the multi-level menu to produce a drop-down menu, you would need to drag a new book control into Main Page Book, right next to Page 1, as shown in the figure.)

After the Navigation style is set on My Book, the following is what the book looks like in XML in the .portal file. If you add a book in the WebLogic Administration Portal, the XML is added to the database. This XML is used as the basis for the rendering of the book.

<netuix:book defaultPage="newPage.1" definitionLabel="my_book_3"
    markupName="book" markupType="Book" title="My Book">
    <netuix:multiLevelMenu
        description="This menu can navigate across may nested books."
        markupName="multiLevelMenu" markupType="Menu" title="Multi Level Menu"/>
            <!-- in this example, the nested page content has been removed -->
</netuix:book>

2. Portal XML elements mapped to JSP skeleton files

When the desktop is viewed in a browser, the portal framework reads the XML elements and uses the skeleton path to map the desktop's XML elements to skeleton JSPs. The following examples show which elements in the book XML are mapped to skeleton JSPs and which skeleton JSPs are used to render the elements.

book XML - The highlighted elements are mapped to skeleton JSPs.

<netuix:book defaultPage="newPage.1" definitionLabel="my_book_3"
    markupName="book" markupType="Book" title="My Book">
    <netuix:multiLevelMenu
        description="This menu can navigate across may nested books."
        markupName="multiLevelMenu" markupType="Menu" title="Multi Level Menu"/>
            <!-- in this example, the nested page content has been removed -->
</netuix:book>


skeleton - Referenced in the look & feel

/framework/skeletons/default/
book.jsp
multilevelmenu.jsp
submenu.jsp
(referenced in multilevelmenu.jsp)

Once rendering has been handed off to the JSPs, the JSPs perform the tasks necessary for conversion to HTML. Following are the book.jsp, multilevelmenu.jsp, and submenu.jsp used in this example. Comments are added to describe what the JSPs are doing.

book.jsp

The book.jsp serves as a high-level container for the book's menu and the book's child books and pages.

<%@ page import="com.bea.netuix.servlets.controls.page.BookPresentationContext,
com.bea.netuix.servlets.controls.page.MenuPresentationContext"
%>
<%@ page session="false"%>
<%@ taglib uri="render.tld" prefix="render" %>
<render:beginRender>
<%-- The content inside the <render:beginRender> tag is processed first and ultimately renders whatever is inside it. In most cases, the skeletons produce an opening <div> HTML tag with specific attributes such as CSS classes. The following block determines where the book falls in the desktop hierarchy (whether it is the top-level book or a nested book). It also sets the base name of the CSS class to use (bea-portal-book) and appends different endings to the base class to apply a different CSS class for each book context. Only processing, not HTML rendering, occurs in this block. --%> <%
BookPresentationContext book = BookPresentationContext.getBookPresentationContext(request);
MenuPresentationContext menu = (MenuPresentationContext) book.getFirstChild("page:menu");
String bookClass = "bea-portal-book";
String useBookClass = bookClass;
if (book.isDesktopBook())
{
bookClass += "-primary";
useBookClass = bookClass;
}
else if (book.isLikePage())
{
useBookClass += "-invisible";
}
String bookContentClass = bookClass + "-content";
%>
<%-- The next block begins the actual HTML rendering, beginning with the comment "Begin Book" followed by an opening <div> HTML tag. Notice the JSP tags used before the closing bracket of the <div> tag. These populate the div tag with style attributes. The methods retrieve any presentation property override values you entered in the WebLogic Workshop Property Editor for the book. For the "class" attribute, the default value is useBookClass, which earlier is set to "bea-portal-book". (If through getting the context the book was found to be the top-level book, the value of useBookClass would be "bea-portal-book-primary".) With no overrides, the useBookClass variable will produce the following HTML, because the book is acting like a page: <div class="bea-portal-book-invisible" > The style sheet class is provided by the skin, and the CSS file containing the class is referenced in the skin's skin.properties file and added to the HTML <head> region. --%> <%-- Begin Book --%>
<div
<render:writeAttribute name="id" value="<%= book.getPresentationId() %>"/>
<render:writeAttribute name="class" value="<%= book.getPresentationClass()%>" defaultValue="<%= useBookClass %>"/> <render:writeAttribute name="style" value="<%= book.getPresentationStyle() %>"/>
>
<%-- The following JSP tag gets the names of the pages and books it will display in its navigation menu, and based on the navigation element used in the portal XML file (in this case netuix:multiLevelMenu), uses the corresponding menu JSP (multilevelmenu.jsp) to render the menu in this position of the HTML. --%> <render:renderChild presentationContext="<%= menu %>"/>
<%-- The following block provides a <div> HTML container for the book's content area--the child books and pages. Again, it uses a JSP tag to set the style sheet "class" attribute. --%> <%-- Begin Book Content --%>
<div
<render:writeAttribute name="class" value="<%= book.getContentPresentationClass()%>" defaultValue="<%= bookContentClass %>"/>
<render:writeAttribute name="style" value="<%= book.getContentPresentationStyle() %>"/>
>
</render:beginRender>
<%-- The closing </render:beginRender> tag signals the portal framework to stop rendering the book. After the book's children and their children are rendered, the portal framework uses the following <render:endRender> tag to close the book's parent HTML tags. --%> <render:endRender>
</div>
<%-- End Book Content --%>
</div>
<%-- End Book --%>
</render:endRender>

Following is a description of the multilevelmenu.jsp, which is used by the book to render the navigation menu for the book's child books and pages.

multilevelmenu.jsp

The multilevelmenu.jsp is rendered inside the book container and provides the boundaries for multi-level menus on books. This JSP also uses submenu.jsp to perform the actual rendering of the menu links.

<%@ page import="com.bea.netuix.servlets.controls.window.WindowPresentationContext,
com.bea.netuix.servlets.controls.page.BookPresentationContext,
com.bea.netuix.servlets.controls.page.MenuPresentationContext,
java.util.List,
java.util.Iterator,
com.bea.netuix.servlets.controls.page.PagePresentationContext,
com.bea.netuix.servlets.controls.window.WindowCapabilities" %>
<%@ page session="false"%>
<%@ taglib uri="render.tld" prefix="render" %>
<%-- The following block determines where the book falls in the desktop hierarchy (whether it is the top-level book or a nested book). It also sets the base name of the CSS class to use (bea-portal-book) and defines different menu style classes by appending different endings to the base class. Only processing, not HTML rendering, occurs in this block. --%> <%
BookPresentationContext book = BookPresentationContext.getBookPresentationContext(request);
MenuPresentationContext menu = MenuPresentationContext.getMenuPresentationContext(request);
String bookClass = "bea-portal-book";
if (book.isDesktopBook())
{
bookClass += "-primary";
}
final String menuClass = bookClass + "-menu";
final String menuContainerClass = menuClass + "-container";
final String menuItemClass = menuClass + "-item";
final String menuItemActiveClass = menuItemClass + "-active";
final String menuItemLinkClass = menuItemClass + "-link";
final String menuHookClass = menuClass + "-hook";
final String menuButtonsClass = menuItemClass + "-buttons";
List menuChildren = menu.getChildren();
%> <render:beginRender>
<%-- The content inside the <render:beginRender> tag is processed first and ultimately renders whatever is inside it, such as opening <div> HTML tags with specific attributes and tables. The following block creates a table cell, sets CSS styles on the <td> tag (based on the members defined in the previous block). --%> <%-- Begin Multi Level Menu --%>
<div class="bea-portal-ie-table-buffer-div">
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
<td class="<%= menuContainerClass %>" align="left" nowrap="nowrap">
<%-- The following block builds the menu in the table cell. It first adds an unordered list <ul> to the cell and sets its style class. Then, an IF statement checks to see if the book is in VIEW mode. If true, CSS styles are put in the request as attributes to be used by the menu. After the attributes are added to the request, the skeleton's submenu.jsp is inserted, which does the following: * Gets the CSS styles from the request. * Gets the book's child pages and books. * Creates list items <li> of the children and creates links out of them. The menuHookClass at the end of the block is used by the skin's menu.js file to insert the rendered menu. The <ul> that is generated is a menu structure description that is read and rewritten by menu.js. * Adds CSS styles to the request and includes submenu.jsp to handle the menus of nested books. After the menu is built, the CSS styles are removed from the request. --%> <ul
<render:writeAttribute name="id" value="<%= menu.getPresentationId() %>"/>
<render:writeAttribute name="class" value="<%= menu.getPresentationClass() %>" defaultValue="<%= menuClass %>"/>
<render:writeAttribute name="style" value="<%= menu.getPresentationStyle() %>"/>
><%
if (book.getWindowMode().equals(WindowCapabilities.VIEW))
{
request.setAttribute(BookPresentationContext.class.getName() + ".root-flag", Boolean.TRUE);
request.setAttribute(BookPresentationContext.class.getName() + ".menu-item", book);
request.setAttribute(BookPresentationContext.class.getName() + ".menu-class", menuClass);
request.setAttribute(BookPresentationContext.class.getName() + ".menu-item-class", menuItemClass);
request.setAttribute(BookPresentationContext.class.getName() + ".menu-item-active-class", menuItemActiveClass);
request.setAttribute(BookPresentationContext.class.getName() + ".menu-item-link-class", menuItemLinkClass);
%><jsp:include page="submenu.jsp"/><%
request.removeAttribute(BookPresentationContext.class.getName() + ".root-flag");
request.removeAttribute(BookPresentationContext.class.getName() + ".menu-item");
request.removeAttribute(BookPresentationContext.class.getName() + ".menu-class");
request.removeAttribute(BookPresentationContext.class.getName() + ".menu-item-class");
request.removeAttribute(BookPresentationContext.class.getName() + ".menu-item-active-class");
request.removeAttribute(BookPresentationContext.class.getName() + ".menu-item-link-class");
}
%></ul>
<div class="<%= menuHookClass %>"></div>
</td>
<%-- The following block adds a table cell next to the menu table cell if a menu is present. The <render:endRender> contents are inserted in the HTML after all menu children are inserted, which closes the menu table. --%> <%
if (menuChildren != null && menuChildren.size() > 0)
{
%>
<td class="<%= menuButtonsClass %>" align="right" nowrap="nowrap">
<%
}
%>
</render:beginRender>
<render:endRender>
<%
if (menuChildren != null && menuChildren.size() > 0)
{
%>
</td>
<%
}
%>
</tr>
</table>
</div>
<%-- End Multi Level Menu --%>
</render:endRender>

submenu.jsp

The submenu.jsp is inserted inside the multilevelmenu.jsp. It retrieves a book's child books and pages and builds the navigation links to those children.

<%@ page import="java.util.Iterator,
java.util.List,
com.bea.netuix.servlets.controls.page.BookPresentationContext,
com.bea.portlet.PageURL,
com.bea.netuix.servlets.controls.page.PagePresentationContext"%>
<%@ page session="false"%>
<%-- The following block gets the CSS styles placed in the request by multilevelmenu.jsp. --%> <%
Boolean isRoot
= (Boolean) request.getAttribute(BookPresentationContext.class.getName() + ".root-flag");
BookPresentationContext bookCtx
= (BookPresentationContext) request.getAttribute(BookPresentationContext.class.getName() + ".menu-item");
String menuClass
= (String) request.getAttribute(BookPresentationContext.class.getName() + ".menu-class");
String menuItemClass
= (String) request.getAttribute(BookPresentationContext.class.getName() + ".menu-item-class");
String menuItemActiveClass
= (String) request.getAttribute(BookPresentationContext.class.getName() + ".menu-item-active-class");
String menuItemLinkClass
= (String) request.getAttribute(BookPresentationContext.class.getName() + ".menu-item-link-class");
%>
<%-- The following block checks to see if the book and its children are visible. If true, the labels of the children are retrieved, iterated over, and inserted as hyperlinked list items <li> inside the unordered list <ul> inserted by multilevelmenu.jsp. Notice the nested <ul> at the end of the block, which provides for submenu nesting. --%> <%
if (!bookCtx.isHidden() && bookCtx.isVisible())
{
if (bookCtx instanceof BookPresentationContext)
{
List bookChildren = bookCtx.getPagePresentationContexts();
Iterator it = bookChildren.iterator();
while (it.hasNext())
{
PagePresentationContext childPageCtx = (PagePresentationContext) it.next();
if (!childPageCtx.isHidden() && childPageCtx.isVisible())
{
%><li class="<%= isRoot.booleanValue() && childPageCtx.isActive() ? menuItemActiveClass : menuItemClass %>"><%
%><a class="<%= menuItemLinkClass %>" href="<%= PageURL.createPageURL(request, response, childPageCtx.getDefinitionLabel()).toString() %>"><%= childPageCtx.getTitle() %></a><%
if (childPageCtx instanceof BookPresentationContext)
{
%><ul class="<%= menuClass %>"><%
request.setAttribute(BookPresentationContext.class.getName() + ".root-flag", Boolean.FALSE);
request.setAttribute(BookPresentationContext.class.getName() + ".menu-item", childPageCtx);
%><jsp:include page="submenu.jsp"/><%
request.removeAttribute(BookPresentationContext.class.getName() + ".root-flag");
request.removeAttribute(BookPresentationContext.class.getName() + ".menu-item");
%></ul><%
}
%></li><%
}
}
}
}
%>

JavaScript in Menus

The menus in a desktop use JavaScript functions for such functionality as drop-down menus and rollovers. These JavaScript functions are called from the skeleton's body.jsp, which contains the following entry:

<render:writeAttribute name="onload" value="<%= body.getOnloadScript() %>"/>

The onload value is retrieved from the following property in the skin's skin.properties file:

document.body.onload: initSkin()

Following is the HTML written by the body.jsp:

<body


    class="bea-portal-body"


    onload="initSkin();"

>

The initSkin() JavaScript function is the base function that calls menu-rendering functions in other JavaScript files. The initSkin() function is contained in the skin.js file. Other menu functions are contained in the menu.js and menufx.js files. Since all of those JavaScript files are listed in the skin's skin.properties file, they are automatically added to the HTML <head> region at rendering, and the functions they contain are recognized.

The next section describes the final process of the skeleton JSPs and skin.properties being converted to HTML.

3. JSP skeleton files and skin.properties are rendered as HTML

The previous section described the skeleton JSPs that are used to convert a book with a multi-level menu to HTML. The descriptions in that section described briefly some of the HTML generated by the JSPs.

This section shows the final HTML that is generated for a book, describes where it came from, and shows where some of the CSS styles used are defined.

Not all HTML for the desktop is shown in the following table. Only the sections that relate to the look & feel and the example book are shown.

skin.properties and skin_custom.properties - The paths to skeletons, skins, images, style sheets, and JavaScript files in the HTML <head> region are inserted from the skin's skin.properties and skin_custom.properties files. To see the original skin.properties entries, see The skin.properties File in "How Look & Feel Determines Rendering." The <head> tag is inserted by the head.jsp file used for the shell. The <title> is inserted from the desktop title in the .portal file.

The first three <meta> tags are for testing and debugging purposes. These can be removed from skin.properties by setting the enable.meta.info property to false.

<head> 

<title>New Portal Desktop</title>
<meta name="bea-portal-meta-skeleton" content="/framework/skeletons/default"/>
<meta name="bea-portal-meta-skin" content="/framework/skins/avitek"/>
<meta name="bea-portal-meta-skin-images" content="/framework/skins/avitek/images"/>
<link href="/sampleportal/framework/skins/avitek/css/body.css" rel="stylesheet"/>
<link href="/sampleportal/framework/skins/avitek/css/button.css" rel="stylesheet"/>
<link href="/sampleportal/framework/skins/avitek/css/window.css" rel="stylesheet"/>
<link href="/sampleportal/framework/skins/avitek/css/plain/window.css" rel="stylesheet"/>
<link href="/sampleportal/framework/skins/avitek/css/portlet.css" rel="stylesheet"/>
<link href="/sampleportal/framework/skins/avitek/css/book.css" rel="stylesheet"/>
<link href="/sampleportal/framework/skins/avitek/css/fix.css" rel="stylesheet"/>
<link href="/sampleportal/framework/skins/avitek/css/layout.css" rel="stylesheet"/>
<link href="/sampleportal/framework/skins/avitek/css/form.css" rel="stylesheet"/>
<script type="text/javascript" src="/sampleportal/framework/skins/avitek/js/menu.js"></script>
<script type="text/javascript" src="/sampleportal/framework/skins/avitek/js/util.js"></script>
<script type="text/javascript" src="/sampleportal/framework/skins/avitek/js/delete.js"></script>
<script type="text/javascript" src="/sampleportal/framework/skins/avitek/js/float.js"></script>
<script type="text/javascript" src="/sampleportal/framework/skins/avitek/js/menufx.js"></script>
<script type="text/javascript" src="/sampleportal/framework/skins/avitek/js/skin.js"></script>
</head>
       
The following section shows the HTML that is produced by each skeleton JSP.

book.jsp

<div
    class="bea-portal-book-invisible"
>

multilevelmenu.jsp

    <div class="bea-portal-ie-table-buffer-div">
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
<td class="bea-portal-book-menu-container" align="left" nowrap="nowrap">
<ul
class="bea-portal-book-menu"
>

submenu.jsp

<li class="bea-portal-book-menu-item-active"><a class="bea-portal-book-menu-item-link" 
href="http://localhost:7001/sampleportal/my.portal?_nfpb=true&_pageLabel=my_page_6">New Page</a></li>

 

                    </ul>
<div class="bea-portal-book-menu-hook"></div>
</td>
            </tr>
        </table>
    </div>
        <div
class="bea-portal-book-content"
>
<%-- The book content (sub-books and pages) is inserted here. --> </div> </div>

When the desktop for this example is rendered, the following appears in the browser:

The circled area in this figure is the only content rendered for the book. The book contains only one page, so there is only one menu item for the book. The "Page 1" and "My Book" tabs are menu items rendered by the parent Main Page Book. That is why you do not see the "My Book" in the previous HTML block: because the book is responsible for rendering only a menu of its child books and pages.

If "New Page" contained a portlet, the portlet would appear in the browser. However, the rendering of the page and portlet is handled by different skeleton JSPs: one to provide a container for the page content, one to render the layout of the page (table cells that contain portlets and sub-books), and a few to handle the rendering of the portlet.

The book is responsible for rendering only two things:

CSS Styles in the Example

As you can see from the previous example of rendered HTML code, the skeleton JSPs insert many CSS styles. For example, the multilevelmenu.jsp inserts <td class="bea-portal-book-menu-container" ...>. The style classes inserted by multilevelmenu.jsp are rewritten by the skin's menu.js file.

Also, some of the style classes inserted by the skeleton JSPs are not defined in any of the CSS files provided by BEA. You can add these style classes to your custom CSS files to control those styles in your portal desktops.

To determine which styles you want to modify, see Portal User Interface Framework Reference.

Changing Look & Feel

If the look & feel is changed, a different skin and skeleton is referenced by the look & feel file, and rendering is subject to that skin and skeleton. With a different skin and skeleton, CSS files and script code can change completely.

Summary

There are three basic stages in the portal rendering process: building a portal in XML, portal XML components being mapped to skeleton JSPs, and skeleton JSPs rendering the portal desktop in HTML. The latter two stages are handled automatically by the portal framework.

There is a rendering difference between viewing a portal desktop in development mode and in administration/end user mode. In development mode, when you view the .portal file in a browser you see it in "single file" mode, meaning the desktop is being rendered from the file system. In administration/end user mode, you view a portal desktop in a browser in "streamed" mode, meaning the desktop components are being streamed from a database. When you create a portal desktop in the WebLogic Administration Portal using a .portal file as a template for the desktop, the portal components are added to the database and are decoupled from the original .portal file.

Related Topics

Portal Key Concepts and Architecture

The Portal User Interface Framework

How Look & Feel Determines Rendering

How the Shell Determines Header and Footer Content

Portal User Interface Framework Reference