Professional Documents
Culture Documents
Developers Guide
Version
Vignette Portal Developers Guide, version 7.4 LiveDocs Update 1 (October, 2008)
Disclaimer
Vignette does not warrant, guarantee, or make representations concerning the contents of this document. All information is provided "AS-IS," without express or implied warranties of any kind including, without limitation, the warranties of merchantability, fitness for a particular purpose, quality, and title. Vignette reserves the right to change the contents of this document and the features or functionalities of its products and services at any time without obligation to notify anyone of such changes.
publications@vignette.com
A member of the Publications team will acknowledge your mail as soon as possible. You can also reach us at the following address: Vignette Corporation Publications Department 1301 South MoPac Expressway, Suite 100 Austin, TX 78746 USA
Contents
Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
Vignette Portal Features and Concepts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Vignette Portal Sites . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Vignette Portal J2EE Architecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Points of Customization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Customizing End-user Components. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Integrating Content and Applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Using and Customizing Vignette Portal Services . . . . . . . . . . . . . . . . . . . . . . Using This Guide . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
15 15 16 17 18 19 21 22
Style Types and Styles for Standard Controls . . . . . . . . . . . . . . . . . . . . . . . . . Navigation Style Types and Styles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Chrome Style Type and Styles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Footer Style Types and Styles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Deploying Styles and Style Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Component Descriptor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . CAR File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Uploading the CAR File into Portal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Style Example: Adding Login Functionality to a Style . . . . . . . . . . . . . . . . . . . . .
50 51 65 71 72 72 75 75 76
Contents
Developing a Secondary Page Type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Creating Custom Portlet Page Layouts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Page Display Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Page Display APIs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Customization Process . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Automating the Validation and Population of HTML Forms . . . . . . . . . . . . . . . Step 1: Develop a FormBean . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Step 2: Set up the Validation Rules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Step 3: Add Validation Code to the Primary JSP . . . . . . . . . . . . . . . . . . . . . . Step 4: Develop the Action Processing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Secondary Page Deployment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Deploying a Secondary Page Instance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Deploying a Secondary Page Type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
115 115 117 120 120 121 122 125 135 135 136 137 143
Contents
Other API Changes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Name Changes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . AJAX-Enabling PortalBean Portlets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Creating AJAX URLs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Performing a Partial Portlet Update from a Link . . . . . . . . . . . . . . . . . . . . . . Performing a Partial View Update from a Form Submission . . . . . . . . . . . . . Uploading a File from a Multipart Form . . . . . . . . . . . . . . . . . . . . . . . . . . . . Auto-Completing a Textbox . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Handling Errors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . CAR Tool . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . <mod:i18nAlias> JSP Tag . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Retiring a Prototype PortalBean . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
236 237 237 238 239 239 239 240 241 241 242 243
15 Caching . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 269
The Vignette Portal Caching System . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Caching Strategies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Passivation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Distributed Caching . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Caching Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
269 270 271 271 272
Contents
Simplest Case. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Using Multiple Strategies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Using a Broadcasting Strategy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Using a Custom Cache Data Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
16 Metrics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 277
The Vignette Portal Metrics System . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . First-Time Database and Connection Pool Setup . . . . . . . . . . . . . . . . . . . . . . . . Creating an External Metrics Database . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Setting Database and Connection Pool Properties . . . . . . . . . . . . . . . . . . . . . Creating a Custom Metric . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Defining a Custom Metric in mbeans.xml . . . . . . . . . . . . . . . . . . . . . . . . . . . Creating a Custom Metrics Archive Table. . . . . . . . . . . . . . . . . . . . . . . . . . . Using Metrics API Calls . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Using Table Aliases . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . <name-space> Element . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . <key/> Element . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . <attribute/> Element . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Metrics Code Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Defining the Custom Metric in mbeans.xml . . . . . . . . . . . . . . . . . . . . . . . . . Creating the Custom Metric Table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Adding JSP/Java Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
277 278 278 279 280 280 282 283 284 284 285 285 286 286 287 287
10
Contents
API Call Examples. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Search Engine Connector Configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . . Customizing Content Rendering . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Step 1: Create Custom JSPs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Step 2: Create and Upload the CAR File . . . . . . . . . . . . . . . . . . . . . . . . . . . . Step 3: Update Portal Properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Step 4: Restart the Portal Application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Appendices
A Vignette Portal Custom JSP Tag Reference . . . . . . . . . . . . . . . . . . . . 391
Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Web Site Tags . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . <vgn-portal:defineObjects/> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . <vgn-portal:i18nElement> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . <vgn-portal:i18nFormat/> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . <vgn-portal:i18nFormattableValue/> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . <vgn-portal:i18nParam/> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . <vgn-portal:i18nParams/> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . <vgn-portal:i18nValue>. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . <vgn-portal:includeNavigation/> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . <vgn-portal:includePageContent/> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
391 392 392 392 393 393 394 395 395 396 397
11
<vgn-portal:includeStyle/> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . <vgn-portal:inSegment> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . <vgn-portal:insertPortletContent/> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . <vgn-portal:onRenderFailure> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . <vgn-portal:onRenderSuccess> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . <vgn-portal:pageContentTitle/> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . <vgn-portal:realmSelector/> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . <vgn-portal:renderPortlet> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . <vgn-portal:styleBlock/> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Story Publisher PortalBean Portlet Tags . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . <content:printDocumentContent/> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . <content:printDocumentImageURL/> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . <content:printDocumentURL/> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . <content:selectedDocument> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . <content:viewableDocuments> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
397 398 398 399 399 399 400 400 401 402 402 402 402 403 403
12
Contents
<locale-key> Element . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . <interface-class-name> Element . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . <diaglet-class-name> Element . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Detail Elements for Service Implementations . . . . . . . . . . . . . . . . . . . . . . . . . . . <service-implementation-definition> Element . . . . . . . . . . . . . . . . . . . . . . . <locale-key> Element . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . <type-version/> Element . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . <implementation-class-name> Element . . . . . . . . . . . . . . . . . . . . . . . . . . . . . <diaglet-class-name> Element . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . <configuration-validator-class-name> Element . . . . . . . . . . . . . . . . . . . . . . . <property-set-definition> Element. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . <value-property-definition> Element . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . <option-list> Element . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . <option> Element . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . <default-value> Element . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . <service-property-definition> Element . . . . . . . . . . . . . . . . . . . . . . . . . . . . . <service-type> Element . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . <indexed-property-set-definition> Element . . . . . . . . . . . . . . . . . . . . . . . . . . Detail Elements for Service Instances . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . <service-instance> Element . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . <type-id> Element . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . <implementation-id> Element . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . <locale-key> Element . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . <property-set> Element . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . <property> Element . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
421 422 422 423 423 423 424 425 425 426 426 427 428 428 429 429 430 430 431 432 432 433 433 433 434
13
_getPageOffsetLeft . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . _getPageOffsetTop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Drag-and-Drop Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . cm_scrolldown . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . cm_scrollleft . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . cm_scrollright . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . cm_scrollup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Column . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Row . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 493
14
Contents
Introduction
Summary: Audience: Topics: Provides an overview of Vignette Portal and of the contents of this guide Web page developers, portlet developers, and Java developers
Vignette Portal Features and Concepts (below) Points of Customization on page 17 Using This Guide on page 22
15
structure of Portal pages), styles (defining page look and feel), and secondary pages (incorporating functionality into pages). Figure 1 illustrates the relationships among Portal components, Portal sites, and web sites.
Figure 1: Portal Components and Sites
Portal Site Presentation Framework extranet site
multiple initiatives
intranet site
Portlets intranet site (a logical object) Grids extranet site (a logical object) Styles corporate site (a logical object) Secondary Pages
corporate site
16
Introduction
Points of Customization
Figure 2:
end user
Points of Customization
Vignette Portal supports the following broad categories of configuration and development (see Figure 3):
Controlling a sites look and feel and functionality through a site
component architecture
Integrating content and applications through portlets Using and customizing Portal services
17
Points of Customization
intranet site
Figure 3:
Portal
extranet site
multiple initiatives
Portlets
corporate site
18
Introduction
Points of Customization
Technology
Portlets are easily upgradable and personalizable web applications that can be plugged into web sites. They serve as mechanisms for integrating content and applications into a site. Both local, in-process and remote, out-of-process applications and content can be built as portlets. Vignette Portal supports both Java standard portletsthose that conform to the JSR 286 specificationand PortalBean portlets, a Vignette technology that was a precursor to Java standard portlets. (Note that this technology is being deprecated in favor of Java standard portlets.) Portlets of either type can be AJAX-enabled using either Portals own AJAX library or any AJAX widget toolkit. In addition, using the Web Services for Remote Portlets (WSRP) standard, Vignette Portal can consume portlets that are published by WSRP producers. Rather than functioning within the same VM as Portal, WSRP producers can reside in disparate geographical locations, thereby enabling workload to be distributed more easily. (For more about Portal and WSRP interoperability, see Knowledge Base (KB) item 7498.)
19
Points of Customization
Section II of this guide provides information about developing Java standard and PortalBean portlets for use with Vignette Portal. Before building a portlet from scratch, consider the no- or low- code alternatives described next.
Prebuilt Portlets
Vignette Portal ships with prebuilt portlets that provide a wide range of outof-the-box functionality. These portlets can be added to Portal sites simply by using the Portal administration consoles to instantiate and configure them. Here are a few examples:
The Federated Search Portlet can aggregate search results from disparate
sources, such as intranets, public Web sites, and search engines collections.
The WebConnector Portlet enables Vignette Portal to proxy content from
external sources.
The .NET Integration Portlet exposes a .NET application. The Text Pad portlet displays any amount of HTML or plain-text content;
multiple instances of this portlet can be used to display various kinds of messages.
Vignette Builder
Vignette Builder is a WSRP producer whose content can be consumed and surfaced by Vignette Portal. Builder significantly reduces the time and cost of developing, deploying, and managing applications within enterprise portals by empowering non-programmers to build portal applications. By dragging and dropping controls (labels, fields, columns, buttons, and links) in a browser to create forms, reports and charts, application designers can easily construct portal applications. Users can interact with data from disparate applications presented within a single composite web application, controlling both the layout and application flow. Applications can draw on data from relational databases, web services, Vignette IDM, Vignette Records and Documents, and SAP (through the Builder Gateway for SAP). Using the Vignette Business Integration Studio, data from virtually any application or repository (such as Siebel, PeopleSoft, JD Edwards, Lotus Notes/Domino, Artesia, and Microsoft Office) can be transformed into a data source usable by Vignette Builder.
20
Introduction
Points of Customization
Builder streamlines portlet development through an intuitive, code-free environment that is seamlessly integrated with Vignette Portal, allowing finished applications to take advantage of Vignette Portal permissions, personalization, and layout flexibility. Application templatespackaged forms, reports, charts, and rules that make up a Builder applicationare available in the Extension Library of the Portal Developer Community of Vignette Connect (http://connect.vignette.com). For convenience, these templates are bundled with a related Portal site.
Sample Portlets
The Portal Developer Community of Vignette Connect (http://connect.vignette.com) provides a means to share sample portlets and useful utilities. You can also join the Portal Developer Forum explore ideas and solutions with your peers.
21
If you want to... customize your Portal installation by modifying the HTML in the end-user JSP files
Modifying the Look and Feel of Existing Styles in Chapter 2, Controlling Navigation and Appearance with Styles Modifying the Look and Feel of Existing Grids in Chapter 3, Controlling Page Structure with Grids Modifying the Look and Feel of an Existing Secondary Page in Chapter 4, Controlling Functionality with Secondary Pages Section I, Portal Site Development (Chapter 1 through Chapter 8) Appendix A, Vignette Portal Custom JSP Tag Reference Chapter 5, Using Cascading Style Sheets Appendix D, Vignette Portal CSS Reference Chapter 6, Internationalizing and Localizing Site Components AJAX-Enabled Navigation Styles and DHTML Navigation Styles in Chapter 2, Controlling Navigation and Appearance with Styles AJAX-Enabling Portal Components in Chapter 7, Using the Site Development APIs AJAX-Enabling Portlets in Chapter 9, Java Standard Portlets and Vignette Portal AJAX-Enabling PortalBean Portlets in Chapter 12, PortalBean Portlets Appendix C, Vignette Portal JavaScript Functions
use JSP to customize your portal use CSS to change the look and feel of enduser Portal pages use the Portal I18N framework add interactive capabilities such as AJAX, JavaScript, or DHTML to Portal components
IMPORTANT: Sample code appearing in this guide is not intended to be compiled, executed, or otherwise used. It is included only to support the surrounding text. In many cases, artificial line breaks have been introduced to fit code lines within the margins of this guide. These line breaks often do not conform to proper Java, JSP, XML, CSS, or HTML syntax or conventions.
22
Introduction
1
Summary: Audience: Topics:
The Site Presentation Framework (below) Overview of a Vignette Portal HTML Page on page 26 Vignette Portal and Request Handling on page 34 Design Points for Vignette Portal Site Development on page 40
25
Figure 4:
J2EE Application Server Vignette Portal (a WAR) Site Presentation Framework filters servlets classes end user Grids
Styles
Secondary Pages
These components are where the bulk of Vignette Portal site development happens. They are introduced in this chapter and explained in detail in subsequent chapters of this guide.
26
Figure 5:
Footer
Footer
Grids
A site component called a grid controls the overall structure of a Vignette Portal HTML page, including the regions that exist on the page. The grid outputs the basic HTML outline of the page, as shown in Figure 6.
Figure 6:
Grid <html> <body> <insert header> <br> <insert page content> <br> <insert footer> </body> </html>
Footer
27
user account management, or display of the main view of a Portal site). This functionality is provided by a component called a secondary page. Every grid must include this type of region.
Figure 7:
Grid Header Page Content
secondary page
Footer
See also:
Chapter 3, Controlling Page Structure with Grids, for details about grid development
28
Figure 8:
Basic Header
Grid Style type: header
Commerce Header
Employee Header
Portal site administrators control the look and feel of their site via themes. A theme specifies one style for every style type in the system, enabling Portal sites to have a unified look and feel. The administrator applies a theme to a particular page or all pages in the site. When a page displays, the region for each style type is fulfilled with a style coming from the theme. In Figure 9, a theme called "basic" contains styles such as the "basic" header, the "basic" footer, etc. An administrator would use this theme to apply the "basic" look and feel to a site or page.
Figure 9: "Basic" Theme Applied to a Page with a Header and Footer
Theme: "basic" style type
header navigation site controls footer "basic" header
style
"basic" "basic" "basic" "basic"
Page Content
See also:
Chapter 2, Controlling Navigation and Appearance with Styles, for details about style and style type development
29
Secondary Pages
While styles determine the appearance of a page, its functionality is controlled by the secondary page component. Each site function has a corresponding type of secondary page. Here are a few out-of-the-box examples:
Login Logout View that displays portlets View that lets a user customize the portlets on a page
Similar to style type and style components, there are secondary page type and secondary page components. Login and logout are examples of secondary page types, and a secondary page type can have multiple implementations, called secondary pages. Secondary page types and secondary pages perform different functional roles:
The secondary page type provides the processing logic (via Java classes). A secondary page provides the rendering logic (the JSP) for a particular
secondary page type. This design enables two different appearances to be developed for a particular site function, like the login page, without touching the pages processing logic. A site administrator can use the Portal site console to select the secondary page to be used by the site for each secondary page type.
See also: Chapter 4, Controlling Functionality with Secondary Pages, for details about secondary page and secondary page type development
Vignette Portal has two other page concepts related to secondary pages:
Portlet PageAlso referred to as a portlet display page and simply as a
"page," a portlet page allows administrators to rapidly create and configure portlet-oriented pages, without coding.
JSP Include PageThis feature is a quick way to introduce a custom JSP
page into the navigation of a site. Administrators, via the Portal site console, attach portlet pages and JSP include pages to the sites navigation tree, which is a visual representation of
30
the sites menus (see Figure 10). The end-user site displays the navigation via navigation styles (see Figure 11).
Figure 10:
navigation tree
Home
Products
Services
Figure 11:
Navigation
One secondary page type, called "Page Display," renders portlet pages for display to an end user. This particular secondary page type gets the portlet page that is attached to the currently selected navigation item and renders it. Rendering consists of generating the administrator-specified layout and invoking the portlets within that layout (see Figure 12).
31
Figure 12:
Similarly, when custom JSPs are displayed to an end user, there is one particular secondary page type, called "JSP Include Page," that handles invoking the custom JSP. The rendering of portlet pages or JSP include pages can be customized by creating a new secondary page of the Page Display or JSP Include Page secondary page type.
Grid Selection
Administrators, via the Portal administration consoles, can select the grid to be used with each secondary page type. Different secondary page types need different grids because different functionality requires inclusion of different style types. For example, the login page does not need the navigation style type: since the user isnt logged in to a site, the sites pages should not be accessible. On the other hand, a user on the main view of a site should be able to navigate that sites pages. Figure 13 illustrates this point.
32
Figure 13:
login
Additionally, administrators can select a grid per navigation item within a sites navigation tree. As a result, different portlet pages and JSP include pages within a site can have very different appearances. For example, Figure 14 shows the use of different grids to render the same portlet page with and without vertical navigation.
Figure 14: Portlet Page with and without Vertical Navigation
main view with horizontal and vertical navigation style of type "vertical navigation"
A user asks to log into site. Portal retrieves the secondary page of type "login". Portal gets the grid for the secondary page type. Portal renders the grid.
33
5 6
The grid applies the appropriate theme (which can be set and overridden at various levels) to get the correct styles. The grid invokes the login secondary page.
Figure 15 summarizes this process. (The details of the process would be a little different if the page requested were part of the navigation tree of a site.)
Figure 15: How Vignette Portal Composes a Page
Portal 1. Get login secondary page 2. Get grid for login secondary page
Style type: header Page Content
end user
URLs
Every Vignette Portal URL has the following elements in common:
protocol, domain name, and port web application context name the constant site followed by the name of the site slashes between elements
34
A URL ending with the site name displays the default page: the first menu item of the navigation tree. In all other cases, the URL includes the remainder of the path information. For a menu item, this path information is either the friendly URI assigned to the menu item, or (if there is no friendly URI) the constant menuitem followed by the menu items unique ID. For a secondary page other than a portlet display page, the path information is the constant template followed by the secondary pages friendly ID. (Note that friendly URIs and friendly IDs are user-assigned values that are mapped internally to unique IDs.) Figure 16 illustrates two URLs: one for a menu item having a friendly URI of products, and the other for the secondary page that enables end users to arrange the portlets on a portlet page.
Figure 16: Elements of Vignette Portal URLs
domain name webapp context site name menu item friendly URI
http://mydomain:80/portal/site/mysite/products/
port servlet URL sub-components controller (path info)
domain name
webapp context
site name
template friendly ID
http://mydomain:80/portal/site/mysite/template.MOVE_CONTENT/
port servlet controller URL sub-components (path info)
Portal administrators can configure the Portal web application to use only the HTTP protocol, to use only the HTTPS protocol, or to select the protocol based on the secondary page. In the selective case, the Portal framework checks whether the current secondary page is configured to be served securely and handles URL generation accordingly.
See also:
Vignette Portal Configuration Guide for information about configuring the Portal web application to serve secure requests Vignette Portal Administrators Guide for information about selecting the URL protocol and the security setting for each secondary page
35
returns a page of markup (HTML) to the user. Display requests result in the execution of the entire rendering framework: grid, styles, and secondary page.
Process requestA request to process something, like a form submission.
A process request usually ends in a redirect to a display request. Process requests do not execute grids or styles; instead, they execute processing logic contained in the secondary page. Here is how these two request types work together on the login secondary page:
A display request to the login secondary page results in a full Portal markup
the login secondary page. The process request executes the secondary pages processing logic. This logic logs the user in, then redirects the user to the main view of the site (which is a display request). This login scenario, with its display and process requests, is shown in Figure 17.
36
Figure 17:
end user
Clicks Log In
end user
Submits user name & password (A PROCESS request). Portal Site Presentation Framework Secondary Page Authenticates user, sends redirect for main view of portal.
redirect
browser
Portal Site Presentation Framework Grid Styles Secondary Page Renders main view using grid, styles, and page display secondary page.
Display Requests
37
Portal invokes the secondary pages display actions (which are Java classes; see Chapter 4, Controlling Functionality with Secondary Pages, for documentation of actions). Portal invokes the grid. The grids JSP, via custom Portal JSP tags, invokes the secondary pages JSP as well as the styles (each style contains a JSP).
2 3
end user
An alternative control flow is if a display action detects an error or unusual condition, which results in a redirection. For example, the user might be redirected to an error page. In this case, the grid, the styles, and the secondary page JSP are not invoked. Figure 19 illustrates this alternative control flow.
38
Figure 19:
end user
Process Requests
Process requests involve secondary pages, grids, and styles working together to service display requests. The processing order in a process request is as follows:
1 2
Portal invokes the secondary pages process actions. The last action processed returns a URL to a display request, to which the user is redirected.
Process requests do not invoke the grid, the styles, or the secondary page JSP. Figure 20 shows this control flow.
39
Figure 20:
end user
JSP
The request and response objects Portal-related context about the current request, like the current user Encapsulation of the URL creation logic
from the request: the grid for the request, the secondary page type for the request, fonts, colors, etc.
A log object, which supports logging errors and other messages in JSPs Custom JSP tags to do tasks such as internationalization, CSS style block
Chapter 5, Using Cascading Style Sheets, for discussion of how Vignette Portal uses CSS Appendix A, Vignette Portal Custom JSP Tag Reference, for a list and explanation of all Vignette Portal JSP tags Chapter 7, Using the Site Development APIs, for details about the other features mentioned above
40
2
Summary: Audience: Topics: See also:
Introduction to Style Types and Styles (below) Style Type and Style Architecture on page 43 Modifying the Look and Feel of Existing Styles on page 47 Developing Styles and Style Types on page 49 Deploying Styles and Style Types on page 72 Style Example: Adding Login Functionality to a Style on page 76
Chapter 1, Vignette Portal Web Site Overview, for additional discussion of the role of style types and styles within the Vignette Portal presentation framework
41
Figure 21:
Header
Vertical Navigation
Chrome
Chrome
Vertical Footer
Each style type can have many styles. A style is an implementation of a style type having a specific appearance and function. Styles control the rendering of their style types portion of a Portal page. The location of each style within a page is determined by the pages grid. (Grids are documented in Chapter 3, Controlling Page Structure with Grids.) A collection of styles that are designed to work together is known as a theme. The Vignette Portal administration consoles can be used to control styles in a variety of ways:
For each style type, one style can be selected for use on a particular site or
on all sites.
Site and system-wide default styles can be specified for use wherever a
used together.
The theme in use can be set at the menu item, site, or server level.
See also: Vignette Portal Administrators Guide for details about using the administration consoles to manage style types, styles, themes, and grids
42
common code that styles of the same style type can use
Component descriptor (component.xml file), required to upload the style
type using the deployment system A style consists of the following files:
Support files, which include the required primary JSP file and any
declare the same variable in the primary JSP or other support files for styles of that type.
43
Some out-of-the-box styles do not use template header files; others do.
When duplicating a Vignette style as the starting point for your own style, be aware of whether the style uses the template header file. Compilation errors can result if you apply the template header file to a style that was not designed to use it, as well as if you do not apply the template header file to a style that was designed to use it. The value of the apply-templateheader Boolean in a styles component.xml file determines whether that style uses the template header file.
Do not reuse code found in template header files shipped with Portal. These
files may use classes and methods that are not part of the Portal published API. Such classes and methods are subject to change between Portal releases. Using them can result in upgrade problems. At minimum, every template header file includes the page import and taglib directives, the custom JSP tag that defines the LOG and portalContext implicit objects, and the declaration of variables:
<%@ page %> <%-- epi_html is for backwards compatibility --%> <%@ taglib uri="epi-tags" prefix="epi_html" %> <%@ taglib uri="vgn-tags" prefix="vgn-portal" %> <vgn-portal:defineObjects/> <% //...variable declarations... %> import="javax.servlet.http.*, // ...more packages...
Table 3 describes variables declared in many of the template header files that ship with Portal. (Note that some of the variables declared in template header files are only to support previous Portal versions.)
Table 3: Common Variables Declared in Out-of-the-Box Template Header Files
Description String defining the site administration console link for the current site
44
Table 3: Common Variables Declared in Out-of-the-Box Template Header Files (Continued) Variable Name baseURL Description String concatenating the web application context, the servlet path, and the site name (if any). For example, if the URL is http://mydomain:80/portal/site/sample (where portal is the context, site is the servlet controller, and sample is the site name), the value of this variable is /portal/site/sample. com.epicentric.template.Branding object, used to retrieve the current users font and color preferences Same as baseURL String defining the Add Portlets link for the current page String defining the Site Home link for the current page String identifying the unique ID of the current Style object, used to retrieve the resource bundle for the style String defining the path to the images used in the end-user web site Boolean indicating whether the current site allows visitors (guests) to self-register String defining the Login link for the current site String defining the Logout link for the current site String defining the Arrange Portlets link for the current page com.epicentric.mypage.MyPageList object, containing the list of My Pages for the current user String defining the My Account link for the current user String defining the My Colors link for the current user and current site String defining the friendly ID for the appropriate My Pages secondary page: either "MY_PAGES_DISPLAY" or "MY_PAGES_MANAGE" String defining the My Pages link for the current user
branding controllerURL editContentURL homeURL i18nID imageRoot isSelfRegAllowed loginURL logoutURL moveContentURL mpList myAccountURL myColorsURL myPagesID
myPagesURL
45
Table 3: Common Variables Declared in Out-of-the-Box Template Header Files (Continued) Variable Name Description
pageBackgroundColor String identifying the current users page background color preference _pathToImages pathToStyle portalHttpRoot registerURL sessionInfo String defining the path to the images and other secondary files for the current style String defining the path to the secondary files for the current style (same as _pathToImages) Same as baseURL String defining the Register link enabling guests to selfregister com.epicentric.common.website.SessionInf o object, which contains current user, site, cookies, and other session-related information. com.epicentric.site.Site object, which encapsulates information about the current site Same as adminURL Boolean indicating whether the current user is being authenticated by a single-sign-on product String identifying the value of com.epicentric .common.website.ParameterConstants.SSO (the single-sign-on attribute) com.epicentric.template.Style object for the current style Same as i18nID Same as style String defining the title of the current com.epicentric.template.Style object current com.epicentric.user.User object
46
Use a Vignette Portal administration console to duplicate the style that you want to modify (Components >> Styles >> Style List). Select the duplicate from the style list, and use the Support Files tab to download the primary file to your local file system. Make any modifications you wish to your local copy of the primary file. You can change the look and feel by modifying the HTML, CSS, or JavaScript of the file.
47
Use Upload New... on the Support Files tab to upload the modified file into the Vignette Portal installation. IMPORTANT: The upload window includes a check box for indicating whether the template header file should be applied to the primary file youre uploading. An incorrect setting for this check box is likely to cause a compile error when your style is requested. Do not apply the template header file when duplicating any of the following Vignette styles:
Vignette Contemporary DHTML Horizontal Navigation Vignette Contemporary DHTML Vertical Navigation Vignette DHTML Horizontal Navigation Vignette DHTML Vertical Navigation Vignette Linear Nav Horz DHTML Vignette Linear Nav Vert DHTML Vignette Linear Nav Vert Interactive
For all other styles that ship with Portal, apply the template header. To determine whether the template header should be applied to any existing style, export the style, open its CAR file, and check the value of the apply-template-header flag in its component.xml file. If your primary file uses different images or other support files, upload them as well.
5
If you want to assign a new name and description to the duplicated style, use the Basics tab. A duplicated component has the same name as the original with (Duplicate) appended. It also has the same description as the original.
Portal administrators can now associate this duplicated style to a theme (Components >> Themes >> Style Name >> Associated Styles). Any Portal page that uses that theme will then use your duplicated style.
See also:
Chapter 5, Using Cascading Style Sheets, for information about how Vignette Portal uses CSS Appendix C, Vignette Portal JavaScript Functions, for a list and description of JavaScript functions that ship with Vignette Portal Vignette Portal Administrators Guide for information about using the administration consoles
48
49
Figure 22:
Header
personalizing the site fonts and colors, switching to the site console if the current user is a Portal site administrator, and returning to the "home" page of the site
Account Controls User-level links (such as My Pages menu item, login
and logout buttons, self-registration button, and user account maintenance button) and personalized welcome message. (See Style Example: Adding Login Functionality to a Style on page 76 for an example of a custom account controls style.)
Page Controls Links for adding portlets to a portlet display page and
changing the arrangement of portlets within a portlet page. In addition, the Floating Page Controls style type is a variation that is designed for use with the Vignette Contemporary theme, which "floats" the page controls outside the main content area of a portlet page. (See Chapter 3, Controlling Page Structure with Grids, for more about the Vignette Contemporary theme.) The current implementations of these style types are the Vignette Contemporary and Vignette Linear styles; if you want to customize any of the control styles, you should duplicate one of these styles as your starting point. Other control styles that ship with Portal are to support earlier versions of the product.
50
The Floating Page Controls template header file declares a number of variables that are unique to this style type. Table 4 lists these variables.
Table 4: Template Header Variables Specific to Floating Page Controls
allPermittedNodes Iterator over allNodes breadCrumbHTML linkedPage menuItemNode node pageModuleSet pathToImages showPageControls String specifying the name of the site Portlet page object that is linked to the selected menu item Menu item object that is currently selected Current menu item in the allPermittedNodes iteration Set of portlets for the linkedPage String defining the path to the images and any other secondary files for the current style Boolean indicating whether the page controls should be displayed
The control styles include logic for determining which links should be displayed. For example, the logout button is displayed only for a registered user where single sign-on is not the authenticator; the My Pages menu item is included only if the My Pages feature is enabled; and the registration link is displayed only if the request is not from a registered user and self-registration is allowed. (See Chapter 14, Users and Access Control, for an explanation of Portal users and authentication.)
51
The Portal site console uses a navigation tree to represent the hierarchy of that sites menus and submenus. Each menu and submenu is a navigation item within the navigation tree. Navigation items can either be created at the root level of the navigation tree or else nested within other navigation items to an arbitrary number of levels beneath the root level. Figure 23 shows the navigation tree for a site having multiple levels of navigation. The root level has three navigation items (Pages 1, 2, and 3); the second level has nine (Pages 1.1, 1.2, 1.3, 2.1, and so on); and Page 1.1 has additional levels.
Figure 23: Navigation Tree of the Portal Site Console
Navigation style types work in conjunction with grids (see Chapter 3, Controlling Page Structure with Grids) to define how navigation items actually display within an end-user page. The grid controls the location of the navigation items, and the navigation style types control the items colors, fonts, shapes, and other display characteristics. Portal ships with two navigation style types:
Horizontal displays navigation items under the control styles near the top of
an end-user page.
Vertical displays navigation items across the left side of an end-user page.
52
These two style types can be used together to create a navigation split, where some levels display horizontally and others vertically. Figure 24 shows how the navigation tree from Figure 23 might look with a horizontal-only style, a vertical-only style, and a navigation split.
Figure 24:
Horizontal
Split
See also:
Vignette Portal Administrators Guide for details about creating navigation items, assigning the default grid for a site, overriding the grid for a particular navigation item, enabling a navigation split, and selecting the styles to be used
53
Vignette Linear Nav Horz DHTML Vignette Linear Nav Vert DHTML
Vignette Linear Nav Vert Interactive is an AJAX-enabled style. The other styles calculate custom background colors. All of the above styles define their own JavaScript functions and CSS. If you want to customize the navigation styles, you should duplicate one of these as your starting point. (Note, however, that the AJAX and DHTML styles do not include the use of images in navigation items.) The remaining out-of-the-box navigation styles are primarily to support earlier versions of Vignette Portal. Here is a brief description of each of these:
Vignette Linear Nav Horz and Vignette Linear Nav Vert respond to the
current themes fonts and colors, support images in navigation items, but are not AJAX-enabled and do not support DHTML.
Vignette DHTML Horizontal Navigation and Vignette DHTML Vertical
Navigation do not calculate custom background colors based on the themes colors, unlike the Linear versions of these two styles. These styles include logic for rendering non-DHTML versions if the client browser does not support DHTML; the non-DHTML versions support use of images in navigation items.
Vignette Horizontal Navigation and Vignette Vertical Navigation use a
hard-coded background color for all nodes and support use of images in navigation items.
See also: Appendix D, Vignette Portal CSS Reference, for listings of theme properties and the corresponding CSS classes
Portal includes an out-of-the-box navigation style, Vignette Linear Nav Vert Interactive, that supports partial retrieval of navigation items and maintenance of the navigation trees state for the duration of the users session. The primary file for this style contains two sections, one for complete output of the navigation tree and the other for a partial update. The isPartialPageRequest() method on the PortalContext object differentiates between a complete and a partial page request. The first request to the navigation tree invokes as a standard (completeoutput) request, and the first level of visible navigation items are found and displayed:
54
MenuItemParams params = (MenuItemParams) request.getAttribute (ParameterConstants.MENU_ITEM_PARAMS); if (params == null) { params = new MenuItemParams(); request.setAttribute(ParameterConstants.MENU_ITEM_PARAMS, params); params.startLevel = 0; params.endLevel = params.startLevel + 1; params.allLevels = MenuItemUtils.generateVisibleMenuItemNode sForAllLevels(portalContext);
(See Visibility on page 64 for a discussion of visible menu item nodes.) When a navigation item in the tree is clicked, the partial update section of the primary JSP executes. Both the request and response are formatted as JSON objects. The request is parsed in JSON format and the child nodes for the selected navigation item are retrieved as follows:
JSONObject jsonobj = (JSONObject) JSONValue.parse(data); JSONObject treeNode = (JSONObject) jsonobj.get("node"); String treeNodeid = (String) treeNode.get("widgetId"); verticalnodes = MenuItemUtils.getChildrenForSelectedMenuItem (treeNodeid, pageContext);
For subsequent complete-output requests, the current state of the navigation tree is returned. The state is stored for each page of a site, in a twodimensional array having the form [pagename][expandedindices]. This array is serialized in a cookie, which is sent to Portal when a navigation item is requested. When the navigation tree is loaded into the browser, the cookie is deserialized to a JavaScript variable and used to expand the tree to its current state. Each site has its own cookie, which is cleared for a new user session. IMPORTANT: Do not apply the template header file to a custom style that is derived from this Vignette Linear Nav Vert Interactive style. Otherwise, the custom style will not compile.
See also: Chapter 7, Using the Site Development APIs, for further discussion of Portals AJAX capabilities, including its AJAX library
Some navigation styles shipped with Portal use DHTML to display navigation items. These styles have the following appearance and behavior in common (see Figure 25):
55
They display only the first level of the navigation tree (unless the site is
At the code level, the Vignette DHTML navigation styles share additional characteristics:
They use functions from the Vignette Portal JavaScript library as well as
DHTML support enabled. (The exceptions are the Vignette Contemporary styles, which are explicitly designed for DHTML.)
They use custom CSS values. They do not include the template header file.
IMPORTANT: Do not apply the template header file to a DHTML navigation style that is derived from one that ships with Vignette Portal. Otherwise, the style will not compile.
Static Navigation Styles
The remaining navigation styles that ship with Portal do not include any AJAX or DHTML code. They support earlier versions of the product. These styles share the following characteristics (see Figure 26):
They display the level for the currently selected navigation item and for the
next level (if applicable). If there are more than two levels, they display the whole path to the current level.
They use color and font changes to distinguish the currently selected menu
item.
56
They include the template header file for their style type (either horizontal
or vertical).
Figure 26: Static Navigation Example
Table 5 lists and describes the navigation-specific variables that are declared in the template header file for the static navigation style types.
Table 5: Navigation-specific Variables Declared in the Template Header File Description List of all menu items for the current user Integer specifying the last level in the navigation hierarchy List of all menu items for a horizontal style List of all menu items for a vertical style Integer specifying the first level in the navigation hierarchy Integer specifying the total number of menu items at all levels
In addition, the static navigation style types declare the following standard variables in their template header file:
57
Navigation Splits
A navigation split displays some navigation levels in one region and other navigation levels in another region. Using the navigation split feature requires a combination of three site console settings:
Selection of a grid that supports this feature Selection of a navigation style that supports this feature Specification of the navigation split level
A grid that supports a navigation split must use the <vgnportal:includeNavigation/> tags isSecondary attribute to specify one navigation style as secondary:
<vgn-portal:includeNavigation friendlyID="navigation-vertical" isSecondary="<%=true%>" />
For details about the <vgn-portal:includeNavigation/> tag, see Appendix A, Vignette Portal Custom JSP Tag Reference. Navigation levels after the split are displayed using the secondary navigation style. In the navigation split illustrated in Figure 24 on page 53, the split occurs between levels 2 and 3, and the vertical navigation style is the secondary navigation. As a result, the first and second navigation levels are displayed horizontally, while the third and any subsequent levels are displayed vertically. NOTE: As shipped, Vignette Portal grids that support a navigation split use the horizontal style as the primary navigation and the vertical style as the secondary navigation. A navigation style that supports the navigation split feature checks the value of the MENU_NAVIGATION_SPLIT static variable on com.epicentric.site.SiteSettings, as follows:
Site site = portalContext.getCurrentSite(); // (Note that SiteSettings implements Settings.) Settings siteSettings = site.getSettings(); int navSplit = com.vignette.portal.util.StringUtils.parseInt(site Settings.getSetting(SiteSettings.MENU_NAVIGATION_S PLIT), 0);
The navSplit variable returns the level where the secondary navigation begins, or 0 if the site has not enabled a navigation split. The primary file for
58
the Vignette Linear Nav Vert style (blue_vertical_nav.jsp) shows how this variable is used to construct the secondary navigation.
See also:
Chapter 3, Controlling Page Structure with Grids, for an example of a grid supporting split navigation Vignette Portal Administrators Guide for details about using the site console to select grids, styles, and a navigation split
navigation items displayed for a particular user depend upon the permissions of the user groups to which that user belongs, a MenuItemNode is a requestspecific object. For the navigation styles shipped with Portal, menu item nodes are either displayed or hidden based on the value of a visibility attribute (discussed in Visibility on page 64). A style gets access to all visible nodes for the current request by calling a method on a utility class (also in com.epicentric.common.website):
MenuItemUtils.generateVisibleMenuItemNodesForAllLevels(po rtalContext)
To get access to all nodes irrespective of the visibility attribute, call this method instead:
MenuItemUtils.generateMenuItemNodesForAllLevels(portalCon text)
Nodes can then be retrieved using various accessor methods on MenuItemUtils. Here are a few examples:
MenuItemUtils.getAllVisibleNodes(portalContext) MenuItemUtils.getAllNodes(portalContext) MenuItemUtils.getNodesInHorizontalOrder(allLevels, startLevel, endLevel) MenuItemUtils.getNodesInVerticalOrder(allLevels, startLevel, endLevel)
The startLevel and endLevel variables are parameters stored on the request. The allLevels variable is stored on com.epicentric.common.website.MenuItemParams.
59
Links. A node is associated with either a URL or a blank space (typically a spacer GIF used to create menu groupings). Navigation styles use the isSpacer(), getHref(), getTarget(), and getTitle() methods on MenuItemNode to retrieve and handle these associations, as shown in the following code snippet (where the node variable represents the current MenuItemNode object): <% if (node.isSpacer()) { %> <img src="<%= _pathToImages %>spacer.gif" border="0" alt="" width="10px" height="3" /> <% } else { %> <a href="<%= node.getHref() %>" <%=node.getTarget()%> class="epi-link3"> <%=node.getTitle()%></a> <% } %> Friendly URIs. The URI for a menu item node has the format protocol://domain:port/context/site/sitename/menuitem.id. Portal administrators have the option of assigning a friendly URI as a replacement for the menuitem.id portion of the URI for a given node. You can retrieve one from the other by using these methods on MenuItemUtils:
The getFriendlyURIFromMenuItemID() method returns null if there is no friendly ID defined for the specified node. Friendly URIs must be unique within a site.
Fonts and Colors. You can use a different visual treatment for the currently selected menu item node, such as a bold font and a lighter background color to distinguish it from the other visible nodes. The isSelected() method on MenuItemNode returns true for the currently selected node.
You can also use different rendering for the parent nodes of the currently selected node. The wasSelected() method on MenuItemNode returns true for the parent nodesthe ones that were selected to get to the currently selected node. In the navigation style shown in Figure 27, gradations of the background color are used to distinguish the currently selected node and its parent nodes. Page 1.1.1 is the currently selected node (isSelected is true); Page 1 and Page 1.1 are the parent nodes (wasSelected is true).
60
Figure 27:
DHTML styles use a dark shade of the background color to display the mouse-over path, as Figure 25 on page 56 illustrates. To retrieve fonts and colors that conform to the server, site, and user settings, use com.epicentric.template.BrandingUtils .getUserBranding(PortalContext portalContext). The values for the fonts and colors can either come from the styles own CSS or from the Vignette Portal CSS. Site administrators can also assign a particular color to any item within the navigation tree. Portal navigation styles use these assigned colors only on nodes where either isSelected() or wasSelected() is true.
See also:
Chapter 5, Using Cascading Style Sheets, for more about how Portal uses CSS Chapter 7, Using the Site Development APIs, for a discussion of Portal branding
Menu item nodes can be represented by images that portal administrators upload when configuring the navigation tree. Each node can have its own set of images. These images are instances of com.epicentric.common.website.MenuItemNodeImage. The getImage(int imageState) and getImage(int imageState, boolean ignoreOtherStates) methods on MenuItemNode enable you to retrieve a MenuItemNodeImage. The imageState value is one of the following MenuItemNode constants:
Images.
61
<% if (node.usesImages() && node.hasImages()) { // display images MenuItemNodeImage image = null; MenuItemNodeImage imageHover = null; if (node.isSelected()) { image = node.getImage(MenuItemNode.IMAGE_SELECTED); imageHover = node.getImage(MenuItemNode.IMAGE_SELECTED _HOVER); } else { image = node.getImage(MenuItemNode.IMAGE_NORMAL); imageHover = node.getImage(MenuItemNode.IMAGE_NORMAL _HOVER); } String imageTagName = "image_" + node.getID(); %> <a class="epi-link3" href="<%= node.getHref() %>" onMouseOver=<%=imageTagName%>.src= "<%=imageHover.getPath()%>"; <%=imageTagName%>.width= "<%=imageHover.getWidth()%>"; <%=imageTagName%>.height= "<%=imageHover.getHeight()%>" onMouseOut=<%=imageTagName%>.src= "<%=image.getPath()%>"; <%=imageTagName%>.width="<%=image.getWidth()%>"; <%=imageTagName%>.height="<%=image.getHeight()%>" > <img name="<%=imageTagName%>" id="<%=imageTagName%>" src="<%=image.getPath()%>" width="<%=image.getWidth()%>" height="<%=image.getHeight()%>" alt="<%=node.getTitle()%>" border="0"> </a> <% } else { // display text %> <a href="<%= node.getHref() %>" <%=node.getTarget()%> class="epilink3"><%=node.getTitle()%></a> <% } %>
The following out-of-the-box styles have built-in support for images in navigation items:
Vignette Linear Nav Horz
62
Vignette Linear Nav Vert Vignette Horizontal Navigation Vignette Vertical Navigation
A navigation item image is imported and exported along with its site.
Custom Properties.
Menu item nodes can have any number of custom properties, which can be used to influence menu item rendering. You define custom properties in your code, and portal administrators maintain the property values through the site console (or server console, in the case of navigation blocks). The getProperty(String propertyName) method on MenuItemNode enables you to retrieve the value of a custom property. For example, to create a tooltip for a link, you could simply declare a string for the custom property name, and then retrieve the property value using the links title attribute:
<% String TOOLTIP = "Hover Text"; while ... { // within loop through nodes for current level... %> <a href="<%= node.getHref() %>" title="<%= node.getProperty(TOOLTIP) != null ? node.getProperty(TOOLTIP) : node.getTitle()%>" ...> <%= node.getTitle() %> </a> ... }
The value of the Hover Text custom property would be displayed as a tooltip for each node where the portal administrator had defined such a value; otherwise, the nodes title would be displayed as the tooltip text. Another example of custom menu item properties is for the case where a menu item node can display different images based on the users locale. Portal administrators could associate supported locales with image files by setting custom properties like this:
Name graphic_en graphic_de graphic_fr Value products_english.gif products_german.gif products_french.gif
63
Assuming that each of these values corresponds to an image that has been uploaded as a secondary file of the navigation style, you can use these custom properties to retrieve the locale-appropriate image as follows:
//get user locale; prepend underscore to it Locale profileLocale = I18nUtils.getLocalizer(session, request).getLocale(); String userLocale = profileLocale.getLanguage() != null ? "_"+profileLocale.getLanguage() : ""; //declare variable for custom property String IMAGEPREFIX = "graphic"; //get image path String pathToImages = portalContext.getPortalHttpRoot() + portalContext.getCurrentStyle().getUrlSafeRelative Path(); while ... { // within loop through nodes for current level... String imagePrefixString = ""; String nodeTitle = node.getTitle(); if (node.getProperty(IMAGEPREFIX+userLocale) != null) { imagePrefixString = "<img src=\"" + _pathToImages + node.getProperty(IMAGEPREFIX+userLocale) + "\"/>"; } if (!StringUtils.isEmpty(imagePrefixString)) { nodeTitle = imagePrefixString; } ... }
The resulting nodeTitle string can then be used in the nodes link:
<a href="<%= node.getHref() %>" ...><%= nodeTitle %></a>
Note that the above example does not use the MenuItemNodeImage class discussed in Images on page 61; the images for this example would be uploaded with the navigation style rather than with the navigation item.
Visibility. In some cases, your organization might not want a menu item node to be visible. For example, your content could include its own menu tree; or you might want to link to content (such as the articles behind headlines or "teasers") from somewhere other than the navigation style. For such cases, portal administrators can use the site console (or server console, in the case of navigation blocks) to hide a navigation item. You can use the isVisible() method on MenuItemUtils to check whether a given navigation item is
64
hidden. Other methods on MenuItemUtils enable you to retrieve either visible menu items or all menu items.
Several secondary page types use the chrome style, including Page Display, Maximize, My PagesPage Display, and My PagesMaximize View. Chrome styles can display any view of a portlet. However, some portlet window states, such as RAW, are designed not to include any chrome. In such a case, the Chrome style will not be invoked.
See also:
Chapter 7, Using the Site Development APIs, for discussion of the various ways that portlet content can be rendered Chapter 4, Controlling Functionality with Secondary Pages, for details about secondary pages Chapter 11, Using Portlet Modes and Window States, for a description of RAW and other window states for Java standard portlets
65
The Chrome template header file declares a number of variables that are specific to chrome rendering. These variables are listed and described in Table 6.
Table 6: Chrome-specific Variables Declared in the Template Header File Description ID attribute of an HTML element associated with the drag-and-drop behavior of the chrome within a Portal page Boolean indicating whether the secondary page that invoked this chrome style contains the necessary DHTML to support drag-and-drop behavior within the Portal page Current users preferred color for the portlet windows background Current users preferred color for the portlet windows title bar Current users preferred color for the portlet windows border Current users preferred color for the portlet windows title Object containing state information about the portlet window
invokingStyleSupportsDrag
Other obsolete chrome-related variables are included in the template header file only for compatibility with earlier versions of Vignette Portal. The following variables are available only if the version property is set to 4.x (portal.controller.version_support=4.x) in the Portal configuration file:
bean deleteURL editable editURL maximizeURL minimizeable minimized
66
A key interface for chrome styles is com.vignette.portal.portlet .website.PortletWindowBean. Implementations of this interface provide all of the state information that a chrome style needs to render a portlet window within a Portal page. This information includes the portlets current mode and window state, the supported modes and window states for the portlet (used to determine which chrome buttons to display), the UID used to access the portlets localized title, and the portlets default title. The primary JSP file uses the PortletWindowBean instance that is accessed through the portletWindow scripting variable, initialized in the template header file:
<jsp:useBean id="portletWindow" scope="request" type="com.vignette.portal.portlet.website.PortletWindow Bean" />
Since the same chrome style can be invoked several times on a page, it may be necessary to namespace HTML elements or JavaScript to avoid collisions.
67
The getNamespace() method on the portletWindow object can be used for this purpose. For example:
<table id="<%= portletWindow.getNamespace() %>" border="0" cellspacing="0" cellpadding="0" width="100%"> Displaying the Portlet Window Title Bar.
The title bar of a portlet window displays the portlet title and the appropriate buttons for personalizing the portlet, maximizing it, etc. Call portletWindow.getPortletUID() to get the I18N resource bundle for the portlet; call portletWindow.getConfiguredTitle() to get the localized default title as configured by the Vignette Portal administrator. For example:
(See Chapter 6, Internationalizing and Localizing Site Components, for an explanation of Vignette Portal I18N tags and methods.) If, instead, you want to get the title as set by the portlet, use this statement:
<%= portletWindow.getPortletSetTitle();
To determine what buttons to include in the title bar, a chrome style must check the portlets current mode, current window state, capabilities, and permissions. The portletWindow object has methods for performing such checks as well as for getting button URLs. For example, the following code displays the Edit button in a table cell if the portlet supports, but is not currently in, the edit mode:
<% if ((!portletWindow.isInEditMode()) && (portletWindow.isEditModeAllowed())) { %> <td align="right" valign="top" width="1%"> <a href="<%= portletWindow.getEditModeURL() %>"><vgnportal:i18nElement><img src="<%=_pathToImages%>icon_portlet_edit.gif" title="<vgn-portal:i18nValue stringID="<%=i18nID%>" key="edit_button" defaultValue="Edit portlet" />" border="0" width="28" height="15"></vgnportal:i18nElement></a> </td> <%
68
} %>
<vgn-portal:onRenderSuccess>
<vgn-portal:insertPortletContent/>
<vgn-portal:onRenderFailure>
69
defaultValue="An error has occurred. This portlet is unavailable at this time."> <vgn-portal:i18nParams value="<%= portletRenderException.getErrorParameters() %>"/> </vgn-portal:i18nValue> ... Optional HTML/JSP ... </vgn-portal:onRenderFailure> </vgn-portal:renderPortlet> See also:
Appendix A, Vignette Portal Custom JSP Tag Reference, for details about these and all other Portal JSP tags Chapter 7, Using the Site Development APIs, for a discussion of other ways that portlets can be included in Portal pages
Chromeless Portlets
The Portal administration consoles (Components >> Portlets >> Portlet List >> Portlet Name >> Basics) enable the chrome for a particular portlet to be suppressed. The result is that the content for that portlet appears to be part of the page. This feature provides a convenient way of embedding text or other content into a portlet display page. Figure 29 shows an example of a chromeless portlet.
Figure 29: Chromeless Portlet on a Portlet Display Page
70
In the case of a chromeless portlet, the content is rendered by a portlet display page (such as Page Display, Maximized, or Raw) instead of by a chrome style.
See also:
Chapter 4, Controlling Functionality with Secondary Pages, for an explanation of portlet display pages Chapter 7, Using the Site Development APIs, for discussion of alternative ways of rendering portlet content
The Portal administration consoles also enable a custom property to be assigned to an individual portlet. The value of such a property can be retrieved by a chrome style by calling getPortletProperty() on the portletWindow. For example, the content of a portlet might include a message that Portal administrators change periodically. If the Custom Properties page for that portlet defined a value for a string property named adminMessage, the portlet could display the current value of the string by calling portletWindow.getPortletProperty(adminMessage) within the chrome style. As another example of a custom property, administrators can create color schemes for portlets by setting a custom color property that the chrome style retrieves and uses.
71
Component Descriptor
A file named component.xml describes a style, style type, or any other Vignette Portal component. You can create the component.xml file for a new seither manually or by using the administration consoles export mechanism. All components share many common component.xml elements. This section discusses the elements and the attribute values that are unique to styles and style types.
Styles
The component.xml file for a style has the following syntax (with the items discussed in this section shown in bold type):
<epideploy:component build-version="string" component-id="string" component-type="Styles" major-version="integer" minor-version="integer" epi-version="string" epi-build="integer"
72
title="string" description="string" xmlns:epideploy="http://www.epicentric.com/deployment"> <epideploy:required-component component-type="Style Types" component-id="string" major-version="integer" minor-version="integer" /> <epideploy:detail> <style-info id="string" friendly-id="string" title="string" description="string" primary-filename="string" template-uid="string" template-default="true"|"false" apply-template-header="true"|"false" is-system="true"|"false" visible="true"|"false" </style-info> </epideploy:detail> </epideploy:component>
The component-type for a style is the literal string value "Styles"; the component-type for its required component is the literal string value "Style Types". The template-uid is the ID of this styles style type, as defined in the style types component.xml. The apply-template-header Boolean specifies whether the deployment system includes the style types header file (if any) when deploying this style.
Style Types
The component.xml file for a style type has the following syntax (with the items discussed in this section shown in bold type):
<epideploy:component build-version="string" component-id="string" component-type="Style Types" major-version="integer" minor-version="integer" epi-version="string"
73
epi-build="integer" title="string" description="string" xmlns:epideploy="http://www.epicentric.com/deployment"> <epideploy:detail> <template-info id="string" friendly-id="string" title="string" description="string" type="templatetype_ui_element" is-system="true"|"false" visible="true"|"false" allow-guest-access="true" | "false" header-filename="string" > </template-info> </epideploy:detail> </epideploy:component>
The component-type for a style type is the literal value "Style Types". The type for the styles covered in this chapter is the literal value "templatetype_ui_element". The header-filename is the name of the template header file. The Vignette Portal convention is to name this file "template_header.inc". Note that a style type component.xml file does not have the <epideploy:required-component> element.
See also:
Chapter 8, Deploying Site Components, for discussion of component.xml files Appendix B, Deployment Reference, for details about every element and attribute of component.xml files
74
CAR File
The component archive (CAR file) contains all of the files for a style or style type. The Portal deployment system requires the CAR file to have a specific directory structure. Table 8 shows the required directory structure for styles.
Table 8: CAR File Directory Structure for Styles Files
component.xml (required) primary JSP file (required) any other JSP files any image, CSS, JavaScript, or other files required by the style
/WEB-INF/i18n
.properties file for each locale (See Chapter 6, Internationalizing and Localizing Site Components, for more about I18N .properties files.)
As shown in Table 9, for style types the CAR file includes only a root directory, which contains the component.xml and template header files.
Table 9: CAR File Directory Structure for Style Types Files
You can create the CAR file using the Java jar command or any compression utility that uses the ZIP format. Alternatively, you can create the CAR file automatically by using the export feature of the administration consoles.
See also: Chapter 8, Deploying Site Components, for a discussion of the deployment system and CAR files
Components).
Place the CAR file in the PortalInstallDir/deployment/upload
75
Here is how you could accomplish this enhancement for a particular site:
1
From the site console, duplicate the style that you want to customize. (On the Styles page (Components >> Styles >> Style List), checkmark the style, then select Duplicate from the drop-down list at the bottom of the page.)
Download the duplicates primary file. (Select the duplicate, click the Support Files tab, click the Download link, and save the primary file to your local file system.) You might also want to assign the duplicate a more meaningful name, such as Custom Account Controls with Login.
Modify the primary file to incorporate the login functionality. The changes required are as follows:
a
Get the realms that the user can be authenticated against. For example:
76
Create a form that uses the login secondary pages process URI. Included in this step is using the createProcessURI() method on PortalContext, passing in the friendly ID of the login secondary page. For example:
<form action="<%= portalContext.createProcessURI("LOGIN") %>" method="post" name="login_form" style="display: inline; margin: 0px">
Add conditional logic to display the login controls. The login controls should display if the current user is a guest, the environment is not single-sign-on, and the current secondary page is not the login page:
<% if (guestUser && !SSO && !ParameterConstants.PAGE_LOGIN.equals(secPageType)) { %> <vgn-portal:i18nValue stringID="<%= i18nID %>" key="username" defaultValue="Username:" /> <input class="epi-input" type="text" size="20" name="logon" id="username" value="" /> <vgn-portal:i18nValue stringID="<%= i18nID %>" key="password" defaultValue="Password:" /> <input class="epi-input" type="password" size="20" name="password" id="password" value="" /> <input type="hidden" name="realm" value="<%=rlm.getID()%>"> <input class="epi-button" type="submit" name="Submit223" value="<vgn-portal:i18nValue stringID="<%= i18nID %>" key="submit223label" defaultValue="Log In" />" /> <% } //else logic... //(preexisting in style) %>
Notice in the above snippet that the form labels have been localized and a hidden field has been assigned the users realm ID.
4
Upload your modified primary file. (Using your duplicate styles Support Files tab, click the Upload New... link, specify the path and name of your primary file. Be sure the state of the
77
"apply header" file is correct, as described in the note marked IMPORTANT on Page 56.)
5
Associate your new style with the theme used for guest users. (Go to Site Settings >> Appearance to see what theme is associated with guest users. Then go to Components >> Themes >> Guest User Theme >> Associated Styles to associate your new style with the Account Controls style type.)
78
3
Summary: Audience: Topics: See also:
Introduction to Grids (below) Grids Shipped with Portal on page 80 Modifying the Look and Feel of Existing Grids on page 83 Developing Grids on page 84 Custom JSP Tags Used in Grids on page 85 Deploying a Grid on page 86 Grid Example on page 88
Chapter 1, Vignette Portal Web Site Overview, for additional discussion of the role of grids within the Portal presentation framework
Introduction to Grids
A grid is a site component that defines the display locations for the various elements of a Portal page:
The style types to be included, such as header, footer, and navigation items The main content, which is provided by a secondary page through the <vgn-portal:includePageContent/> custom JSP tag
The regions included on a Portal page depend upon the purpose of that page. As a result, different types of pages require different grids. For example, the grid for a login page needs to define only a few regionsthe location of controls, the HTML form from the secondary page, and possibly a header and footerwhereas the grid for a portlet display page typically defines the
79
location of site controls, account controls, navigation regions, the portlet display region, and a header and footer (see Figure 32).
Figure 32:
Header Account Controls
<includePageContent/>
Vertical Navigation
<includePageContent/>
Footer
Vertical Footer
As shipped, the most commonly used grid is the server default grid. Among the secondary pages that use the server default grid (as shipped) are the pages for displaying, adding, and arranging portlets. Vignette Portal site administrators can associate each secondary page type with a grid, set the site-wide grid default, and override the site-wide grid at either the page or menu item level. Portal server administrators can define the server-wide default grid as well as assign a default grid to each secondary page type.
See also:
Chapter 2, Controlling Navigation and Appearance with Styles, for details about developing styles and style types Chapter 4, Controlling Functionality with Secondary Pages, for details about developing secondary pages and secondary page types Vignette Portal Administrators Guide for information about using the server and site consoles to manage components
80
style types that it uses. (For an explanation of each style type, see Chapter 2, Controlling Navigation and Appearance with Styles.)
Table 10: Summary of Vignette Grids Site Account NavigaHeader Controls Controls tion X X
Grid Title Vignette Contemporary Front Page Vignette Content-Only Vignette Frame View Vignette Front Page Vignette Front Page - Vertical Only Vignette Linear Front Page (Horz Nav)
Footer
Notes
Horizontal Horizontal Also includes floating page and controls; see discussion Vertical below Contains the <includePageContent> tag only
X X
X X Horizontal Horizontal "Light" version has less table and nesting Vertical Vertical Horizontal
Horizontal Horizontal Imports JavaScript functions for form handling "Light" version has less table nesting
Vignette Linear Front Page (Split Navigation) Vignette Linear Front Page (Vert Nav)
Imports JavaScript functions for form handling Calculates color gradations between style types Imports JavaScript functions for form handling "Light" version has less table nesting Includes page content title and CSS styles only
Vertical
Vertical
81
Table 10:
Summary of Vignette Grids (Continued) Site Account NavigaHeader Controls Controls tion
Footer
Notes Like Vignette Linear Popup Page except also includes style for page background color
Horizontal Includes a 4.x style type called System Controls (now obsolete) X Horizontal
Note that grids do not include the Portlet Chrome style. Secondary page types that display portlets, such as Page Display and Maximize, typically incorporate the chrome style. Most grids also do not include the Page Controls style, which provides buttons for adding and arranging portlets; rather, the page controls are typically incorporated, indirectly, through the <vgnportal:includePageContent/> tag in the grid. This tag results in the execution of the appropriate secondary page. In the case of the Page Display secondary page (which displays portlets), the Page Controls style is called from one of the secondary pages include (.inc) files. One out-of-the-box gridthe Vignette Contemporary Front Page grid includes a call to a special page controls stylethe Floating Page Controls styledirectly in the grid. This style and grid are designed to place the page controls outside of the area where the page content is displayed (see Figure 33). They should be used in conjunction with the Vignette Contemporary theme, whose "regular" page controls style is the Empty Page Controls style. This style is a JSP file with no code. It is the one that is indirectly invoked through the Contemporary grids call to the <vgnportal:includePageContent/> tag; as a result, the "regular" page controls are not displayed, even though they are invoked from the secondary page.
82
Figure 33:
See also:
Chapter 4, Controlling Functionality with Secondary Pages, for a discussion of secondary page types
Use a Portal administration console to duplicate the grid that you want to modify (Components >> Grids). Select the duplicate from the grid list, and use the Support Files tab to download the primary file to your local file system. Make any modifications you wish to your local copy of the primary file. You can change the look and feel by modifying the HTML, CSS, or JavaScript of the file.
4 5
Use Upload New... on the Support Files tab to upload the modified file into the Portal installation. If you want to assign a new name and description to the duplicated grid, use the Basics tab.
83
Developing Grids
A duplicated component has the same name as the original with (Duplicate) appended. It also has the same description as the original.
See also:
Chapter 5, Using Cascading Style Sheets, for information about how Portal uses CSS Appendix C, Vignette Portal JavaScript Functions, for a list and description of JavaScript functions that ship with Portal Vignette Portal Administrators Guide for information about using the administration consoles
Developing Grids
To develop a new grid, create a single JSP file that defines the grids structure. To see the source code for a grid that ships with Portal, use an administration console to duplicate and export the grid. A grid is enclosed within opening and closing <HTML> and <BODY> tags. Vignette grids use HTML tables for the basic structurefor example:
<table> <tr> <td><!--header area--></td> </tr> <tr> <td><!--site controls area--></td> </tr> <tr> <td><!--horizontal navigation--></td> </tr> <tr> <td><!--vertical navigation--></td> <td><!--page content area--></td> </tr> <tr> <td><!--footer area--></td> </tr> </table>
A grids rows and cells depend upon the style types that the structure includes. In two special casescontent-only and popup gridsthere are no rows and cells because there are no style types included.
84
<vgn-portal:includeNavigation/>
<vgn-portal:styleBlock/>
See also:
Appendix A, Vignette Portal Custom JSP Tag Reference, for more about all custom JSP tags provided by Portal
85
Deploying a Grid
Deploying a Grid
Once youve created a new grid, it can be deployed into one or more Portal installations. The deployment system takes a specially formatted file known as a component archive (CAR file) as its input. The component archive contains all of the components files as well as a component descriptor (component.xml file). This section explains the contents of the component descriptor and component archive for grids. NOTE: The export mechanism of the administration consoles creates component archive and descriptor files for an existing component. You can use this mechanism as an alternative to creating these files from scratch. However, you should carefully check the resulting files against the information in this section and modify them as appropriate before using them to deploy a new grid.
See also: Chapter 8, Deploying Site Components, for more about the deployment system
Component Descriptor
A file named component.xml describes a grid or any other Vignette Portal component. All components share many common component.xml elements. This section discusses the elements and the attribute values that are unique to grids. The component.xml file for a grid has the following syntax (with the items discussed in this section shown in bold type):
<epideploy:component build-version="string" component-id="string" component-type="Grids" major-version="integer" minor-version="integer" epi-version="string" epi-build="integer" title="string" description="string" xmlns:epideploy="http://www.epicentric.com/deployment"> <epideploy:required-component component-type="Style Types" component-id="template0005"
86
Deploying a Grid
major-version="integer" minor-version="integer" /> <epideploy:detail> <style-info id="string" friendly-id="string" title="string" description="string" primary-filename="string" template-uid="template0005" template-default="true"|"false" apply-template-header="false" is-system="true"|"false" visible="true"|"false" </style-info> </epideploy:detail> </epideploy:component>
The component-type for a grid is the literal string value "Grids"; the component-type for its required component is the literal string value "Style Types". All grids share one grid style type, which is component template0005. Therefore, this is the value for the required component component-id as well as the template-uid. The Vignette Portal naming convention for grid IDs (component-id and id attributes) is t0005style followed by a unique integer. To ensure that your grids do not collide with Vignettes, if you use the same naming convention include your organizations name in the grid ID. The apply-template-header Boolean is set to false for grids because they do not have header files.
See also:
Chapter 8, Deploying Site Components, for discussion of component.xml files Appendix B, Deployment Reference, for details about every element and attribute of component.xml files
CAR File
The component archive (CAR file) for a grid requires two files:
the grids component.xml file the grids primary JSP file
87
Grid Example
In addition, a grid CAR file can contain support files, such as a grid-specific CSS file. Place these files in the same directory, then create the CAR file using the Java jar command or any compression utility that uses the ZIP format.
See also: Chapter 8, Deploying Site Components, for a discussion of the deployment system and CAR files
Components).
Place the CAR file in the PortalInstallDir/deployment/upload
Grid Example
This example is for a grid that includes the following style types:
88
Grid Example
Figure 34:
Header
Vertical Navigation
<includePageContent/>
Footer
The JSP file for this grid starts with the JSP page directive, the Vignette tag library declaration, and the <vgn-portal:defineObjects> tag that all Vignette components include:
<%@ page import="java.util.*" %><%@ taglib uri="vgn-tags" prefix="vgn-portal" %> <vgn-portal:defineObjects/>
Next are the <html> opening tag and (within the <head> tag) the custom tags for including the secondary page title and CSS style block, the definition of the location of the JavaScript library, and the localized message to be displayed if the client does not support JavaScript:
<html> <head> <vgn-portal:pageContentTitle /> <vgn-portal:styleBlock /> <script language="JavaScript" src="<%= portalContext.getPortalHttpRoot() %>jslib/form_state_manager.js"> </script> <noscript><vgn-portal:i18nValue stringID="<%= portalContext.getCurrentStyle().getUID() %>" key="noscript" defaultValue="In order to bring you the best possible user experience, this site uses JavaScript. If you are seeing this message, it is
89
Grid Example
likely that the JavaScript option in your browser is disabled. For optimal viewing of this site, please ensure that JavaScript is enabled for your browser."/> </noscript> <base target="_top"> </head>
NOTE: The <vgn-portal:pageContentTitle/> tag wraps the title in opening and closing <title> tags, so you should not include these tags yourself. Following the <head> tag, the <body> tag uses the Vignette CSS class to retrieve the background color for the page:
<body class="epi-pageBG" topmargin="0" leftmargin="0" rightmargin="0" bottommargin="0" marginwidth="0" marginheight="0">
A full-size outer table encloses the grid and includes the footer:
<table cellpadding="0" cellspacing="0" width="100%" height="100%"> <tr> <td valign="top" width="100%" height="100%"> </td> </tr> <tr> <td valign="bottom" height="1"> <vgn-portal:includeStyle friendlyID="footer" /> </td> </tr> </table>
Within the first cell of this outer table, a nested table includes the header on the first row and the site controls on the second:
<table cellpadding="0" cellspacing="0" width="100%" height="100%"> <tr> <td colspan="2" height="1"> <vgn-portal:includeStyle friendlyID="header"/> </td> </tr> <tr> <td colspan="2" height="1"> <vgn-portal:includeStyle friendlyID="site_controls"/> </td> </tr>
The next row of the inner table defines the horizontal navigation:
90
Grid Example
<tr> <td colspan="2" height="1"> <!-- Begin horizontal navigation --> <vgn-portal:includeNavigation friendlyID="navigationhorizontal" /> <!-- End horizontal navigation --> </td> </tr>
The vertical navigation and page content are included in the two cells of the final row of the inner table. Notice that the vertical navigation style type is the secondary navigation for this grid:
<tr> <td valign="top" class="epi-BG2" height="100%"> <!-- Begin vertical navigation --> <vgn-portal:includeNavigation friendlyID="navigationvertical" isSecondary=<%= true %> /> <!-- End vertical navigation --> </td> <td valign="top" width="100%"> <!-- Begin pageContent --> <vgn-portal:includePageContent /> <!-- End pageContent --> </td> </tr> </table>
The file is now complete, except for the closing <body> and <html> tags:
</body> </html>
91
Grid Example
92
4
Summary: Audience: Topics: See also:
Introduction to Secondary Pages (below) Modifying the Look and Feel of an Existing Secondary Page on page 95 Secondary Page Types and Secondary Page Instances on page 96 Actions: Where Secondary Pages Do Processing on page 98 Developing a Secondary Page Instance on page 101 Developing a Secondary Page Type on page 115 Creating Custom Portlet Page Layouts on page 115 Automating the Validation and Population of HTML Forms on page 121 Secondary Page Deployment on page 136
Chapter 1, Vignette Portal Web Site Overview, for additional discussion of the role of secondary pages within the Portal site presentation framework
93
content/functionality portion. That portionthe region surrounded by dotted lines in the figuresis rendered by secondary pages.
Figure 35: Portlet Page Example
Figure 36:
94
Use a Portal administration console to duplicate the secondary page that you want to modify (Components >> Pages >> Secondary Page List). Select the duplicate from the secondary page list, and use the Support Files tab to download the primary file to your local file system. Make any modifications you wish to your local copy of the primary file. You can change the look and feel by modifying the HTML, CSS, or JavaScript of the file. (Chapter 5, Using Cascading Style Sheets, discusses CSS and Portal; Appendix C, Vignette Portal JavaScript Functions, provides JavaScript reference information.) TIP: You can include a particular portlet within a secondary page simply by inserting Vignette Portal JSP tags that render the portlets content. For details, see Displaying Portlets in Chapter 7, Using the Site Development APIs.
Use Upload New... on the Support Files tab to upload the modified file into the Portal installation. If your secondary page uses different images or other support files, upload them as well.
Use the Basics tab to verify or change the secondary pages default values. A duplicated component has the same name as the original with (Duplicate) appended as well as the same description as the original. The Basics tab also has a check box for controlling whether this secondary page should be served over HTTPS instead of HTTP.
Portal site administrators can now make this duplicated secondary page the one to use for its secondary page type (Site Settings >> Appearance >> Secondary Pages); Portal server administrators can make it the server-wide default secondary page for its type (Server Settings >> Server Defaults >> Site & Appearance >> Default Secondary Pages).
95
The rest of this chapter explains concepts and procedures for developing new secondary page instances and types.
See also:
Creating Custom Portlet Page Layouts on page 115 for the process of modifying the Page Display secondary page Vignette Portal Administrators Guide for information about using the Portal server and site consoles
96
Figure 38:
Using the Portal administration consoles, administrators choose which secondary page is used for each secondary page type. Portal administrators can also specify which grid is associated with a given secondary page type.
97
processing before the primary JSP is invoked. A common use of a predisplay action is to set up a FormBean object, which the JSP uses to render a form.
Process Actions are invoked on a process request. These actions do form
processing and any other type of processing where no rendering is involved. A process action finishes by redirecting the user to a display request. Figure 39 illustrates the role of pre-display actions, process actions, and the primary JSP.
Figure 39: Actions and JSP
Portal Site Presentation Framework Secondary Page Process Actions Pre-Display Actions
PROCESS request
end user
Primary JSP
Portal Site Presentation Framework Secondary Page Process Actions 1 2 Pre-Display Actions Primary JSP
DISPLAY request
end user
98
Actions are defined in the component descriptor (component.xml file) for each secondary page (type or instance). Actions are sequentially invoked in the order in which they appear in the descriptor file.
See also:
Secondary Page Deployment on page 136 for discussion of the component.xml file for secondary pages Technical Library on Vignette Connect (http://connect.vignette.com/) for API documentation of the secondary page types that ship with Portal (including javadocs of each action)
Action Reuse
Most of the Portal secondary page types contain all of the actions, both predisplay and processing. Each secondary page instance typically contains only JSPs; it inherits the actions from its secondary page type. Figure 40 shows how this concept applies to a display request. First the pre-display actions defined in the secondary page type are invoked, and then the primary JSP of the secondary page instance is invoked.
Figure 40: Action Reuse
Portal Site Presentation Framework Secondary Page Type Process Actions 1 Pre-Display Actions
DISPLAY request
end user
Secondary Page 2 Primary JSP
Action reuse allows the same functionality to be presented in different ways, by changing the secondary page instance without affecting the processing logic. Upon upgrade of Vignette Portal, the processing logic upgrades.
99
The secondary page instance can use actions defined by its secondary page type. Figure 41 shows a secondary page instance with two pre-display actions: a custom one and a reference to its secondary page types pre-display action. This reference is an example of direct reuse of an action.
Figure 41: Direct Reuse of Actions
Portal Site Presentation Framework Login Secondary Page Type Pre-Display Actions SetUpLoginFormAction
DISPLAY request
end user
1 2 3
Java Inheritance
Java inheritance enables a secondary page instance to create new action classes that extend ones defined by its secondary page type (see Figure 42). An instances action class invokes its parents behavior by calling super.execute():
100
public class MySetUpLoginFormAction extends SetUpLoginFormAction { public PortalURI execute( PortalContext portalContext ) throws Exception { . . . // custom logic here... . . . return super.execute(portalContext); } }
Figure 42:
Java Inheritance
Portal Site Presentation Framework Login Secondary Page Type Pre-Display Actions SetUpLoginFormAction
DISPLAY request
end user
1 2
extends
IMPORTANT: Modifying any of the actions that ship with Vignette Portal is not recommended unless there is no alternative for accomplishing a particular customization. If you do change the logic in any shipped actions, additional modifications might be required when you upgrade Vignette Portal.
101
The following roadmap summarizes the procedures involved in developing a new secondary page instance.
Procedure Determine what the current secondary page functionality is and how you need to change it. If your instance requires any display request processing that is different from that provided by its secondary page type, create one or more pre-display actions that define that processing. If your instance requires any custom processing of the process request, create one or more process actions. Create the primary JSP file for your instance. See Step 1: Plan Your Work (below) Step 2: Create Any PreDisplay Actions on page 103 Step 3: Create Any Process Actions on page 109 Step 4: Create the Primary JSP File on page 111
See also:
Chapter 7, Using the Site Development APIs, for additional component development topics such as AJAX enablement; request, response, and session objects; logging and error APIs; URI generation; and friendly IDs
102
See also:
Secondary Page Deployment on page 136 for more about component.xml and CAR files for secondary page types and instances Technical Library on Vignette Connect (http://connect.vignette.com/) for API documentation (javadocs) of each action class that ships with Portal Modifying the Look and Feel of an Existing Secondary Page on page 95 for information about duplicating a secondary page instance Vignette Portal Administrators Guide for information about using the administration consoles
A pre-display action can instantiate a custom JavaBean-like class and set it in the request. This JavaBean defines variables that can be retrieved by the secondary pages JSP. While a JavaBean class is optional, it reduces the amount of Java code required in the JSP. Here is an example of such a class:
public class PreDisplayLoginBean { private private private private boolean isForgottenPassAllowed boolean isSelfRegAllowed boolean allowFutureVisits List realmList = = = = true; true; true; null;
103
public void setIsForgottenPassAllowed(boolean b) { isForgottenPassAllowed = b; } public boolean getIsForgottenPassAllowed() { return isForgottenPassAllowed; } public void setIsSelfRegAllowed(boolean b) { isSelfRegAllowed = b; } public boolean getIsSelfRegAllowed() { return isSelfRegAllowed; } public void setAllowFutureVisits(boolean b) { allowFutureVisits = b; } public boolean getAllowFutureVisits() { return allowFutureVisits; } public void setRealmList(List l) { realmList = l; } public List getRealmList() { return realmList; } }
The Portal framework instantiates a number of JavaBeans for use by secondary pages. If you want to store your own variables to the request, do not extend a JavaBean of the Portal framework; instead, create your own JavaBean. In your custom pre-display action class, declare a string variable that the JSP can use to retrieve your JavaBean from the request:
public static final String DISPLAY_BEAN = "displayBean";
In the execute() method, instantiate your JavaBean and set it as a request attribute:
HttpServletRequest request = portalContext.getPortalRequest().getRequest(); PreDisplayMyBean bean = new PreDisplayMyBean(); request.setAttribute(DISPLAY_BEAN, bean);
Every action has an opportunity to return a URL within its execute() method. The URL is typically created or retrieved by calling a method on com.vignette.portal.website.enduser.PortalContext. For
104
example, if the current user is not authenticated, an action can redirect to the login page as follows:
User user = portalContext.getCurrentUser(); String logon = (String)user.getProperty(User.LOGON_PROPERTY _ID); PortalURI uri = portalContext.createDisplayURI(ParameterCon stants.PAGE_LOGIN); if (logon == null) { return uri; }
The Portal framework uses the PortalURI object to perform redirects on behalf of actions. Once a PortalURI is returned, no more actions for the secondary page instance are processed. In the login page example above, the URL resulting from the call to
PortalContext has a number of methods for returning PortalURI objects. createDisplayURI(ParameterConstants.PAGE_LOGIN) would be similar to this (where protocol is either http or https, as determined by the
As another example, portalContext.getPortalURI() returns the PortalURI for the current site:
protocol://domain/portal/site/mysite
In most cases, the URLs generated by Portal methods are relativefor example, /portal/site/mysite. The exception is if Portal is configured to be selectively secure and the target secondary page has a different secure setting than the current secondary page (that is, one is configured to be secure and the other is not). In that case, the generated URL is absolute.
See also: Chapter 1, Vignette Portal Web Site Overview, for discussion of Portal URL generation and secure settings
The BaseAction class has a concrete getErrorURI(String errorMessage, PortalContext portalContext) method, which uses the framework to redirect to an error
Redirecting to an Error Page.
105
// Get session and request from javax.servlet.http. HttpSession session = portalContext.getPortalRequest().getSession(); HttpServletRequest request = portalContext.getPortalRequest().getRequest(); // Get secondary page (which is a Style object). Style style = portalContext.getCurrentSecondaryPage(); String errorMessage = I18nUtils.getValue(style.getUID(), "no_site_msg", "Unable to retrieve current site from [CUSTOM_PRE_DISPLAY_ACTION]", session, request); return getErrorURI(errorMessage, portalContext); }
(Note that getCurrentSecondaryPage() returns a Style object. Secondary pages are instances of com.epicentric.template.Style.)
Redirecting Using the Response Object
The PortalContext provides intra-portal redirection capabilities only. However, a secondary page might need to redirect to a URL that is not in the local web application. For such circumstances, an action can perform a redirection itself, using the Java servlet API and returning a null PortalURI. For example:
try { portalContext.getPortalResponse().getResponse() .sendRedirect("http://www.vignette.com"); return null; //null PortalURI } catch (IOException ioe) { LOG.error(ioe); }
In this case, Portal detects the redirection, stops processing actions, and does not send any redirection itself.
Forwarding Rather than Redirecting within an Action
When an action returns a URL, by default the framework generates a redirect. However, the framework also supports forward calls, which result in a request being forwarded internally within Portal rather than a redirect being sent to the user. In most cases, the default redirect behavior is desired because it lets the client browser know the actual URL of the page being displayed (rather than leaving the client browser under the impression that it is viewing the page it initially invoked). As a result, end users can safely bookmark the URL.
106
However, you might want to use forwards for any of these reasons:
You can pass information to the next secondary page using request
attributes, which can carry large and complex objects. With redirects, you can pass information only by using query strings or by putting the information in the session.
Forwards are generally faster for the client because they avoid a second
round trip across the network. The performance improvement on a 100 Mbps intranet isnt significant, but it can make a big difference if the end user is connected by cell phone or other mobile device.
Each request creates many objects. A forward eliminates one request and
thus eliminates the overhead of creating that requests objects. URLs are forwarded by calling setForward() on the PortalURI object:
PortalURI uri = PortalContext.createDisplayURI("FRONT_ PAGE"); uri.setForward(true);
An action can return null if no redirection is necessary. If no pre-display action returns a URL or when all pre-display actions for a secondary page have been executed, the secondary pages primary JSP is invoked.
Passing Request Attributes to a Portlet
The Portal can share information with a Java standard portlet by setting a request attribute in a pre-display action. The call to the setAttribute() method must be namespaced as follows (where request is the PortalRequest object and portlet-name is the value of the <portletname> element in the portlet.xml file):
request.setAttribute("com.vignette.portal.attribute.portlet.por tlet-name.attributeName", attributeValue);
A portlet that is executed during the same request can access the request attribute as follows (where request is the PortletRequest object):
request.getAttribute("com.vignette.portal.attribute.portlet.por tlet-name.attributeName");
107
The default content type is "text/html". You can override this default in a pre-display action by calling setContentType() on the HttpServletResponse object. For example, if your secondary page needs to support mobile devices, you can set the content type to Wireless Markup Language:
response.setContentType("text/wml");
Since the content type cannot be modified after the response has been written, be sure that your call precedes the writing of the response.
Pre-Display Action Example
The following action demonstrates some common calls in a pre-display action. (Like all code examples in this book, this sample class is not designed to be executed.)
import com.vignette.portal.website.enduser.PortalURI; import com.vignette.portal.website.enduser.PortalContext; import com.vignette.portal.website.enduser.components.ActionEx ception; import com.vignette.portal.website.enduser.components.BaseAc tion; import com.epicentric.common.website.RealmUtils; import javax.servlet.http.HttpSession; import javax.servlet.http.HttpServletRequest; import java.util.List; public class PreDisplaySampleAction extends BaseAction { // key used to store the JavaBean in the request public static final String DISPLAY_BEAN = "displayBean"; // main method public PortalURI execute( PortalContext portalContext ) throws ActionException { // Get request and session objects. HttpServletRequest request = portalContext.getPortalRequest().getRequest(); HttpSession session = request.getSession(); // Get list of authentication realms for this user. List realms = RealmUtils.getLoginRealms(); if (realms == null || realms.size() == 0) {
108
// Use LOG object to log errors or messages. // LOG variable is defined in BaseAction. LOG.error("No realm supports new password request."); String sDiagnostic = I18nUtils.getValue(portalContext .getCurrentSecondaryPage().getUID(), "realmpasswddiag", "No Realm supports new password request.", session, request); // Use getErrorURI() to ask framework to redirect // to an error page. return getErrorURI(sDiagnostic, portalContext); } // Instantiate custom JavaBean to pass to primary JSP. PreDisplaySampleBean bean = new PreDisplaySampleBean(); bean.setRealmList(realms); // Set bean as request attribute. request.setAttribute(DISPLAY_BEAN, bean); /* Returning null means framework can proceed with execution of next pre-display action or (if none) primary JSP. */ return null; } }
and can return a null URL. On a process request, if no action returns a URL, the framework redirects the user to the display for the secondary page doing the processing. IMPORTANT: Do not extend any of the Vignette Portal actions. These actions are subject to change in future releases of the product.
See also: Automating the Validation and Population of HTML Forms on page 121 for information about creating and using validation rules within a process action
109
Often, a process action needs to pass data to a displayfor example, to send an error or status message back to the secondary page for display. You can set the message on the session and use getCurrentPageURI() to return to the display page. For example, the process action for the My Account page can send a confirmation message to the display as follows:
String confirmation = I18nUtils.getValue(style.getUID(), "save_success", "Your account changes have been saved.", session, request); ErrorMessage confMssg = new ErrorMessage(ErrorMessage.CONFIRMATION, confirmation); SessionUtils.setNamespacedAttribute(session, ParameterConstants.ERROR_MESSAGE, null, confMssg); return portalContext.getCurrentPageURI(ParameterCon stants.PAGE_MY_ACCOUNT);
(Note that I18nUtils, ErrorMessage, SessionUtils, and ParameterConstants are classes in com.epicentric.common.website.)
Process Action Example
The following code demonstrates some of the calls that are commonly included in a process action:
import com.vignette.portal.website.enduser.components .BaseAction; import com.vignette.portal.website.enduser.components. ActionException; import com.vignette.portal.website.enduser.PortalURI; import com.vignette.portal.website.enduser.PortalContext; import com.vignette.portal.util.StringUtils; import com.epicentric.common.website.*; import javax.servlet.http.HttpSession; import javax.servlet.http.HttpServletRequest; public class ProcessSampleAction extends BaseAction { // main method public PortalURI execute( PortalContext portalContext ) throws ActionException { // Get request and session objects. HttpServletRequest request = portalContext.getPortalRequest().getRequest(); HttpSession session = portalContext.getPortalRequest().getSession();
110
// Get page requesting user account verification. SessionInfo sessionInfo = (SessionInfo) session.get Attribute(SessionInfo.SESSION_INFO_NAME); String requestingPage = sessionInfo.getPageRequestingVerification(); // Get current users logon. User user = portalContext.getCurrentUser(); String logon = (String) user.getProperty(User.LOGON_PROPERTY_ID); if (logon == null) { // Use createDisplayURI() to ask framework to redirect // to login page. return portalContext.createDisplayURI(ParameterCon stants.PAGE_LOGIN); } // Get and validate password. String password = RequestUtils.getParameter(request, "password"); if (StringUtils.isEmpty(password)) { ErrorMessage errorMsg = new ErrorMessage(ErrorMessage.USER_ERROR, I18nUtils.getValue(portalContext.getCurrentSeconda ryPage().getUID(), "empty_password", "You must enter a valid password.", session, request)); // Set error message in session. SessionUtils.setNamespacedAttribute(session, ParameterConstants.ERROR_MESSAGE, null, errorMsg); // Return to same page. return portalContext.getCurrentPageURI(ParameterCon stants.PAGE_ACCOUNT_VERIFY); } // Otherwise, processing successful--ask framework to // redirect to requested page. return portalContext.createDisplayURI(requestingPage); } }
111
If a secondary page instance needs to display more than one HTML page, the primary JSP file can act as the controller for other JSPs by including them under specified conditions.
Using the JavaBean
The <jsp:useBean/> tag enables you to use the JavaBean that was instantiated in the secondary pages pre-display action. For example:
<jsp:useBean id="displayBean" scope="request" type="com.companyname.portal.mycomponents .login.CustomLoginBean" />
You can then access any of the variables stored on the JavaBean from the JSP:
displayBean.getIsSelfRegAllowed() See also: Developing a Secondary Page Instance on page 101 for discussion of JavaBeans and pre-display actions
A secondary page instance is a com.epicentric.template.Style object. You can retrieve the unique identifier to this object as follows:
<% String i18nID = portalContext.getCurrentSecondaryPage().getUID(); %>
The JSP uses this unique identifier to retrieve localized values for the secondary page. For example, you can display the title of the secondary page like this:
<% EndUserUtils.displayTitleOfPageContent(pageContext, I18nUtils.getValue(i18nID, "display_title", "Account Verification", session, request), 1, true); %>
112
If your secondary page instance has any process actions, the JSP needs to generate a process request. In the most common case, an HTML form creates the process URL in its action attributefor example:
<form action="<%= portalContext.createTemplateProcessURI() %>">
The createTemplateProcessURI() method creates an encoded URL that points to the first (or only) process action for the current secondary page instance. The forms submit button posts to this URL. Rather than generating a process request for the current secondary page, the
createProcessURI(String friendlyID) method enables you to pass
The following example demonstrates the basics of a primary JSP file that includes a simple HTML form.
<%-- Import utility class. --%> <%@ page import="com.epicentric.common.website.I18nUtils"%> <%-- Declare custom Vignette tag library. --%> <%@ taglib uri="vgn-tags" prefix="vgn-portal" %> <%-- Import implicit objects (LOG and portalContext). --%> <vgn-portal:defineObjects/> <%-- Import JavaBean set in request by pre-display action. --%> <jsp:useBean id="displayBean" scope="request" type="mycomponents.component.DisplayBean" /> <%-- Get ID of secondary page instance. --%> <% String i18nID = portalContext.getCurrentSecondaryPage() .getUID(); %> <%-Create form. Process URL is for current secondary page type. --%> <form action="<%= portalContext.createTemplateProcessURI() %>" name="epi_form" style="display: inline; margin: 0px"> <table border="0" cellpadding="0" cellspacing="0"> <tr><td>
113
<%-- Display secondary page title. --%> <% EndUserUtils.displayTitleOfPageContent(pageContext, I18nUtils.getValue(i18nID, "display_title", "Sample Secondary Page", session, request), 1, true); %> </td></tr> <%-- Display value from bean. --%> <tr><td valign="top" width="100%"> <% displayBean.getSampleName(); %> </td></tr> <%-- Display form field. --%> <tr><td> <input class="epi-input" type="password" size="13" style="width: 150px" value="" name="password" id="password" /> </td></tr> </table> <hr size="1" noshade="noshade" /> <table border="0" cellspacing="0" cellpadding="0"> <tr> <%-- Evaluate form button labels. --%> <% String submitLabel = I18nUtils.getValue(i18nID, "submitlabel", " Verify Password ", session, request); String cancelLabel = I18nUtils.getValue(i18nID, "cancel", "Cancel", session, request); %> <td width="100%" nowrap="nowrap" style="padding-right: .5em"> <%-- Display form buttons. Submit posts to URI created above by calling createTemplateProcessURI(). --%> <input type="submit" align="left" name="verifypassword" id="verifypassword" value="<%=submitLabel%>" class="epi-button" /> <%-- Cancel button returns to current page. --%> <input onClick="history.go(-1);" type="button" name="cancel" id="cancel" value="<%=cancelLabel%>" class="epi-button" /> </td></tr> </table> </form> See also: Automating the Validation and Population of HTML Forms on page 121 for an explanation of validating HTML forms
114
each instance need only consist of the primary JSP file and any custom images it uses. IMPORTANT: Do not replace any of the Vignette Portal secondary page types with your own types; for example, do not attempt to develop your own login secondary page type and use it in lieu of the Portal login secondary page type. Rather, create your own instance of a Portal secondary page type.
115
Figure 43:
The Portlet Placement page (Figure 44) enables Portal administrators to specify the position of individual portlets within the panels defined in the Layout page as well as to determine the degree of control that end users have over the page. For example, some or all portlets can be included as defaults that end users are free to override; individual portlets or all portlets in a panel can be locked so that end users cannot remove them; or the entire page can be locked so that end users can neither add nor remove portlets.
Figure 44: Portlet Placement Page, Portal Administration Consoles
116
If you want to control portlet layout and placement to a finer degree of granularity than that supported by the administrative UI, you can create a custom instance of the Page Display secondary page type. This section describes the out-of-the-box Page Display secondary pages and explains how to customize them.
117
Figure 45:
displaypage.jsp
DHTML?
Include displaypage_dhtml.inc
N Include displaypage_static.inc
Column Y Orientation?
Chromeless Portlet?
Include chromeless_portlet.inc
118
DHTML Page Display Files Description Primary JSP; contains the following code:
displaypage.jsp
page import and taglib directives <vgn-portal:defineObjects/> tag, defining the LOG and portalContext implicit variables two <jsp:useBean/> tagspageBean and portletWindowBeansmade available in the Page Display actions global variable declarations inclusion of displaypage_dhtml.inc if the browser supports DHTML, or displaypage_static.inc otherwise
displaypage_dhtml. Sets up JavaScript and CSS, includes the page controls style, inc then includes displaypage_dhtml_module_layout_inc. displaypage_dhtml_ Contains the bulk of the HTML, CSS, JavaScript, and Java module_layout_inc logic. For each portlet, includes display_portlet.inc. display_portlet .inc Checks whether the current portlet is chromeless. If so, calls chromeless_portlet.inc; if not, includes the chrome style (which contains the portlet-rendering tags).
chromeless_portlet Contains the portlet-rendering tags for displaying portlet .inc content within a chromeless portlet. displaypage_static Includes the page controls style, then checks the pages .inc orientation; calls either displaypage_static_column_oriented.inc or displaypage_static_row_oriented.inc. displaypage_static Sets up a column-oriented page, including _column_oriented displaypage_static_common.inc for each panel of .inc portlets. displaypage_static Sets up a row-oriented page, including _row_oriented.inc displaypage_static_common.inc for each panel of portlets. displaypage_static Loops through each portlet, including _common.inc display_portlet.inc for each.
The non-DHTML Page Display secondary page shares all of the displaypage_static*.inc files with the DHTML version but has a separate displaypage.jsp (primary) file, which contains the same logic as
119
the DHTML primary file except that it skips the browser check and instead always includes displaypage_static.inc.
See also: Chapter 2, Controlling Navigation and Appearance with Styles, for details about chrome, page control, and other style types
The classes in the com.epicentric.page.website package are of particular note for customizing portlet layout. In addition, you can use the <vgn-portal:renderPortlet> tag with the portletFriendlyID attribute if you want to include specific portlets in your custom layouts.
See also:
Chapter 7, Using the Site Development APIs, for a discussion of the ways that portlets can be included in a page Technical Library on Vignette Connect (http://connect.vignette.com/) for API documentation of the com.epicentric.page.website package
Customization Process
Vignette recommends that you use the following methodology when creating custom page layouts.
To customize the Page Display secondary pages: 1 2 3 4
Use a Portal administration console to duplicate either the DHTML Page Display or the Page Display secondary page that ships with Portal. Download the duplicates support files to your file system. For each custom layout that you require, create a JSP include (.inc) file that contains the rendering logic for that layout. Modify the duplicated primary JSP to add logic for including each of your custom layout files or the out-of-the-box JSP file as appropriate.
120
For example, if you created custom layouts for a national news page and an international news page, you would add logic to the primary JSP similar to the following statements shown in bold:
<% String pageTitle = pageBean.getPageTitle(); if "nationalnews".equals(pageTitle)) { %> <!- include layout for nationalnews page --> <%@ include file="nationalnews.inc" %> <% } else if "internationalnews".equals(pageTitle)) { %> <!- include layout for internationalnews page --> <%@ include file="internationalnews.inc" %> <% // rest is existing code in DHTML Page Display } else if (HtmlUtils.browserSupportsDHTML(request)) { <%@ include file="displaypage_dhtml.inc" %> <% } else { <%@ include file="displaypage_static.inc" %> <% } %> 5
Using the administration console, upload your modified primary file, custom JSP include files, images, and any other files as the new support files for the secondary page that you duplicated. Assign your custom secondary page to the Page Display secondary page type, using either Site Settings >> Appearance >> Secondary Pages on a site console or Server Settings >> Server Defaults >> Site & Appearance >> Default Secondary Pages on the server console.
See also:
Modifying the Look and Feel of an Existing Secondary Page on page 95 for more about duplicating a secondary page Deploying a Secondary Page Instance on page 137 for deployment details
121
The Vignette Portal validation framework separates the business rules used for form validation from the technical implementation of the validation. The framework provides a set of predefined validation rules for the most common validation cases used on web sites. You can use these predefined rules, thereby avoiding code duplication. In addition, you can modify the validation rules separately, without having to modify the validation code. The following roadmap summarizes the procedures involved in using the Portal validation framework.
Procedure Create a JavaBean-like class called a FormBean to validate and populate an HTML form. Create an XML file that defines the validation rules; optionally create custom validation rules. Instantiate and use the FormBean in the primary JSP file. Create a process action that uses the validation rules. See Step 1: Develop a FormBean (below)
Step 2: Set up the Validation Rules on page 125 Step 3: Add Validation Code to the Primary JSP on page 135 Step 4: Develop the Action Processing on page 135
The getFormName() method returns the name of the form that this FormBean validates. The return value must match the name specified in validation.xml (the file that provides the validation rules for this FormBean), but the value does not need to match the form name specified in the primary JSP file.
122
getPotentialErrors() Method
For each validation rule on each form field, the getPotentialErrors() method loads a map of validation rule/form field pairs. When a validation rule fails, it looks up the error message for the field being checked and adds that message to the list of errors that the form has generated. The map that this method returns must have a value for each rule that is run on each field specified in the validation.xml file for this FormBean. All keys should be of the form fieldProperty::ruleName, where fieldProperty is the property of the field and ruleName is the name of the validation rule. The map values should be arrays of type com.epicentric.i18n.format.Formattable.
See also: Chapter 6, Internationalizing and Localizing Site Components, for details about the Formattable class
FormBean Example
The following example of a FormBean gets its form name from a field on its process action and defines three potential errorstwo that use Portal-defined validation rules and one that uses a custom rule:
package com.companyname.portal.mycomponents; import com.vignette.portal.website.enduser.utils.I18nHelper; import com.vignette.portal.website.enduser.components.EndUser FormBean; import com.epicentric.i18n.format.Formattable; import java.util.Map; import java.util.HashMap; public class SampleFormBean extends EndUserFormBean { private private private private static final long serialVersionUID = 1L; String _pageName = ""; boolean _reachMax = false; String[] _errMsgs = null;
public boolean isReachMax() { return _reachMax; } public void setReachMax(boolean reachMax) { this._reachMax = reachMax; }
123
public String[] getErrorMsgs() { return _errMsgs; } public void setErrorMsgs(String[] errMsgs) { this._errMsgs = errMsgs; } public String getPageName() { return _pageName; } public void setPageName(String pageName) { _pageName = pageName; } /* * Returns the name of the form this FormBean validates. * The name must match the value specified in validation.xml */ public String getFormName() { return ProcessSampleValidationAction.FORM_KEY; }
/* * Defines the error messages for this FormBean, using * I18NHelper to localize the messages. */ protected Map getPotentialErrors() { // standard Portal validation rule Formattable[] message_title_required = { I18nHelper.getFormattable(super.getBundleId(), "_global.message_title_required_1", "The name you entered was invalid.", null), I18nHelper.getFormattable(super.getBundleId(), "_global.message_title_required_2", "Names must contain at least one non-whitespace character.", null) }; // standard Portal validation rule Formattable[] message_title_maxlength = { I18nHelper.getFormattable(super.getBundleId(), "_global.message_title_maxlength_1", "Sample name was too long.", null), I18nHelper.getFormattable(super.getBundleId(), "_global.message_title_maxlength_2",
124
"Names cannot be more than 32 characters in length.", null) }; // custom validation rule Formattable[] message_title_unwantedchars = { I18nHelper.getFormattable(super.getBundleId(), "InvalidCharacterErr", "The value you entered for the name is invalid.", null), I18nHelper.getFormattable(super.getBundleId(), "InvalidCharacterInstruct", "Names may contain any characters except the following: < > \ \"", null) }; Map potentialErrors = new HashMap(); potentialErrors.put("pageName::required", message_title_required); potentialErrors.put("pageName::maxlength", message_title_maxlength); potentialErrors.put("pageName::unwantedchars", message_title_unwantedchars); return potentialErrors; } }
To define the validation required by a form, you need to create a file named validation.xml. This file has the following basic structure:
<form-validation> <global> <validator ... /> <validator ... /> </global>
125
<formset> <constant ... /> <constant ... /> <form ... /> <form ... /> </formset> </form-validation>
An example of this file is available in VignettePortalInstallDir/samples/form/validation.sample. A validation.xml file must have at least one <form> element. The <global>, <validator/>, and <constant> elements are optional. A <formset> element encloses <form> and <constant> elements, both of which have child elements. For example, the following validation.xml file provides validation of two fields on one form:
<form-validation> <formset> <form name="registrationForm"> <field property="streetAddr" depends="minlength"> <var> <var-name>min</var-name> <var-value>5</var-value> </var> <field property="postalCode" depends="requiredif,mask"> <var> <var-name>mask</var-name> <var-value>${zip}</var-value> </var> </field> </form> </formset> </form-validation> <form> Element.
This required element defines the validation rules for a particular form. A <form> element contains one or more <field> elements, which correspond to input tags on a JSP page. A <field> element has two attributes. The value of the property attribute is the string identifying the field. The depends attribute is where you specify a comma-separated list of validation rules to run on this field.
The <field> element has a child element named <var>. Each <var> element is a variable that is made accessible to the validation rules that operate on its field. A <var> element contains two required child elements: <var-name> and <var-value>. The value of <var-name> identifies a validation rule and must be all lower case.
126
<constant> Element.
This element provides you with a single place to specify values used multiple times in the rest of validation.xml. You may specify zero or more constants. Each <constant> element should contain exactly one <constant-name> element and one <constant-value> element. You may use the constants name to substitute the constants value anywhere else within the <formset> element. The value of a constant is a regular expression in Perl. For example:
<constant> <constant-name>zip</constant-name> <constant-value>^\d{5}(-\d{4})?$</constant-value> </constant>
In this example, the value of zip would be referred to in a field in the formset by making a Perl-style variable reference, ${zip}. The validation.xml file may include zero or more <validator/> elements. Each <validator/> element defines a custom validation rule (described a little later in this chapter). A <validator/>
<validator/> Element.
element has no body text and no child elements. If you have one or more
<validator/> elements, they must be child elements of the <global> element; if you do not have any <validator/> elements, there is no need to include a <global> element in your XML file. Here is an example of a <validator/> element:
<global> <validator name="uniquecategory" classname="com.companyname.portal.mycomponents .SampleValidationRules" method="validateUniqueCategoryName" methodParams= "com.vignette.portal.website.form.FormBean, org.apache.commons.validator.Field, org.apache.commons.validator.ValidatorAction, java.util.List, java.util.Map" depends="required" /> </global>
The <validator/> element has four required attributes and one optional attribute:
nameRequired. String identifying this validation rule. Names are case-
sensitive and must be unique from all rules in use. In other words, make sure that you do not name any of your validation rules the same as any of
127
the Portal standard validation rules. (You can, however, use the same name for validation rules that you create in separate components.)
classnameRequired. Fully qualified name of the Java class containing
validation.
methodParamsRequired. Fully qualified, comma-separated classnames
in the methods signature. These classnames must be listed in the same order as they are listed in the methods signature.
dependsOptional. Comma-separated names of any other validation
rules that must be run before this one can be executed. Be sure not to create any circular dependencies with this attribute.
Using Standard Validation Rules
The Portal validation framework includes all of the validation rules listed in Table 13. The rule names are all lower case (by Vignette Portal convention), and the var-name values must be all lower case (as dictated by Struts).
Table 13: Rule intrange Validation Rules Provided with the Portal Validation Framework var-name min var-value Minimum acceptable int value Maximum acceptable int value Minimum acceptable float value Maximum acceptable float value Minimum acceptable double value Description Specifies the minimum value when testing whether the field is within a particular integer range. Specifies the maximum value when testing whether the field is within a particular integer range. Specifies the minimum value when testing whether the field is within a particular floating-point range. Specifies the maximum value when testing whether the field is within a particular floating-point range. Specifies the minimum value when testing whether the field is within a particular double range.
max
floatrange
min
max
doublerange min
128
Validation Rules Provided with the Portal Validation Framework (Continued) var-name max var-value Maximum acceptable double value Maximum acceptable length Minimum acceptable length n/a Name of the field to be tested Description Specifies the maximum value when testing whether the field is within a particular double range. Checks if the fields length is less than or equal to a maximum value. Checks if the fields length is greater than or equal to a minimum value. Checks if the field contains at least one non-white-space character. Specifies the field to be tested; the type of test is specified by other variables. Can be used one or more times.
max min n/a field[i] (where i is a zero-based index) field-test[i] (where i is a zerobased index)
null | notnull | Performs the specified type of test; used in equal | notequal conjunction with field[i]. Can be used one or more times. Performs an equality test for fieldtest[i]; applies when var-value is equal or notequal. Defines the logical operator to be used if testing more than one field. Checks if the field can safely be converted to a byte primitive. Checks if the field can safely be converted to a short primitive. Checks if the field can safely be converted to an int primitive. Checks if the field can safely be converted to a long primitive. Checks if the field can safely be converted to a float primitive. Checks if the field can safely be converted to a double primitive.
field-value[i] Value that field(where i is a zerotest[i] is to be based index) compared to field-join byte short integer long float double n/a n/a n/a n/a n/a n/a and | or n/a n/a n/a n/a n/a n/a
129
Validation Rules Provided with the Portal Validation Framework (Continued) var-name n/a date-pattern var-value n/a Lenient date pattern to which the date must conform Description Checks if the field is a valid credit card number Checks if the field is a valid date and conforms to the lenient date pattern (i.e., the parser may use heuristics to interpret inputs that do not precisely match the date pattern). Requires that java.util.Locale be provided as an additional resource. If neither datepattern nor date-patternstrict is supplied, the pattern specified by the locale is used. Checks if the field is a valid date and conforms to the strict date pattern (i.e., inputs must match the date pattern exactly). Requires that java.util.Locale be provided as an additional resource. If neither datepattern-strict nor datepattern is supplied, the pattern specified by the locale is used. Checks if the field is a valid email address Checks if the field matches the specified regular expression.
creditcard date
date-patternstrict
email mask
n/a mask
For example, this field is required, must be convertible to an int, and must have a value between 1 and 256 (inclusive):
<field property="maxSize" depends="required,integer,intrange"> <var> <var-name>min</var-name> <var-value>1</var-value> </var> <var> <var-name>max</var-name> <var-value>256</var-value> </var> </field>
The following example shows two fields that use date validation:
130
<field property="scheduleEndDate" depends="date"> </field> <field property="scheduleEndTime" depends="date"> <var> <var-name>date-pattern</var-name> <var-value>hh:mm a</var-value> </var> </field>
The first field validates against the pattern specified by the locale, and the second field uses lenient validation against the specified pattern. In the next example, a color text field is required if the selectedOption field has a value of either bgcolor or font_color; and the value of color must be six characters in the range of 0 to 9, a to f, and A to F:
<field property="color" depends="requiredif,mask"> <var> <var-name>field[0]</var-name> <var-value>selectedOption</var-value> </var> <var> <var-name>field-test[0]</var-name> <var-value>EQUAL</var-value> </var> <var> <var-name>field-value[0]</var-name> <var-value>bgcolor</var-value> </var> <var> <var-name>field[1]</var-name> <var-value>selectedOption</var-value> </var> <var> <var-name>field-test[1]</var-name> <var-value>EQUAL</var-value> </var> <var> <var-name>field-value[1]</var-name> <var-value>font_color</var-value> </var> <var> <var-name>field-join</var-name> <var-value>OR</var-value> </var> <var> <var-name>mask</var-name> <var-value>[0-9a-fA-F]{6}</var-value> </var> </field>
131
You can extend the validation framework by creating custom validation rules. To do so, you simply create a validation method within your process action class and add a <validator/> element to validation.xml that points to that method. Here is an example of a validation method:
/** * Ensures that the field does not contain any single or double * quotes or any less-than or greater-than symbols. * * @param bean The FormBean on which validation is being * performed * @param field The field that is being validated * @param action An encapsulation of all the information * contained in the validation.xml file about this particular * validation rule * @param currentErrors All errors that have been generated by * validation so far * @param potentialErrors A map of all errors that might be * generated while validating the current form * @return <code>true</code> if the field does not contain * any of these characters: " < > */ public static boolean validateUnwantedChars(FormBean bean, Field field, ValidatorAction action, List currentErrors, Map potentialErrors) { String value = ValidatorUtil.getValueAsString(bean, field.getProperty()); if (value.indexOf("\") != -1 || value.indexOf("\"") != -1 || value.indexOf("<") != -1 || value.indexOf(">") != -1) { // invalid characters found ValidationTestSuite.putErrorInList(action, field, currentErrors, potentialErrors); return false; } else {// no invalid characters found return true; } }
fails. The reference to this method within validation.xml might look like this:
132
<global> <validator name="unwantedchars" classname="com.companyname.portal.mycomponents .ProcessSampleValidationAction" method="validateUnwantedChars" methodParams="com.vignette.portal.website.form.FormBean, org.apache.commons.validator.Field, org.apache.commons.validator.ValidatorAction, java.util.List, java.util.Map" /> </global>
The validation.xml file can use this method by referring to the validator name within a <form> elementfor example:
<form name="add_form"> <field property="pageName" depends="required,maxlength,unwantedchars"> <var> <var-name>max</var-name> <var-value>32</var-value> </var> </field> </form> Default Validation Resources.
five parameters. These parameters correspond to objects that are available to all validation rules. A sixth object (org.apache.commons.validator.Validator) is also available to all validation rules. Here is a description of each of these default resources:
com.vignette.portal.website.form.FormBeanthe FormBean associated with the form that is currently being validated (the FormBean on which validate() is being called) org.apache.commons.validator.Fieldan object representing the field on the form that is being validated, derived from validation.xml org.apache.commons.validator.Validatorthe validator object
that is responsible for retrieving the properties from the bean and figuring out which methods to call to perform the validation
org.apache.commons.validator.ValidatorActionan object representing the criteria being tested, derived from validation.xml
133
validation so far
java.util.Mapa map linking all fields and validation rules to
appropriate error messages (the values stored in this map are what get placed in the java.util.List above if the current validation fails)
Additional Validation Resources.
If the validation method that you create requires any parameters other than the ones listed above, your process action needs to pass those parameters into the method as a map (as shown in Step 4: Develop the Action Processing on page 135). Additional resources specified in this map are added to the default resources available to the validator. Each map key must be a string that is the qualified classname of the object with which it is associated. The value may be an instance of the class, an instance of a subclass of the class, or an implementation of the interface. The Portal validation framework pulls objects out of the default and additional resources maps and passes them as parameters to the validation rules. Parameters have the following restrictions:
The keys in the additional resources map must be the exact same
classnames as the parameters in the validation rules. In other words, if the parameter of a validation method is a java.util.Collection, the key in additionalResources must be "java.util.Collection"it cannot be "java.util.Set" even though java.util.Set is a subclass of java.util.Collection.
Your custom validation method may not have two parameters that are of the
same class. The default parameters have specific values, so you may not create a method that uses these variables for anything other than their original purpose. In other words, none of your custom validation rules can take a java.util.Map that holds anything other than the potential validation errors. The map that is available to validation rules holds those errors, and only one java.util.Map can be available to validation rules. You may, however, use a java.util.HashMap as a parameter, but if you do so be sure that both the method signature and the additionalResources map refer to a java.util.HashMap, not a java.util.Map. You can also supply your custom validation rule with data by specifying a variable. Variables allow you to write more generic validation rules because specific information can be supplied on a per-field basis. Once you have specified a variable, you can access it using the getVarValue(var-name) method on the field
Field Variables.
134
(org.apache.commons.validator.Field object). This method returns the String that was supplied as the body content of the <var-value> element in your validation.xml file.
The JSP can then use the FormBean as shown in bold face:
<form action="<%= portalContext.createTemplateProcessURI() %>" name="add_form" method="post"> <%-- The value attribute should be obtained from the FormBean, so that the FormBean can repopulate the fields upon validation failure. --%> <input type="text" name="pageName" class="epi-input" size="25" id="name" value="<%= add_form.getPageName() %>" /> </form>
In your process actions execute() method, call the validate() method of the com.vignette.portal.website.enduser .components.Validator class. The validate() method ensures that the value of each of the FormBeans properties conforms to your validation rules. It returns TRUE or FALSE based on whether the submitted information is valid. The validate() method takes as parameters the requests PortalContext object and a key used to find the FormBean object associated with the specific secondary page form in the session. If your action uses custom validation requiring additional resources, use the three-parameter
135
signature of this method and specify the additional resources map as the third parameter. The following example is for an action that includes custom validation that requires additional resources.
public class ProcessSampleValidationAction extends BaseAction { // Key to be used to refer to the FormBean stored in session protected static final String FORM_KEY = "sample_form"; public PortalURI execute( PortalContext portalContext ) throws ActionException { /* Load map of additional resources. */ Map additionalResources = new HashMap(); additionalResources.put("com.companyname.portal. mycomponents.MyParam", param1); additionalResources.put("com.companyname.portal. mycomponents.MyOtherParam", param2); /* *[...] */ if(!(new Validator()).validate(portalContext, FORM_KEY, additionalResources)){ /* If validation fails, return to the primary JSP for this * secondary page */ return portalContext.getCurrentPageURI(SampleValida tionConstants.SAMPLE_PAGE); } /* Otherwise, proceed with the processing logic... * [...] */ }
Your process action is responsible for redirecting to the initial primary view when the form information is invalid. After calling validate() you can check the FormBean for errors, which you can retrieve from the FormBean and use to create an error message for display. If there are no errors, you may wish to create a confirmation message for display.
136
page instance and then describes how the deployment process is different for secondary page types.
existing secondary page. You can use the export mechanism as an alternative to creating these files from scratch. However, you should carefully check the resulting files against the information in this section (and in Automating the Validation and Population of HTML Forms on page 121 for validation.xml) and modify them as appropriate before using them to deploy a new secondary page instance. In particular, ensure that the CAR file includes any action classes you developed for this secondary page instance, and that the component.xml file refers to those action classes.
See also: Chapter 8, Deploying Site Components, for more about the deployment system, component descriptors, and component archives
Component Descriptor
A component.xml file describes a secondary page instance, or any other component, to Vignette Portal. All components share many common component.xml elements. This section discusses the elements and the attribute values that are unique to secondary page instances. The component.xml file for a secondary page instance has the following syntax (with the items discussed in this section shown in bold type):
<epideploy:component component-id="string" component-type="Secondary Pages"
137
major-version="integer" minor-version="integer" build-version="string" epi-version="string" epi-build="integer" title="string" description="string" xmlns:epideploy="http://www.epicentric.com/deployment"> <epideploy:required-component component-id="string" component-type="Secondary Page Types" major-version="integer" minor-version="integer" /> <epideploy:detail> <style-info id="string" friendly-id="string" title="string" description="string" primary-filename="string" template-uid="string" template-default="true"|"false" is-system="false" processing-type="action_based" > <actions> <group-reference group-id="INHERIT_ALL"|"string" /> <action id="string" type="PRE_DISPLAY"|"PROCESS"> <class>fully_qualified_package.ClassName</class> </action> ...any number of <action> elements... </actions> </style-info> </epideploy:detail> </epideploy:component> component-type. The component-type for a secondary page is the literal string value "Secondary Pages"; the component-type for its required component is the literal string value "Secondary Page Types". processing-type.
The value of the processing-type for a secondary page is the literal string "action_based".
138
The optional <actions> element lists any action classes for the secondary page instance. Each action class is a separate <action> child element of the <actions> element. The type action attribute is a literal string: either "PRE_DISPLAY" or "PROCESS". The actions are executed in the order in which they are listed. If your secondary page instance does not include any actions of its own and you want the actions defined on its secondary page type to be executed, do not include the <actions> element; if, instead, you dont want any actions executed for your secondary page instance, include an empty <actions> element:
actions. <actions> </actions>
If you want to execute a group of actions that are defined on the secondary page type, include a <group-reference> element as a child element of <actions>, and use the group ID from the secondary page types component.xml as its group-id attribute value. If you want all of the actions of the secondary page type executed, use the literal string "INHERIT_ALL" as the value of the group-id attribute. Each action identified by the <group-reference> element will be executed at the point where this element appears within the actions list; then execution will continue with the next action (or action group) in the actions list. (See Defining a Group of Actions on page 144 for discussion of action groups in secondary page types.)
action groups. Example 1. Typically, a secondary page instance simply uses the actions of its secondary page type. The following component.xmlfile supports such a case. Notice that it has no <actions> element but has a processing-type of "action_based"; as a result, it inherits the actions of its secondary page type (whose ID is template0014). <?xml version="1.0" encoding="UTF-8"?> <epideploy:component component-id="t0014style0001" component-type="Secondary Pages" major-version="7" minor-version="0" build-version="76" epi-version="7.0" epi-build="1" title="Log In" description="Default for user login" xmlns:epideploy="http://www.epicentric.com/deployment"> <epideploy:required-component component-id="template0014"
139
component-type="Secondary Page Types" major-version="7" minor-version="0"/> <epideploy:detail> <style-info id="t0014style0001" friendly-id="login" title="Log In" description="Default for user login" primary-filename="login.jsp" template-uid="template0014" template-default="true" is-system="true" visible="true" processing-type="action_based"/> </epideploy:detail> </epideploy:component> Example 2.
In the following example of a component.xml file, the secondary page instance is of type template0012. It inherits all of the actions of its type, and it has one process action of its own, which executes last.
<?xml version="1.0" encoding="UTF-8"?> <epideploy:component component-id="t0012style0005" component-type="Secondary Pages" major-version="7" minor-version="0" build-version="76" epi-version="7.0" epi-build="1" title="Sample Secondary Page" description="Secondary page example to demonstrate component.xml values only" xmlns:epideploy="http://www.epicentric.com/deployment"> <epideploy:required-component component-id="template0012" component-type="Secondary Page Types" major-version="7" minor-version="0"/> <epideploy:detail> <style-info id="t0012style0005" friendly-id="SAMPLE_SECONDARY_PAGE"
140
title="Sample Secondary Page" description="Secondary page example to demonstrate component.xml values only" primary-filename="sample_secondary_page.jsp" template-uid="template0045" template-default="true" is-system="false" visible="true" processing-type="action_based"> <actions> <group-reference group-id="INHERIT_ALL"/> <action id="1" type="PROCESS"> <class>com.companyname.portal.mycomponents .ProcessSampleAction</class> </action> </actions> </style-info> </epideploy:detail> </epideploy:component> See also:
Chapter 8, Deploying Site Components, for discussion of component.xml files Appendix B, Deployment Reference, for details about every element and attribute of component.xml files
CAR File
The component archive (CAR file) contains all of the secondary page files. The Portal deployment system requires the CAR file to have a specific directory structure, as shown in Table 14.
Table 14: CAR File Directory Structure for Secondary Page Instances Files
component.xml (required) primary JSP file (required) any other JSP files any image, CSS, JavaScript, or other files required by the secondary page
/WEB-INF/classes/path_to_classes
Loose Java .class files for pre-display and process actions (if any)
141
Table 14:
CAR File Directory Structure for Secondary Page Instances Files .properties file for each locale (See Chapter 6, Internationalizing and Localizing Site Components, for more about I18N .properties files.) validation.xml file if this instance uses the Portal form validation framework (See Automating the Validation and Population of HTML Forms on page 121 for details about using the Portal form validation framework.)
/WEB-INF/misc
The Vignette Portal convention is to include the IDs of the secondary page type and secondary page instance in the path to action classesfor example,
/WEB-INF/classes/com/companyname/portal/mycompo nents/template0019/t0019customstyle0002 (where template0019 is the secondary page type ID and t0019customstyle0002 is the ID of
your new secondary page instance). NOTE: In some environments, long paths to Java classes can exceed file system length limitations, causing deployment of loose classes to fail. If this limitation is a potential problem in your environment, create a JAR file that contains the component classes and place this JAR file in the /WEBINF/lib directory of the CAR file. You can create the CAR file using the Java jar command or any compression utility that uses the ZIP format.
See also: Chapter 8, Deploying Site Components, for a discussion of the Portal deployment system and CAR files
The CAR file for your secondary page instance can be uploaded using either of these methods:
Import the CAR file from the server console (Tools >> Import
Components).
Place the CAR file in the PortalInstallDir/deployment/upload
directory, then restart the Portal web application. If the CAR file contains
142
any JAR files, restart the Portal web application a second time. (The first restart uploads the CAR file and deploys the JAR files, and the second restart causes the application server to start using the JAR files. If the CAR file contains only loose Java classes instead of JARs, only one restart is necessary.) If your secondary page should be served via HTTPS, the administration consoles can now be used to set the secure flag.
See also: Vignette Portal Administrators Guide for more about the import and HTTPS features
element defines the action classesand optionally groups of actionsthat any instances of that type can use. In most cases, a secondary page type has no <epideploy:required-component/> element (the exception is discussed in Sharing Code between Secondary Page Types on page 146). Here is an example of a typical component.xml file for a secondary page type. The differences compared to a secondary page instance are shown in bold type.
<?xml version="1.0" encoding="UTF-8"?> <epideploy:component component-id="template0014" component-type="Secondary Page Types" major-version="7" minor-version="0" build-version="76" epi-version="7.0" epi-build="1" title="Log In" description="The page where users type their username and password when logging in to the system" xmlns:epideploy="http://www.epicentric.com/deployment">
143
<epideploy:detail> <template-info id="template0014" friendly-id="LOGIN" title="Log In" description="The page where users type their username and password when logging in to the system" type="templatetype_page_content_include" is-system="true" visible="true"> allow-guest-access="true" header-filename=""> <actions> <action id="1" type="PRE_DISPLAY"> <class>com.vignette.portal.website.enduser.components .login.PreDisplayLoginAction</class> </action> <action id="2" type="PROCESS"> <class>com.vignette.portal.website.enduser.components .login.ProcessLoginAction</class> </action> </actions> </template-info> </epideploy:detail>
The <template-info> element contains a subset of the same attributes as the <style-info> element of a secondary page instance. Note that the Vignette naming convention for a secondary page types component-id attribute is "templateNNNN" (compared to "tNNNNstyleNNNN" for a secondary page instance). To ensure that your secondary pages do not collide with Vignettes, if you use the same naming convention include your organizations name in the component ID.
Defining a Group of Actions
The component.xml file for a secondary page type can include a <group> element as a child of its <actions> element. The <group> element, in turn, has child elements identifying the actions that are part of the group. The following example creates one group of pre-display actions and another group of process actions:
144
<actions> <group id="1"> <action id="1" type="PRE_DISPLAY"> <class>com.vignette.portal.website.enduser.components .mypage.common.MyPagesEnableCheckAction </class> </action> <action id="2" type="PRE_DISPLAY"> <class>com.vignette.portal.website.enduser.components .mypage.common.MyPageResolutionAction </class> </action> <action id="3" type="PRE_DISPLAY"> <class>com.vignette.portal.website.enduser.components .mypage.movecontent.PreDisplayMoveContentAction </class> </action> </group> <group id="2"> <action id="4" type="PROCESS"> <class>com.vignette.portal.website.enduser.components .mypage.common.MyPageResolutionAction</class> </action> <action id="5" type="PROCESS"> <class>com.vignette.portal.website.enduser.components .mypage.movecontent.ProcessMyPagesMoveAction </class> </action> </group> </actions>
A secondary page instance refers to a group defined in its type using the <group-reference> element. For example, a secondary page instance could use the pre-display actions group defined above (group 1) and replace the process actions with its own action sequence as follows:
<actions> <group-reference group-id="1"/> <action id="1" type="PROCESS"> <class>com.vignette.portal.website.enduser.components .mypage.common.MyPageResolutionAction </class> </action> <action id="2" type="PROCESS"> <class>com.vignette.portal.website.enduser.components .mypage.movecontent.dhtml.ProcessMyPagesDHTMLMoveA ction </class> </action>
145
Secondary page types can share common code by including in component.xml an <epideploy:required-component/> element that identifies the secondary page type containing the common code. For example, Page Display (the secondary page type for displaying portlets) has the following element in its component.xml file:
<epideploy:required-component component-type="Secondary Page Types" component-id="template0066" major-version="7" minor-version="0"/>
The template0066 component is for the Page Common secondary page type, whose component.xml looks like this:
<?xml version="1.0" encoding="UTF-8"?> <epideploy:component component-id="template0066" component-type="Secondary Page Types" title="Page Common" major-version="7" minor-version="0" build-version="76" epi-version="7.0" epi-build="1" description="Contains classes used by other Page related end user components." xmlns:epideploy="http://www.epicentric.com/deployment" > <epideploy:detail> <template-info id="template0066" friendly-id="PAGE_COMMON" title="Page Common" description="Contains classes used by other Page related end user components." type="templatetype_page_content_include" allow-guest-access="false" is-system="true" visible="false">
146
The Page Common secondary page type has no instances; rather, it contains only the shared Java classes. Note that its visible attribute has a value of "false"; as a result, this secondary page type is not included within the lists that are visible from the Portal administration consoles. To deploy a shared component, you create a CAR file that contains the components classes and component.xml.
147
148
5
Summary: Audience: Topics:
Customizing the Look and Feel of Your Portal (below) Working with the Vignette Portal CSS on page 151 Customizing the CSS on page 153
149
When developing portlets, styles, and secondary pages, you should use this CSS so that your Portal takes advantage of its benefits:
Ensures a consistent look and feel between custom components and out-of-
the-box components.
Allows the look and feel of components to be managed by administrators
feel.
The server administrator can change the fonts and colors for the default theme and for individual themes. All sites that use the server default theme inherit the fonts and colors set by the server administrator. Site administrators can also set and change the fonts and colors for any themes over which they have appropriate permissions.
Site level.
User level.
If end users have permission to customize fonts and colors for their view of a particular site, they can override server and site settings.
150
You need not put CSS classes on these tags in order for text in those tags to get a consistent visual treatment that responds to the administrator-set theme and end-user settings. This strategy ensures that most HTML developed will have basic consistency without doing anything, as long as the HTML doesnt include tags that override formatting, such as <font>.
small, regular, and large, as well as other varieties like footnotes error, warning, and confirmation
Messages:
Titles: page titles, subtitles, subsection titles, search result titles, and article headlines Menus: Forms:
menu items and navigation trails form fields and field labels both form buttons and HTML links that act as buttons
Buttons:
151
Data tables:
tables that display rows of data (headers, footers, alternating row colors, pagination links) trees that display hierarchical data (like a list of nested folders)
Appendix D, Vignette Portal CSS Reference, for descriptions and screen shots of these classes
NOTE: As of Portal version 7.0, a number of CSS classes have been deprecated. These have been replaced by new classes that provide more granular control over page display. Although deprecated classes will continue to work, you should replace them with the current classes.
If font.body.face is set to Helvetica, the Portal style sheet would contain this:
.epi-fontLg { font-family: Helvetica font-size: large; }
This would render "Hello, world" in Helvetica (or whatever font was set in the administrator-controlled theme).
152
End users can set their own font and color preferences. These preferences affect the values of font and color properties on the theme.
See also: Table 29 and Table 30 in Appendix D, Vignette Portal CSS Reference, for a full mapping of CSS to Portal theme properties.
portion look different. For instance, you can include a custom style sheet in a portlet chrome. Because each panel on a Portal portlet page can be set to use a different chrome, this is one way to make panels look different. If your custom styles have different CSS classes than those used by the Portal CSS, you can include the CSS using whatever inclusion mechanism you want (inline or a linked external reference), wherever you want it.
153
154
} See also: Chapter 7, Using the Site Development APIs, for more about Portal branding
Heres sample JSP code that constructs a link to a custom style sheet:
<% com.epicentric.template.Style currentStyle = portalContext.getCurrentStyle(); String customCssPath = com.epicentric.template.StyleUtils. createCSSStyleSheetLink( portalContext, currentStyle, "myCustomCSS.jsp", null ); %> <link rel="stylesheet" type="text/css" href="<%=customCssPath%>">
155
156
6
Summary: Audience: Topics:
Vignette Portal, I18N, and L10N (below) Creating I18N Property Files on page 158 Accessing Localized Values in Component Code on page 159
157
158
or secondary page. For each display string, the property file should define two key/value pairs:
keyname=value keyname_comment=value
The first pair provides the name of the key and its default value (used if there is no locale-specific value). The second pair provides a description of the keys purpose, to aid translators in providing appropriate text for a particular locale; note that _comment is a literal string. For example:
OKButton=OK OKButton_comment=Label for OK button
Typically, you begin the process of creating a style or secondary page by exporting an existing one. Among the exported files is the existing default properties file, which you can use as the starting point for your own properties file. When youre ready to deploy your new component, place the default properties file in the WEB-INF/i18n directory of the components CAR file. If you also have locale-specific property files for the component, name them according to the Java property file naming convention (using the twocharacter language code followed by the country code followed by the dialect or variant codefor example, t0016style_en_US.properties) and place them in this directory as well. Once the component is deployed, any number of locale-specific property files can be added using the administration consoles. (The administration consoles also allow direct entry of translations.)
See also: Vignette Portal Administrators Guide for details about using the administration consoles to upload or enter translations
159
This section explains the most common usages of custom tags for I18N.
See also: Appendix A, Vignette Portal Custom JSP Tag Reference, for details about optional attributes for I18N tags and about all Portal custom JSP tags
The simplest localization case is when you need to display localized text within a Portal style or secondary page. For such a case, you can use the <vgn-portal:i18nValue/> tag with three attributes: the UID for the style or secondary page, the resource bundle key, and the default value to be displayed if a localized value is not found. The following example displays either the current styles localized value for the key named "myaccount" or the default value"My Account" :
<vgn-portal:i18nValue stringID="<%=i18nID%>" key="myaccount" defaultValue="My Account" />
(The i18nID variable identifies the current style and is typically defined in the styles template header file. For a secondary page instance, the unique identifier is usually declared and retrieved by the primary JSP file.) The <vgn-portal:i18nValue/> tag can have a number of other attributes. For example, you can prepend and append literal strings to a localized value using the beginString and endString attributes:
<% String buttonBeginString = <input type="submit" name="cancelBtn" id="cancelBtn" value="; String buttonEndString = class="epi-button" />; %> <td align="right" nowrap="nowrap"> <vgn-portal:i18nValue stringID="<%= i18nID %>" key="cancel_button" defaultValue="Cancel" beginString="<%= buttonBeginString %>" endString="<%= buttonEndString %>" />
160
However, an easier way to deal with such situations is with the <vgnportal:i18nElement> tag:
<td align="right" nowrap="nowrap"> <vgn-portal:i18nElement> <input type="submit" name="cancelBtn" id="cancelBtn" value=<vgn-portal:i18nValue stringID="<%= i18nID %>" key="cancel_button" defaultValue="Cancel" /> class="epi-button" /> </vgn-portal:i18nElement>
Because the locale for a particular I18N key depends upon a precedence algorithm that takes the current user and a number of other factors into account, the value returned by the <vgn-portal:i18nValue/> tag could use a locale that is different from the pages locale. When this is the case, the <vgn-portal:i18nValue/> tag wraps the localized text within <span lang="locale"></span> tags (a practice that is in compliance with requirements of the American Disabilities Act). However, there are cases where you need to wrap the <span> tags around more than just the localized text itself. For example,
<img src="confirm_delete.gif" alt=<vgn-portal:i18nValue stringID="<%=i18nID%>" key="confirmalt" defaultValue="confirm deletion" />>
generates the following HTML, which erroneously displays the <span> tags as part of the alt text:
<img src="confirm_delete.gif" alt=<span lang="locale">confirm deletion</span>>
Another custom tag, <vgn-portal:i8nElement>, enables you to control where <span> tags are placed. To account for the possible presence of <span> tags, you should enclose <vgn-portal:i18nValue/> tags within beginning <vgn-portal:i18nElement> and ending </vgnportal:i18nElement> tags when displaying image, input, and other display elements. For the example above, you would wrap the <img> tag inside <vgn-portal:i18nElement> tags like this:
161
<vgn-portal:i18nElement> <img src="confirm_delete.gif" alt=<vgn-portal:i18nValue stringID="<%=i18nID%>" key="confirmalt" defaultValue="confirm deletion" />> </vgn-portal:i18nElement>
Doing so correctly places the <span> tags outside the entire <img> tag instead of outside the alt attribute only:
<span lang="locale"><img src="confirm_delete.gif" alt="confirm deletion"></span>
Suppose that you have two localizationsthat is, two <vgnportal:i18nValue/> tags within <vgn-portal:i18nElement> tags. You can specify which of the locales should take precedence by using the
primary attribute of <vgn-portal:i18nValue/>. For example:
<vgn-portal:i18nElement> <img src="image.gif" name=<vgn-portal:i18nValue .../> title=<vgn-portal:i18nValue ... primary="true"/>> </vgn-portal:i18nElement>
In this case, if <span> tags are necessary, the locale for the title will take precedence. If you omit the primary attribute in this circumstance, the locale that takes precedence is not guaranteed to be consistent between Portal versions. If you have more than one <vgn-portal:i18nValue/> tag surrounded by <vgn-portal:i18nElement> tags but you want <vgnportal:i18nElement> to apply to only one of the <vgnportal:i18nValue/> tags, simply set the ignoreAncestors attribute to true in the <vgn-portal:i18nValue/> tags that should ignore the <vgnportal:i18nElement> wrapper. For example,
<vgn-portal:i18nElement> <a href="/someURL.html" alt=<vgn-portal:i18nValue ... />> <vgn-portal:i18nValue ... ignoreAncestors="true" /></a> </vgn-portal:i18nElement>
The <vgn-portal:i18nParam/> tag can be used within opening <vgnportal:i18nValue> and closing </vgn-portal:i18nValue> tags to
162
insert values into java.text.MessageFormat pattern strings. This tag has a single attribute, value, which specifies the value to be inserted within the string. Here is an example of the use of <vgn-portal:i18nParam/>:
<vgn-portal:i18nValue stringID="<%=i18nID%>" key="note_heading" defaultValue="Note {0} of {1}"> <!-- 1st parameter: ordinal number of current note --> <vgn-portal:i18nParam value="<%= noteID %>"/> <!-- 2nd parameter: total number of notes --> <vgn-portal:i18nParam value="<%= totalNotes %>"/> </vgn-portal:i18nValue>
As shown above, you can enclose multiple <vgn-portal:i18nParam/> tags within <vgn-portal:i18nValue>. Parameters are substituted in the pattern according to the rules of java.text.MessageFormat. The <vgn-portal:i18nParams/> tag enables you to insert multiple values from an object array into a pattern. For example, chrome styles use this tag to return error messages resulting from an attempt to render a portlet:
<vgn-portal:i18nValue stringID="<%= i18nID %>" key="<%= portletRenderException.getName() %>" defaultValue="An error has occurred. This portlet is unavailable at this time."> <vgn-portal:i18nParams value="<%= portletRenderException.getErrorParameters() %>"/> </vgn-portal:i18nValue>
The <vgn-portal:i18nFormat/> tag converts number and date strings to a localized format. This tag has two attributes, both of which are required: value (string to be converted) and pattern (literal defining the output format). Here is an example:
<vgn-portal:i18nFormat value="<%= startDate %>" pattern="date.long"/>
When localized values are retrieved within the JSP of Portal pages, information about the contextthe current user, preferred languages, current site, and so onis available to the JSP. The <vgn-portal:i18nValue> tag is designed for use in such cases.
163
However, there are cases where a JSP must retrieve localized values when the user context is not known. The <vgn-portal:i18nFormattableValue/> tag is a convenient way of providing internationalization in such cases. This tag has one required attribute: formattable, which is an object of type com.epicentric.i18n.format.Formattable (described next). The <vgn-portal:i18nFormattableValue/> and <vgnportal:i18nValue/> tags are similar in function. However, <vgnportal:i18nParam/> and <vgn-portal:i18nParams/> are not used in conjunction with <vgn-portal:i18nFormattableValue/>; instead, <vgn-portal:i18nFormattableValue/> takes a formattable attribute as a parameter. For example:
<vgn-portal:i18nFormattableValue formattable="<%= errorMessage %>"/>
following purposes:
Specifying a string and its locale Defining output styles (for example, a "caution" style, which might be
The Formattable implementation most commonly used for internationalization is FormattableBundle, which supports localization of messages. These messages follow the same patterns as those of java.text.MessageFormat.
164
The following example shows passing in arrays that contain Formattable objects and strings of type java.text.MessageFormat.
FormattableBundle bundle = new FormattableBundle(uid, key, new Object[]{x}) bundle.setDefaultPattern("The default message with {2}, a {0}, and a {1} in it.", Locale.US);
Parameters are substituted in the pattern according to the order in which they appear in the arraythe first object in the array is substituted for {0}, the second for {1}, and so on. The following method uses FormattableStyle to format a style based on document type, FormattableGroup to group the style-specific string with the message text, and Formattable[] to assemble the full message.
Formattable getMessage() { // Format "Warning" heading based on locale and document type FormattableStyle warningWord = new FormattableStyle(new FormattableString("Warning:", Locale.US), com.epicentric.doctype.MarkupSource.STYLE_WARN); // Specify message string for US locale FormattableString noBackupMsg = new FormattableString("Data has not been backed up", Locale.US); // Group and return heading and message strings return new FormattableGroup(new Formattable[] {warningWord, noBackupMsg}); }
The FormattingContext class can be used to encapsulate the context for Formattable objects. A Formattable passes the FormattingContext when formatting the output string. The following calls within a JSP file would format and display the message for the current request:
<!-- Get context from request --> FormattingContext formattingContext = FormattingContext.getFormattingContext(request); Formattable formattable = null; <!-- Formattable assignment goes here... --> <!-- Format output --> formattable.format(out, formattingContext);
165
methods for getting the current locale, the Portal system-wide default locale, and the locales for a particular site. I18nUtils.getValue() is the Java equivalent of the <vgn-portal:i18nValue> tag. For example:
HttpServletRequest request = portalContext.getPortalRequest().getRequest(); HttpSession session = portalContext.getPortalRequest().getSession(); String uid = portalContext.getCurrentSecondaryPage().getUID(); String key = "not_found_msg"; String defaultMsg = "Unable to retrieve"; String i18nMessage = I18nUtils.getValue(uid, key, defaultMsg, session, request);
NOTE: One distinction between I18nUtils.getValue() and the <vgnportal:i18nValue> tag is that the tag has built-in error handling.
SafeMessageFormat
example, if a resource bundle inadvertently contains extra spaces or carriage returns, MessageFormat throws errors that can cause the entire Portal enduser site to fail. By contrast, SafeMessageFormat allows Portal to render a page with the exception of the string or strings causing errors. In the following example, SafeMessageFormat is used to include the current step number in a multi-step self-registration process (where displayBean is a JavaBean that is instantiated in the display action of the secondary page):
<tr> <%
166
String defaultTitle = I18nUtils.getValue(i18nID, "display_title", "Self Registration", session, request); String pattern = I18nUtils.getValue(i18nID, "title_pattern", ": Step {0} of {1}", session, request); // Load array with current step and total number of steps Object[] args = {new Integer(displayBean.getSteps()-1), new Integer(displayBean.getSteps())}; // Display across 3 columns. true means already localized EndUserUtils.displayTitleOfPageContent(pageContext, defaultTitle + SafeMessageFormat.format(pattern, args), 3, true); %> </tr> See also:
Chapter 4, Controlling Functionality with Secondary Pages, for details about display actions Chapter 7, Using the Site Development APIs, for discussion of the EndUserUtils class
SafeMessageFormat does not extend MessageFormat. Rather, it manipulates the error handling of an underlying MessageFormat.
I18nHelper
The com.vignette.portal.website.enduser.utils .I18nHelper class has a getFormattable() method that you can use to create a Formattable from a specified resource bundle. For example, the following method uses getFormattable() to construct a map of potential error messages (where super is the EndUserFormBean class):
protected Map getPotentialErrors() { Formattable[] message_title_required = { I18nHelper.getFormattable(super.getBundleId(), "message_title_required_1", "Invalid name.", null), I18nHelper.getFormattable(super.getBundleId(), "message_title_required_2", "Names must contain at least one non-whitespace character.", null) }; Formattable[] message_title_maxlength = { I18nHelper.getFormattable(super.getBundleId(), "message_title_maxlength_1",
167
"Name is too long.", null), I18nHelper.getFormattable(super.getBundleId(), "message_title_maxlength_2", "Maximum length is 32 characters.", null) }; Map potentialErrors = new HashMap(); potentialErrors.put("pageName::required", message_title_required); potentialErrors.put("pageName::maxlength", message_title_maxlength); return potentialErrors; }
The final parameter for getFormattable()which is set to null in the above exampleis for a MessageFormat pattern. For example:
String params[] = {"valueOne", "valueTwo"}; defaultValue = "Value1:{0} and Value2:{1}"; formattable = I18nHelper.getFormattable(bundleID, "sample_key", defaultValue, params);
168
7
Summary: Audience: Topics: See also:
Working with the Request and Response (below) Working with the Session on page 170 Generating URIs on page 172 Displaying Portlets on page 174 AJAX-Enabling Portal Components on page 178 Writing to the Vignette Portal Log on page 185 Handling Errors on page 186 Using UIDs and Friendly IDs on page 187 Working with Portal Branding on page 189 Retrieving System Properties on page 190 Retrieving the Portal Installation Location on page 190 Vignette Portal Utility Classes on page 191 Vignette Portal Constants and JSP Variables on page 191 Technical Library on Vignette Connect (http://connect.vignette.com) for Vignette Portal API documentation (javadocs) Chapter 13, Portal Services Overview, for discussion of the use of the MetaStore as a data storage mechanism
169
Vignette Portal JSP has access to PortalContext as an implicit JSP object named portalContext. You retrieve the PortalRequest from the PortalContext as follows:
PortalRequest portalRequest = portalContext.getPortalRequest();
You should use getParameter() only if the parameter has only one value; otherwise, use getParameterValues():
String[] portletsToAdd = portalContext.getPortalRequest().get ParameterValues(PORTLETS_TO_ADD_CHECKBOX_NAME);
Both of these parameter accessors perform character encoding as specified by the portal.character.encoding.default property in the Portal configuration file (PortalInstallDir/config/properties.txt).
See also:
Chapter 4, Controlling Functionality with Secondary Pages, for additional discussion of the PortalContext object Vignette Portal Configuration Guide for more about the properties.txt file
SessionInfo Class
Portal stores information about the current user, site, cookies, and so forth in a com.epicentric.common.website.SessionInfo object, which in turn is stored in the HTTP session. The SessionInfo object is built around a com.epicentric.user.User object; that is, its constructor takes a User object as a parameter. The SessionInfo object is retrieved from the session through the key SessionInfo.SESSION_INFO_NAME:
SessionInfo sessionInfo = (SessionInfo) session.getAttribute(SessionInfo.SESSION_INFO_NAME );
170
You can retrieve and modify information the SessionInfo object contains, as shown in the following example:
String requestingPage = sessionInfo.getPageRequestingVerification(); // code to verify account... // Now update the SessionInfo and session if (!com.vignette.portal.util.StringUtils.isEmpty (requestingPage)) { sessionInfo.setAccountVerifiedPage(requestingPage); session.setAttribute(SessionInfo.SESSION_INFO_NAME, sessionInfo); }
SessionUtils Class
The com.epicentric.common.website.SessionUtils class provides three methods that are wrappers for corresponding methods in javax.servlet.http.HttpSession. These methods are as follows:
getNamespacedAttribute(HttpSession session, String name, String subNamespace) setNamespacedAttribute(HttpSession session, String name, String subNamespace, Object value) removeNamespacedAttribute(HttpSession session, String name, String subNamespace)
As their names indicate, these methods provide namespacing of attributes. To prevent collisions between attribute names within the session, use these wrappers instead of their HttpSession counterparts. The following example illustrates retrieval of the site UID and the attribute identified by
com.epicentric.common.website.ParameterConstants.TEMP_CUS TOM_COLORS:
String siteUID = site==null?null:site.getUID(); HttpSession session = portalContext.getPortalRequest().getSession(); Hashtable tempCustomColors = (Hashtable) SessionUtils.getNamespacedAttribute(session, ParameterConstants.TEMP_CUSTOM_COLORS, siteUID);
In the following example, an error message is set in the session with no additional namespacing:
171
Generating URIs
Generating URIs
The Portal framework handles the intricacies of URI generation for you, providing APIs that save you from having to concatenate strings or construct the full URL. The URI generation logic includes determining whether the current request should be served over HTTP or HTTPS. In most cases, the Portal APIs generate relative rather than absolute URLs. The com.vignette.portal.website.enduser.PortalURI interface represents a pointer to a Vignette Portal resource, such as a menu item or secondary page. The PortalURI object can be converted into a string through its toString() method, which URL-encodes the object. You can create a PortalURI using methods on
com.vignette.portal.website.enduser.PortalContext (one of
the implicit objects available to JSPs). Most URI generation occurs in the actions of secondary pages.
See also:
Chapter 1, Vignette Portal Web Site Overview, for discussion of URL generation Chapter 4, Controlling Functionality with Secondary Pages, for more about the PortalURI and PortalContext objects as well as discussion of redirecting and forwarding
172
Generating URIs
(Notice that the <a> tag uses a Vignette Portal CSS class to control look and feel and a custom JSP tag to localize the button text.)
See also:
Chapter 5, Using Cascading Style Sheets, for an explanation of how to use CSS with Portal Chapter 6, Internationalizing and Localizing Site Components, for details about the Portal I18N framework
Whereas the login button creates a display URI, the logout button creates a process URI, which in turn redirects to the logout page after the logout processing has occurred.
See also:
Chapter 2, Controlling Navigation and Appearance with Styles, for details about the account controls and other Portal styles Chapter 4, Controlling Functionality with Secondary Pages, for more about using PortalURI within actions and for a discussion of redirecting and forwarding
173
Displaying Portlets
The first parameter is the friendly ID of the secondary page type, and the second parameter is the friendly ID of a page that displays portlets. For example, the following call would force rendering of the portlet page whose friendly ID is "nationalnews":
PortalURI newsURL = portalContext.createPageURI(PAGE, "nationalnews");
If you dont specify the template friendly ID, the Portal framework defaults to the Page Display secondary page type.
See also: Chapter 4, Controlling Functionality with Secondary Pages, for information about creating custom portlet display pages
Displaying Portlets
You display a portlet by using a series of Vignette Portal JSP tags, nested as follows:
<vgn-portal:renderPortlet portletWindow=object | portletFriendlyID="string"> <vgn-portal:onRenderSuccess> ...content before portlet-rendered content... call to <vgn-portal:insertPortletContent /> ...content after portlet-rendered content... </vgn-portal:onRenderSuccess> <vgn-portal:onRenderFailure> ...content to be displayed when portlet rendering fails...
174
Displaying Portlets
</vgn-portal:onRenderFailure> </vgn-portal:renderPortlet>
Both of the attributes of the <vgn-portal:renderPortlet> tag are optional. All types of portletsJava standard (JSR 286) portlets, portlets that meet the Web Services for Remote Portlets (WSRP) specification, and PortalBean portletsmay be rendered using these custom tags. This section describes the ways that you can use these tags to display portlets within a Portal page. .
See also:
Appendix A, Vignette Portal Custom JSP Tag Reference, for details about Portal JSP tags Chapter 9, Java Standard Portlets and Vignette Portal, for more about Java standard portlets Vignette Application Portal Module Developers Guide for details about the rendering of PortalBean portlets
(optional border, title bar, and buttons for users to interact with the portlet) in addition to rendering the portlet content. (See Chapter 2, Controlling Navigation and Appearance with Styles, for details about chrome styles and discussion of chromeless portlets.)
The Page Display and DHTML Page Display secondary pages, which
render chromeless portlets within a portlet page. (See Chapter 2, Controlling Navigation and Appearance with Styles, for discussion of chromeless portlets. See Chapter 4, Controlling Functionality with Secondary Pages, for discussion of secondary pages.)
The Default Maximize secondary page, which renders a portlets MAXIMIZED window state The Default Raw secondary page, which renders a portlets RAW window
175
Displaying Portlets
within any JSP (such as a style) These out-of-the-box components use the <vgn-portal:renderPortlet> tag without either of its optional attributes. This usage is designed for display of any portlet instance on a portlet page (that is, on a page designed to display one or more portlets). The portlet window is specified by a request attribute, and the content to be rendered is specified by the portlet window.
The Portal framework supports the <vgn-portal:renderPortlet> tag with the portletFriendlyID attribute in any JSP page that is part of the Portal web application. This attribute can be used to display a portlet in any window state: NORMAL, MAXIMIZED, MINIMIZED, RAW, SOLO, or BINARY. NOTE: Although the framework allows a portlet to be embedded in a grid, best practice is to restrict the grid to its intended role of defining the structure of a portal page.Portlets that are embedded into styles are rendered in serial, just as styles themselves are. The portletFriendlyID attribute supports chromeless portlets only. If a portlet has been configured to include chrome, the setting will be silently ignored and the portlet will be rendered without chrome.
See also:
Chapter 2, Controlling Navigation and Appearance with Styles, for a discussion of chromeless portlets Chapter 3, Controlling Page Structure with Grids, for details about developing grids
Here are a few examples of features you can implement by embedding particular portlets within styles:
You can include a search portlet in the header style.
176
Displaying Portlets
You can add a portlet that displays a message or image and include a
reference to the portlet within your header or footer style. Portal administrators can then change the message or image simply by updating the portlets details from the server or site console.
You can use a portlet to display site navigation by creating a navigation
portlet and embedding it within the navigation style; or you can remove the navigation style from your grid and embed the navigation portlet in any other style that the grid includes.
You can surface any kind of specialized content by creating a custom style
and embedding a portlet in it. For example, you can create an advertisement style and embed an advertisement portlet within it. Portlets that are embedded into styles are rendered in serial, just as styles themselves are. NOTE: Java standard portlets are not parallel-rendered, under any circumstances. WSRP portlets are parallel-rendered, on all application servers. PortalBean portlets are parallel-rendered using the pageStart() method.
See also: Chapter 2, Controlling Navigation and Appearance with Styles, for details about developing header, footer, navigation, and custom styles
Portlets can also be embedded directly into a custom secondary page. For example, if you want specific portlets to display in specific locations within the portlet display page, you can create a custom Page Display secondary page that embeds those portlets. You can also embed a navigation or other specialized portlet into the custom secondary page rather than into a style.
See also:
Chapter 1, Vignette Portal Web Site Overview, for an explanation of the Portal page composition process Chapter 4, Controlling Functionality with Secondary Pages, for details about customizing the Page Display secondary page
177
When you refer to a specific portlet using the portletFriendlyID attribute of <vgn-portal:renderPortlet>, the following steps are necessary to fully deploy your customizations:
If the portlet referred to is not already deployed, it must be deployed along
Chapter 10, Deploying a Java Standard Portlet into a Portal Instance, for details about deploying Java standard (JSR 286) portlets Vignette Application Portal Module Developers Guide for details about deploying PortalBean portlets Chapter 8, Deploying Site Components, for details about deploying all other components
178
179
See also:
Chapter 2, Controlling Navigation and Appearance with Styles, for more about developing styles Chapter 4, Controlling Functionality with Secondary Pages, for more about developing secondary pages Chapter 9, Java Standard Portlets and Vignette Portal, for discussion of AJAX enablement of Java standard (JSR 286) portlets Chapter 12, PortalBean Portlets, for discussion of AJAX enablement of PortalBean portlets Appendix C, Vignette Portal JavaScript Functions, for reference information about the JavaScript functions in the Portal AJAX Library
If an AJAX request contains the friendly ID for a style or secondary page, the specified component is invoked independently of the surrounding grid. The usual MVC pattern is respected: A secondary page invocation results in the execution of pre-display and/or process actions prior to the secondary page JSP being executed, and a style directly invokes the associated style JSP. An AJAX request can optionally forward to a standard Portal URI that results in the rendering of a complete Portal page. NOTE: If a component redirects or forwards during an AJAX request to a component whose display is intended to be rendered in a non-AJAX fashion, the URL in the browsers address bar still reflects the original URL after the redirection or forward occurs. This behavior is because the URL is transparent to the XMLHttpRequest object and hence cannot be loaded into the address bar. (Also note that redirecting or forwarding from a nonAJAX URI to an AJAX URI is not supported, since an AJAX request must be initiated from the client browser using the XMLHttpRequest object.) In the primary JSP for a style or secondary page, you can include logic to handle the AJAX request separately from the non-AJAX requestfor example:
<% if (portalContext.isPartialPageRequest() ) {%> // markup to be aggregated in AJAX-style update <% } else { %> // standard page request
180
If Portal is configured to be selectively secure and a secondary page creates an AJAX URL to another secondary page, redirection fails if there is a mismatch in security requirementsthat is, under either of these conditions:
If a secondary page does not require security, but it creates an AJAX link to
secondary page that does not require security To avoid such mismatches, care must be taken when configuring the Portal selective security settings. Redirection also fails even if the security requirements between current and target secondary pages match, but Portal redirects to a secondary page having the opposing security requirement. This circumstance applies most commonly to the login page: If an AJAX request redirects to the login page because of a session timeout and the security requirements between Portal and the login page (and its referring page) are mismatched, the redirection fails. A solution to this circumstance is to avoid redirection to pages that might have opposing security requirements. (See Chapter 1, Vignette Portal Web Site Overview, for discussion of Portals selective security feature.) The next sections provide examples of the use of the Portal AJAX Library with styles and secondary pages. You enable a style or secondary page to partially update itself by using an AJAX URI. This URI may be either an action URI or a display URI. To create an AJAX URI, first use the portalContext implicit object (within a JSP) or com.vignette.portal.website.enduser.PortalContext (within a Java class) to create a PortalURI object; then use setPartialPageURI() on PortalURI to delineate it as an AJAX URIfor example:
Creating URIs for Partial Page Updates. PortalURI autoCompleteURI = portalContext.createTemplateProcess URIAsPortalURI(); autoCompleteURI.setPartialPageURI(); String autoCompleteURIAsString = autoCompleteURI.toString();
If an AJAX URI points to a style, the styles primary JSP is included. If an AJAX URI points to a secondary page, the secondary pages pre-display and process actions are invoked prior to rendering the display; when the display is rendered, it does not include any of the surrounding Portal accoutrements. In the case of action URIs, the corresponding process action class can use conditional logic to return different URIs.
181
IMPORTANT: Be sure to call setPartialPageURI() before returning a URI that is intended for AJAX-style updates. Failing to do so is considered an error response to an AJAX request.
Performing a Partial Page Update from a Link.
An AJAX request can be initiated simply by the clicking of a link. The following example illustrates the use of the Portal AJAX Librarys sendURL() function to partially update a page from a link:
<% PortalURI linkURI = portalContext.createDisplayURI("ajaxsecondary"); linkURI.setPartialPageURI(); String linkURIAsString = linkURI.toString(); %> <a href="" onclick="new VignettePortal.AJAXClient().sendURL(<%=linkURIAsS tring%>,callbackFunction);return false"> Next Page </a> <script language="JavaScript"> function callbackFunction(req) { var responseText=req.responseText; // code to update DOM in browser } </script> Performing a Partial Page Update from a Form Submission.
You can perform AJAX requests in forms that use either GET or POST. The following example shows a form whose submission partially updates a page. It demonstrates the use of AJAX with an HTTP POST request.
PortalURI formProcessURI = portalContext. createTemplateProcessURIAsPortalURI(); formProcessURI.setPartialPageURI(); String formProcessURIAsString = formProcessURI.toString();
<%
182
method="POST"> </form> <script language="JavaScript"> function callbackFunction(req) { var responseText=req.responseText; // code to update DOM in browser } </script>
Note this examples use of the Portal AJAX Librarys sendForm() function. The Portal AJAX Library provides multipart form support through its customization of the Dojo IframeIO. For a multipart form, set the encoding type as multipart/form-data, and use the sendMultiPartForm() library function. This function supports text/plain, text/html, and text/javascript responses. Here is a multipart form example where the response is text/plain content (the default):
Uploading a File from a Multipart Form. <form name="main" id="main" action="<%=formProcessURIAsString%>" enctype="multipart/form-data" onSubmit="new VignettePortal.AJAXClient().sendMultiPartForm(this ,callbackFunction);return false" method="POST"> <input type="file" name="fileContent"> </form>
For a text/html or text/javascript response, specify the response MIME type as wellfor example:
onSubmit="new VignettePortal.AJAXClient().sendMultiPartForm(this ,callbackFunction,text/html);return false"
The Portal AJAX Library uses an IFrame to achieve this functionality. As a result, the only reliable, cross-browser way of knowing when the response is loaded is by using an HTML document as the return type. For text/plain and text/javascript responses, the response must be within the first textarea of the response document. The library returns the contents of the textarea as the response to your callback function. For text/html responses,
183
the callback functions parameter is the complete HTML document. Consult the Dojo documentation for further details.
Auto-Completing a Textbox.
The following example shows a form POST providing immediate feedback based on what is entered into a textbox, without any explicit button interaction:
PortalURI autoCompleteURI = portalContext.createTemplatePro cessURIAsPortalURI(); autoCompleteURI.setPartialPageURI(); String autoCompleteURIAsString = autoCompleteURI.toString();
<%
%> <form name="formToSubmit" action=<%=autoCompleteURIAsString%> method="POST" ... > <input type="text" size="20" autocomplete="off" name="autoCompleteField" onkeyup=" new VignettePortal.AJAXClient().sendForm(docu ment.forms[formToSubmit],callbackFunction);retur n false"/> </form> <script language="JavaScript"> function callbackFunction(req) { var responseText=req.responseText; // code to update DOM in browser } </script> Session Timeouts and Errors.
If an AJAX request occurs after the session has expired, the request is redirected to the Portal login page. This redirect also occurs if the user does not have proper authorization. For secondary pages, two conditions result in errors:
and it is not handled in that class. In this case, the Portal framework displays the standard error page.
If an action class redirects or forwards to a non-AJAX URI. In this case,
you should redirect to the next logical view of your application or to a customized error page.
184
To gracefully handle an error condition, catch any exceptions and call the setPartialPageURI() method on the URI object to which you want to redirect or forward.
See also: Performing a Partial Page Update from a Form Submission on page 182 for more about the setPartialPageURI() method
Another signature for the logging methods takes three parameters: the message, a throwable, and a map providing current environment information. For example:
try { . . . } catch(Exception e) { LOG.debug("could not connect to resource", System.getProperties(), e); }
You can also log a throwable without including an explicit message or any other parameters:
try { . . . } catch(Exception e) { LOG.debug(e); }
The LOG implicit variable in JSPs is an instance of com.vignette.portal.log.LogWrapper, which provides a simplified means of namespacing logged messages. LogWrapper has two constructors:
185
Handling Errors
where originatingClass is the name of the class that is the source of the message and subsystem is an optional category of messages, used to filter messages by subsystem. If the subsystem is not specified, the Java package of the source class is used. The willLogAtLevel(int level) method on LogWrapper can avoid unnecessary logging overhead. You should call this method before the logging method whenever message preparation will require processing (such as string concatenation or map formation)for example:
if (LOG.willLogAtLevel(LogConfiguration.DEBUG)) { LOG.debug(LOG.debug("HEADER " + name + " = " + value); }
Within a Java class, the recommended way to use the logging API is to declare a private static variable that is an instance of LogWrapper:
public class SampleClass { private static final LogWrapper LOG = new LogWrapper(SampleClass.class, "com.companyname.samples") . . . }
Then, use this LOG instance to perform all logging within the class. Each message that is logged will include the name of the subsystem.
Handling Errors
Within style components, you can display a localized error message inline as the error is encounteredlike this:
<p class="epi-error"><vgn-portal:i18nValue stringID="<%= i18nID %>" key="password_invalid" defaultValue="The password you entered is invalid. Please enter your password again." /></p>
NOTE: Chrome styles have their own error-handling exceptions and JSP tags.
186
To display an error that exists within the session, use this method on com.epicentric.common.website.EndUserUtils, passing in the PageContext:
<% EndUserUtils.displayErrorMessage(pageContext); %>
Secondary page actions can redirect to an error secondary page by using the getErrorURI() method on the BaseAction class. Styles can use a method on EndUserUtils and the com.epicentric.common .website.ParameterConstants.REDIRECT_TYPE_PRINT constant to redirect to the default error page, as shown in the following example:
try { pageModuleSet = linkedPage.getPageModuleSet(); } catch (PageException pe) { LOG.error(pe); String errorMessage = I18nUtils.getValue(i18nID, "PageExceptionMsg", "could not get page module set for page", session, request); EndUserUtils.errorRedirect(pageContext, errorMessage, ParameterConstants.REDIRECT_TYPE_PRINT); return; }
You can define an error page for any JSP page. You can also define error pages for the WAR that contains a JSP page. If error pages are defined for both the WAR and a JSP page, the JSP pages own error page takes precedence. You therefore could implement a strategy of creating a generic error page in addition to specialized error pages for individual JSPs. To retain your organizations branding, you can create a custom error secondary page type.
See also:
Chapter 2, Controlling Navigation and Appearance with Styles, for an explanation of style components Chapter 4, Controlling Functionality with Secondary Pages, for details about handling errors within a secondary page action
187
UIDs within code is to retrieve the current styles I18N resource bundlefor example:
<% String i18nID = portalContext.getCurrentStyle().getUID(); %> <a href="<%=logoutURL%>" class="epi-link1"><vgnportal:i18nValue stringID="<%=i18nID%>" key="logout" defaultValue="Logout" /></a>
(See Chapter 6, Internationalizing and Localizing Site Components, for more about the use of the i18nID variable with resource bundles.) Many Portal componentsstyles, style types, secondary pages, secondary page types, grids, etc.also have friendly IDs, which are strings that provide a more human-readable means of referring to objects within code and the administration consoles. For example, you can include the current Page Controls style in a JSP page like this:
<vgn-portal:includeStyle friendlyID="page_controls"/>
Use the PortalRequest object to get the friendly ID for the current style type or secondary page type:
String secPageType = portalContext.getPortalRequest().getTemplateFriend lyId();
(See Working with the Request and Response on page 169 for a discussion of the PortalRequest object.) In this next example, com.epicentric.template.TemplateUtils returns the current grid (which is a Style object), and the grid returns its friendly ID:
Style currentGrid = TemplateUtils.getCurrentGrid(portalContext); String gridFriendlyID = ""; if (currentGrid != null) { gridFriendlyID = currentGrid.getFriendlyID(); }
a unique friendly ID. Also, two grids cannot have the same friendly ID (because grids are all styles of one grid Template object); for the same
188
reason, two styles of the same style type and two secondary pages of the same secondary page type cannot have the same friendly ID. When assigning names to friendly IDs, avoid using spaces and special characters like colons and slashes. Also note that friendly IDs are case sensitive. The initial value of a friendly ID comes from the component descriptor (component.xml file, explained in Chapter 8, Deploying Site Components). Friendly IDs can be managed through the administration consoles; administrators can change the friendly ID of a component. Doing so would necessitate changing the value of the friendly ID wherever it is used in the code. As a result, you must coordinate with Portal administrators to ensure that friendly IDs in the UI are consistent with those in the code.
See also: Chapter 2, Controlling Navigation and Appearance with Styles, for information about friendly URIs for navigation items
Here is an example of how you can use the Branding object to retrieve display characteristics:
String fontFamily = branding.getFontValue("font.body.face"); String bgColor = branding.getColorValue("bgColor.bg4"); String textColor = branding.getColorValue("fontColor.link3Link"); String rolloverTextColor = branding.getColorValue("fontColor.font1");
189
The parameter passed into getFontValue() and getColorValue() is a theme property. The values of theme properties are mapped to the Vignette Portal CSS.
See also: Chapter 5, Using Cascading Style Sheets, for information about using the Portal CSS
NOTE: The com.epicentric.common.Props class has been deprecated. Use the pattern shown above instead of it to retrieve Portal properties.
190
com.epicentric.common
Working with the Request and Response on page 169 for more about the PortalContext object Writing to the Vignette Portal Log on page 185 for more about the Portal log
191
192
8
Summary: Audience: Topics:
Vignette Portal Component Architecture (below) Deployment Process Overview on page 195 Component Archive File Structure on page 198 Component Descriptor File Structure on page 199 Component Uniqueness and Versioning on page 204
193
Figure 46:
end user
component.xml Secondary Page Classes & JSPs component.xml
Vignette Portal site components can be divided into two categories based on the underlying objects that represent them:
Style types, secondary page types, and a single grid style type are represented by objects of type com.epicentric.template.Template. Styles, secondary pages, and grids are specific instances within a Template category and are represented by objects of type com.epicentric.template.Style.
See also:
Chapter 10, Deploying a Java Standard Portlet into a Portal Instance, for information about Java standard portlet deployment Vignette Application Portal Module Developers Guide for information about PortalBean portlet deployment
194
A specialized compressed file referred to as the component archive, or CAR file, is created (either manually or by exporting an existing component using the administrative consoles). This archive contains all of the files that make up a particular component. It also includes the component.xml file, which describes the component as well as the structure and contents of the CAR file. Portal imports (or uploads) information from the CAR file into the Portal database. The uploaded component becomes a new record in the database, unless a component of the same type and with the same ID and version already exists in the database. In this case, the newly uploaded component replaces the existing record in the database. Portal deploys the component from the information in the Portal database, creating files in the file system as required by the component.
195
Figure 47:
Deployment Overview
Portal Component JSPs & Images Java Classes Java Libraries component.xml Portal Database CAR file (A compressed set of directories and files)
All end-user components JSPs and images are deployed to subdirectories under the WARs templates directory. All Java classes and libraries are deployed under the WEB-INF directory. The data contained in the component.xml file is uploaded into the Portal database; this file and its data do not reside on the file system. For a secondary page that uses the Portal validation framework, the validation.xml file is also uploaded into the Portal database and not copied onto the file system. NOTE: You must restart Portal in order to realize any deployed component containing jars or classes.
Uploading Components
Deployment of components into a Vignette Portal installation can be initiated in either of two ways:
By importing CAR files using the Portal administration consoles, followed
by a Portal web application restart if the CAR files include any JAR files
By placing CAR files in the PortalInstallDir/deployment/upload
directory and then restarting the Portal web application. If the CAR file
196
contains any JAR files, a second restart is necessary. (The first restart uploads the CAR file and deploys the JAR files, and the second restart causes the application server to start using the JAR files. If the CAR file contains only loose Java classes instead of JARs, only one restart is necessary.)
See also: Vignette Portal Administrators Guide for details about using the administration consoles to import components
Downloading Components
The deployment system also includes an export mechanism, whereby data on a specific, previously deployed component is downloaded from Portal and assembled into a CAR file on the file system. The export mechanism constructs the component descriptor (component.xml file) from the data contained in the Portal database. In the case of a secondary page that uses the Portal validation framework, the validation.xml file is also constructed from the data in the Portal database. Rather than creating component.xml and CAR files from scratch when developing new components, you can use the export mechanism as part of your development methodology. For example, when developing a new style or grid, you can use the administration consoles on a development Portal to introduce the component into the Portal, upload its primary and secondary files, and perform iterative testing and modification cycles. When development is complete, you can create the new components CAR file (including its component descriptor) by exporting it. IMPORTANT: If you use the export mechanism to create a new components CAR file, before uploading that CAR file to a QA, production, or other Portal installation, be sure to check and modify it as needed. For example, a secondary page having custom action classes must include those classes in the CAR file as well as make reference to them within the component descriptor. Other examples of changes you might want to make are adding I18N property files to the CAR file, modifying existing I18N property files, or editing the component ID in the component descriptor rather than using the automatically assigned ID.
See also: Vignette Portal Administrators Guide for details about using the administration consoles to create and export components
197
Depending upon the type of component, CAR files can include the following directories and files:
/component.xml /*.jsp /*.html /*.gif /*.jpg /*.css /*.inc / any other support files /WEB-INF/classes/classpath/secondaryPageTypeID/*.class /WEB-INF/classes/classpath/secondaryPageTypeID/second aryPageID/*.class /WEB-INF/i18n/componentUID_locale.properties /WEB-INF/lib/*.jar /WEB-INF/misc/validation.xml
Table 16 describes the CAR file contents and where these contents are deployed.
Table 16: CAR File Contents and Deployment Destination Location After Deployment Loaded in the database; not copied to the file system PortalWebAppDir/templates/template ID/styleID PortalWebAppDir/templates/template ID PortalWebAppDir/templates/templateID/s tyleID Comments This file provides instructions to the deployment system. Styles, grids, and secondary pages have JSP files. Some style types have template header files. Styles, grids, and secondary pages can include various support files.
File Name or Type component.xml JSP files Template header (.inc) files Image, CSS, and other support files
198
Table 16:
CAR File Contents and Deployment Destination (Continued) Location After Deployment Comments
PortalWebAppDir/WEB-INF/classes Only secondary page types and secondary pages that define their own actions in loose Java classes include this directory structure. Loaded in the database; not copied to the file system PortalWebAppDir/WEB-INF/lib These files provide localized and default values for display strings. See Uploading Components on page 196 for information about restarting Portal when deploying CAR files that contain JAR files. Only a secondary page that uses the Portal validation framework includes this file.
validation.xml
See also:
Chapter 2, Controlling Navigation and Appearance with Styles, for information specific to CAR files for styles and style types Chapter 3, Controlling Page Structure with Grids, for information specific to CAR files for grids Chapter 4, Controlling Functionality with Secondary Pages, for information specific to CAR files for secondary pages and secondary page types as well as validation.xml files for secondary pages
199
epi-build="integer" title="string" description="string" xmlns:epideploy="http://www.epicentric.com/deployment" > <epideploy:required-component component-type="Style Types"|"Secondary Page Types" component-id="string" major-version="integer" minor-version="integer" /> <epideploy:detail> ... component-specific detail elements ... </epideploy:detail> </epideploy:component>
The <epideploy:component> element is the parent for all of the other elements of component.xml. Here is a brief description of the attributes of <epideploy:component>:
component-idThe unique ID of the component. When a new
component is deployed, Portal uses this ID as the name of the subdirectory it creates for the components primary and secondary files. When you create or duplicate a component through the administration consoles, Portal assigns a unique 128-bit number in hexadecimal notation as the ID. For out-of-the-box components, the Portal naming convention is, for example, "template0088" (for a style type or secondary page type) or "t0088style0001" (for a style or secondary page of type template0088). To ensure that your components do not collide with Vignettes, if you use the same naming convention include your organizations name in the component ID.
component-typeThe appropriate literal value shown above. major-version, minor-version, and build-versionCombination
of values that identify the version of the component (note, however, that the deployment system ignores build-version).
epi-version and epi-buildStrings identifying the oldest version of
Portal that the component will run on (note that the deployment system ignores epi-build).
title and descriptionStrings having a maximum length of 255
200
above. If a component has dependencies, the <epideploy:component> element must include a child element named <epideploy:requiredcomponent/> for each dependency. This element applies primarily to styles and secondary pages, which have a dependency on their style types and secondary page types respectively. The attributes of <epideploy:required-component/> uniquely identify the dependency. The <epideploy:component> element must include a child element named <epideploy:detail>. The structure and contents of <epideploy:detail> depend upon the kind of component. The two broad categories of components are templates (style types and secondary page types) and styles (styles, grids, and secondary pages).
See also:
Appendix B, Deployment Reference, for details about every element and attribute in component.xml Component Uniqueness and Versioning on page 204 for a description of the deployment systems versioning scheme
Style types and secondary page types must include <template-info> as a child element of <epideploy:detail>. The id attribute must match the
201
component-id attribute of <epideploy:component>, and the title and description attributes can be the same as the <epideploy:component>
attributes of the same name. Here is a brief description of the other attributes of <template-info>:
friendly-idMnemonic or other meaningful ID of up to 255
characters.
typeThe literal value "templatetype_ui_element" for most style types or "templatetype_page_content_include" for secondary
page types. There are two specialized style types: grid and JSP include. For the grid style type, the type value is "templatetype_ui_grid_element"; for the JSP include style type, the type value is "templatetype_standard_jsp_include". (Portal ships with one grid style type and multiple grid styles. Portal also ships with one JSP include style type and one JSP include style.)
header-filenameThe name of the template header file, if any, for a
style type (secondary page types do not have header files). The Portal naming convention for this file is "template_header.inc".
allow-guest-accessBoolean specifying whether access by guests is
allowed. (A guest is a site visitor who either does not have a Portal user account or is not currently logged in.)
is-systemBoolean specifying whether this component is one that ships
with Portal.
visibleBoolean specifying whether this component is visible within
the Portal administration consoles. For secondary page types only, the <template-info> element can include a child element named <actions>:
<actions> <action id="string" type="PROCESS|PRE_DISPLAY"> <class>full.path.to.class</class> </action> ...any number of additional <action> elements... <group id="string"> ...any number of <action> elements... </group> </actions>
202
See also:
Chapter 4, Controlling Functionality with Secondary Pages, for discussion and examples of actions Appendix B, Deployment Reference, for details about every element and attribute in component.xml
Styles, grids, and secondary pages must include <style-info> as a child element of <epideploy:detail>. Many of the attributes of <styleinfo> are the same as for <template-info> (explained in the previous section). Here is a brief description of the attributes that are unique to <style-info>:
primary-filenameThe name of the primary JSP file for the
component.
template-uidThe ID of this components style type or secondary page type, as defined in the types component.xml. template-defaultBoolean specifying whether this component is the
system should apply the style types header file, if any (applies only to style components).
203
processing-typeThe literal value "ACTION_BASED" for a secondary page that is to use any action classes defined for it, or "JSP_BASED" in all
other cases. As with secondary page types, a secondary page can have an <actions> child element within its <style-info> element:
<actions> <action id="string" type="PROCESS|PRE_DISPLAY"> <class>full.path.to.class</class> </action> ...any number of additional <action> elements... <group id="string"> ...any number of <action> elements... </group> </actions> See also:
Chapter 4, Controlling Functionality with Secondary Pages, for discussion and examples of actions Appendix B, Deployment Reference, for details about every element and attribute in component.xml
If a component is deployed where these four values match the values for an existing record in the database, then the data from the new CAR file replaces the existing record. The version of a component is determined by the major-version and minor-version attributes. If a component is deployed and then later the same component with the same or newer (larger) major version or minor version is deployed, that component overwrites and replaces the previously
204
deployed version. (The build-version attribute is ignored by the deployment system but can be useful in tracing bugs.) An older version of a component cannot be deployed on a Vignette Portal installation that already has a newer version of that component. However, the newer version can be deleted via the Portal administration consoles, and then the older version can be deployed.
205
206
9
Summary: Audience: Topics: See also:
Overview of Vignette Portal and Java Standard Portlets (below) Java Standard Portlet Tag Library on page 210 Roles on page 210 User Attribute Mapping on page 211 Handling URL Security Exceptions on page 212 AJAX-Enabling Portlets on page 212 Introduction to this guide for discussion of the Vignette Portal architecture Chapter 7, Using the Site Development APIs, for discussion of the ways that portlets can be displayed on Portal pages
209
Portal supports the required portlet modes defined in the specification (VIEW, EDIT, and HELP) as well as all predefined custom portlet modes except for the PRINT mode. Portal also supports the required window states (NORMAL, MAXIMIZED, and MINIMIZED), in addition to three custom window states (BINARY, SOLO, and RAW). Chapter 11, Using Portlet Modes and Window States, provides more information about these topics. Java standard portlets and Portal can share information using request attributes, which can be set in the display actions of Portal secondary pages. This topic is among those covered in Chapter 4, Controlling Functionality with Secondary Pages At this time, Java standard portlets do not have access to Vignette Portal services (such as connection pooling and caching) or the Portal public APIs.
See also:
http://java.sun.com for the Java Portlet Specification and other information about Java standard portlets http://jakarta.apache.org/pluto for details about the open-source Apache Pluto project
NOTE: Portal requires that Java standard portlets use version 2.3 of the Web Application DTD.
Roles
Any role declared by a portlet in portlets.xml shows up as a permission on that portlet in the Portal administration consoles. Both code in the portlet and code in servlets/JSPs can call isUserInRole() on the
210
Portal User Property email firstname middlename lastname gender address1 city state zip country employer day_phone night_phone mobile_phone fax
211
NOTE: Because the portlet standards attribute for date of birth (user.bdate) is expected to be a string representing milliseconds since January 1, 1970, 00:00:00 GMT, this attribute is not mapped to the Portal dob property (which is a string). As a result, calls to retrieve user.bdate will return null. Also note that the portlet standard divides telephone numbers into component attributes (international code, local code, number, and extension), whereas Portal uses single properties (day_phone, night_phone, and mobile_phone) for telephone numbers. Check your user data to determine what mappings are most appropriate.
See also: Vignette Portal Configuration Guide for details about adding properties to entity_management.xml and performing other updates to the file
AJAX-Enabling Portlets
Portal provides AJAX support for Java standard portlets through the RAW custom window state (discussed in Chapter 11, Using Portlet Modes and Window States). You can use a third-party AJAX widget toolkit, a homegrown toolkit, or the Portal AJAX Library to perform AJAX-style updates within this window state. For those situations where using a widget toolkit does not fit your use case ideally, the Portal AJAX Library is a convenient API providing an abstraction layer over the lower-level details. When using any AJAX library or toolkit, be sure to use proper namespacing of the JavaScript functions. The following example ensures that having more
212
AJAX-Enabling Portlets
than one instance of a portlet on a page does not lead to JavaScript name contention:
String nameSpace = renderResponse.getNamespace(); String formName = nameSpace +".myForm"; String callbackFunction = nameSpace +".callbackFunction"; // more nameSpace declarations... See also: Chapter 7, Using the Site Development APIs, for general discussion of AJAX support within Vignette Portal
followed by a render request on each portlet on the page, with the exception of any portlets that have cached markup. This requirement is not met for a portlet that triggers an action or render request using an AJAX-style request model.
The JSR 168 specification states that a portlet rendered as a side effect of a
client interaction with a different portlet on the page must receive the same set of parameters as those received in the previous render request. This requirement is not met with AJAX-style updates. When a portlet display page is refreshed as a result of either a browser refresh command or a standard interaction with another portlet on the page, a portlet that uses AJAX-style updates does not receive its last set of render parameters. For example, suppose a portlet display page has two shopping portlets on it, one that uses AJAX and one that does not. Suppose also that a user interacts with the traditional portlet and then performs an AJAX-style search with the AJAX portlet. At that point, if the user switches back to interacting with the traditional portlet, as soon as that interaction causes a page refresh the AJAX portlet reverts to its main (initial) view, thereby losing the search results. On the other hand, if both portlets are implemented using traditional techniques, the user can interact with both portlets without losing state in either.
AJAX-style updates can cause overlaps or excessive gaps between portlets
213
AJAX-Enabling Portlets
You enable a portlet to partially update itself by creating a URL to the RAW window statefor example:
PortletURL ajaxURL = renderResponse.createRenderURL(); WindowState windowState = new WindowState("raw"); ajaxURL.setWindowState(windowState);
214
AJAX-Enabling Portlets
An AJAX request can be initiated simply by the clicking of a link. The following example illustrates the use of the Portal AJAX Librarys sendURL() function to partially update a portlet from a link:
<a href="" onclick="new VignettePortal.AJAXClient().sendURL(<%=ajaxURL.to String()%>,callbackFunction);return false"> Next Page </a> <script language="JavaScript"> function callbackFunction(req) { var responseText=req.responseText; // code to update DOM in browser } </script>
The following example shows a form whose submission partially updates a portlet. It demonstrates the use of AJAX with an HTTP POST request.
<form name="<%=formName%>" onSubmit="new VignettePortal.AJAXClient().sendForm(this,<%=call backFunction%>);return false" ... method="POST"> ... </form> <script language="JavaScript"> function callbackFunction(req) { var responseText=req.responseText; // code to update DOM in browser } </script>
Note this examples use of the Portal AJAX Librarys sendForm() function.
215
AJAX-Enabling Portlets
The Portal AJAX Library provides multipart form support through its customization of the Dojo IframeIO. For a multipart form, set the encoding type as multipart/form-data, and use the sendMultiPartForm() library function. This function supports text/plain, text/html, and text/javascript responses. Here is a multipart form example where the response is text/plain content (the default):
<form name="<%=formName%>" enctype="multipart/form-data" onSubmit="new VignettePortal.AJAXClient().sendMultiPartForm (this,<%=callbackFunction%>);return false" ... method="POST"> ... <input type="file" name="fileContent"> </form>
For a text/html or text/javascript response, specify the response MIME type as wellfor example:
onSubmit="new VignettePortal.AJAXClient().sendMultiPartForm (this,<%=callbackFunction%>,text/html);return false"
The Portal AJAX Library uses an IFrame to achieve this functionality. As a result, the only reliable, cross-browser way of knowing when the response is loaded is by using an HTML document as the return type. For text/plain and text/javascript responses, the response must be within the first textarea of the response document. The library returns the contents of the textarea as the response to your callback function. For text/html responses, the callback functions parameter is the complete HTML document. Consult the Dojo documentation for further details.
216
AJAX-Enabling Portlets
Auto-Completing a Textbox
The following example illustrates providing immediate feedback based on what is entered into a textbox, without any explicit button interaction.
<% // Create the AJAX URL PortletURL ajaxURL = renderResponse.createActionURL(); WindowState windowState = new WindowState("raw"); ajaxURL.setWindowState(windowState); // Declare namespace variables String nameSpace = renderResponse.getNamespace(); String formName = nameSpace +".myForm"; String inputName = nameSpace +".myInput"; String callbackFunction = nameSpace +".doAutoCompleteCallback"; %> <form name="<%=formName%>" action=<%=ajaxURL.toString()%> method="POST"... > <input type="text" size="20" autocomplete="off" name="<%=inputName%>" onkeyup="new VignettePortal.AJAXClient().sendForm(document .forms[formToSubmit],callbackFunction);return false" /> </form> <script language="JavaScript"> function callbackFunction(req) { var responseText=req.responseText; // code to update DOM in browser } </script>
Handling Errors
AJAX request error-handling follows the same pattern as handling any other Java standard portlet error conditions: Ensure that your portlets gracefully recover from AJAX errors and display appropriate messages in the portlet window.
217
AJAX-Enabling Portlets
218
10
Summary: Audience: Topics:
Deployment Overview (below) Using the Vignette Portal Portlet Packaging Tool on page 221 Enabling Direct Requests to a Portlet Application on page 224
Deployment Overview
Under Vignette Portal, portlets are deployed as web applications that are separate from the Portal web application (see Figure 48). Portal uses the application servers standard WAR deployment procedure. Before the first deployment of a portlet application, its web.xml file must be modified to enable Portal to access and manage the portlet or portlets that the application contains. Portal includes a tool that performs this modification.
Figure 48: Separate Portal and Portlet Web Applications
Application Server
portal user
219
Deployment Overview
Here is the sequence of events required to develop and deploy a portlet into Vignette Portal:
1 2
The developer prepares the portlet application files. The output from this step can be a WAR file, an EAR file, or exploded WAR files. The developer runs the Portal Portlet Packaging Tool, which prepares the portlet application for use with Portal. If the portlet application was archived, the packaging tool rearchives it after applying the modifications. The developer or deployment manager deploys the portlet application to the application server, supplying the applications context root. This step uses the application servers normal deployment feature. When the portlet application is started, the portlet appears in the Portal administration consoles. The Portal Portlet Packaging Tool needs to be run only once; if the portlet application is modified and redeployed, the tool does not need to be re-run.
This process is summarized for WAR and EAR files in Figure 49, and for exploded WAR files in Figure 50.
Figure 49: Deploying a Portlet from a WAR or EAR File
Develop portlet.
Application Server Portlet application (WAR or EAR) Portal-ready Portlet WAR or EAR
220
Figure 50:
Modify portlet application on filesystem. JSP changes take effect immediately. Java class and web.xml configuration changes take effect on portlet application restart.
Portal supports hot deployment and redeployment: portlets can be deployed and replaced without requiring a server restart. Deployment can occur with Portal running or not. Once deployed, the portlet application can be started and stopped independently from Portal, whether or not Portal is running at the time.
221
The packaging tool is an Ant task that adds the information required by Portal to a portlet applications web.xml file. For the simplest casedeploying one portlet applicationyou can use a script that ships with Portal; for access to all of the tools features, you can create your own Ant build file. The Ant task can be incorporated into your existing build processes so that running the packaging tool is a seamless part of development.
Create a WAR file for the portlet application, and place the WAR file in the PortalInstallDir/ant/examples/portletpackagetool/myportlet directory. Make PortalInstallDir/ant/bin the current directory. Run generic_portletpackagetool.bat (Windows) or generic_portletpackagetool.sh (UNIX), supplying the portlet applications context root as a command-line argument. When prompted, enter the WAR file name (including the .WAR extension). When prompted, enter the portlet applications context root. NOTE: If the context root is the name of the WAR file minus the .WAR extension, some application servers allow you to simply press Enter in response to this prompt; others require you to type the context root. The packaging tool explodes the WAR file, modifies web.xml, and recreates the WAR file.
2 3
4 5
Deploy the WAR file to the application server. NOTE: Be sure to supply the same context root when deploying the WAR file as you specified when running the packaging script.
222
deployment. The task can package one or more WAR files, exploded WAR files, and EAR files. In the following example, the build file runs the tool against /dev/portlets/to_deploy/MyPortlets.ear and places the output in /dev/portlets/to_deploy/repackaged. If the destination directory already contains MyPortlets.ear, the existing file will be overwritten with the new one. (Note that in this example, it is not necessary to specify the context root; the tool extracts that information from the EARs application.xml file.)
<?xml version="1.0" encoding="UTF-8"?> <project name="repackage_portlets" default="run" basedir="/dev/portlets/to_deploy"> <taskdef name="PortletPackageTool" classname="com.vignette.portal.ant.external. portlet.PackageTask"/> <target name="run"> <record name="portlet_package_log.txt" loglevel="info"/> <PortletPackageTool file="MyPortlets.ear" destdir="repackaged" rename="false"> </PortletPackageTool> </target> </project> See also:
PortalInstallDir/ant/doc for complete documentation of the packaging tool elements and attributes PortalInstallDir/ant/examples/portletpackagetool for additional examples of Ant build files
Portal
Security filter that blocks unauthorized requests to the portlet application
223
will be deployed
There might be circumstances where it is necessary for certain resources to make direct requests. For example, the web application might include (in addition to one or more portlets) a servlet or JSP-based application. In such circumstances, you can edit web.xml to remove the Portal security filter (named PortletApplicationSecurityFilter) and mapping. CAUTION: Removing the security filter will allow any external client to access the web application without being authenticated or authorized by Vignette Portal. Also note that rerunning the Portal packaging tool will reinsert the security filter into the web.xml file.
224
11
Summary: Audience: Topics:
Portlet Modes
Vignette Portal supports the Java standard portlet modes shown inTable 18. According to the Java Portlet Specification, a mode controls the specific task that the portlet is to perform. For example, VIEW is the regular informational view of the portlet, whereas EDIT is the view that enables the end user to edit preferences.
Table 18: Mode VIEW Portlet Modes Supported by Vignette Portal Purpose Shows the main views of the portlet instance User Type End User and Administrator How accessed within Portal
End User: from all Portal displays other than EDIT and HELP Administrator: from the Preview tab of the server or site console
HELP
End User
From portlet chrome (a Portal UI element) or from a link provided in the portlet content (if portlet supports this mode)
225
Portlet Modes Supported by Vignette Portal (Continued) Purpose Allows an end user to customize read-write or modifiable preferences for the portlet Allows an administrator to configure read-only or nonmodifiable preferences for the portlet Allows an administrator to set defaults for read-write or modifiable preferences for the portlet Displays information about the portlet, such as version or vendor User Type End User How accessed within Portal From portlet chrome or from a link provided in the portlet content (if portlet supports this mode) Details tab of the server or site console
CONFIG
Administrator
EDIT_DEFAULTS
Administrator
ABOUT
Administrator
From a link within the Basics tab of the server or site console
Note that when a portlet is invoked in either CONFIG or EDIT_DEFAULTS mode, the preference values that are set will apply to all users of the portlet instance. As a result, an administrator can configure the portlet once for all users in the system. A user can then customize the portlet in EDIT mode, whereby the portlet container will store preference values on a per-user basis.
See also: Vignette Portal Administrators Guide for details about using the server and site consoles
226
portlet. These display elements are referred to as portlet chrome. By default, the portlet chrome includes buttons to switch to the other modes and window states. Whether a portlet displays with chrome depends upon settings within the Portal administration consoles. For the MAXIMIZED window state, a portlet includes chrome only when two conditions are met: it is so configured within the Portal administration consoles and the Portal property portlet.website.maximized.chromeless is set to false (which is the default setting for this property). NOTE: Portal does not auto-generate a "back" button; the portlet is responsible for providing such a link based on its previous mode and window state.
See also:
Chapter 2, Controlling Navigation and Appearance with Styles, for details about portlet chrome Vignette Portal Configuration Guide for details about the Portal properties file
The following code within the portlet sends a Word document for rendering:
WindowState currentWindowState = renderRequest.getWindowState(); if( currentWindowState.toString().equals("binary") { renderResponse.setContentType("application/msword"); byte[] b = new byte[1024];
227
FileInputStream fileInputStream = new FileInputStream("Test.doc"); int i; OutputStream portletOutputStream= renderResponse.getPortletOutputStream(); do { i = fileInputStream.read(b); portletOutputStream.write(b); } while (i != -1); portletOutputStream.flush(); }
Figure 52 illustrates a portlets inline display of an image. The portlets Submit button is to the VIEW mode, NORMAL window state. When the Submit button is clicked, Portal asks the portlet for markup, and the portlet responds by generating an image link (<img src="...">). The image URL is to the same portlet, BINARY window state:
PortletURL url = renderResponse.createRenderURL(); WindowState w = new WindowState("binary"); url.setWindowState(w); writer.write("<img src=\"" + url.toString() + "\">");
228
Figure 52:
Page 1
Page 2
Page 3
Portlet A
Stocks Portlet
Ticker Symbol:
Content
Submit
Page 1
Page 2
Page 3
Portlet A
Stocks Portlet
229
The POPUP_URL value is formed by creating a PortletURL, setting the window state to SOLO, and including an HTTP parameter of display=pastSearches. The mode is still VIEW.
Figure 53: SOLO Window State Example
Page 1
Page 2
Page 3
Portlet A
Search Portlet
Search For:
Content
Submit
Past Searches
Search Portlet
Select a past search: Portlet Spec Portal Documentation
Page 1
Page 2
Page 3
JSP Resources
Portlet A
Search Portlet
JSP Spec JSP Future Directions JSP References JSP Examples JSP & Servlets JSP Books JSP Tips
When the Past Searches link is clicked, Portal invokes the search portlet popup window in VIEW mode, SOLO window state, parameter display=pastSearches. The pop-up window displays links to past searches, while the parent Portal page stays as-is (it doesnt even refresh). When the user clicks one of the links in the pop-up window, the portlet itself, in the markup of the pop-up window, uses JavaScript to put the link selection in a hidden form field of the parent pages view of the portlet. The JavaScript
230
does the equivalent of clicking the Submit button on the form in that portlet view, refreshing the parent Portal page and then closing the pop-up window. At this point, the search portlet displays the results for the selected past search within the Portal page, and the other portlets on the page display with their preexisting state. NOTE: Use the getNamespace() method on PortletResponse to ensure the uniqueness of pop-up window names, JavaScript function names, form fields, and any HTML ID element that JavaScript will interact with. This practice prevents portlets on the same page from interfering with each other.
Page 1
Page 2
Page 3
Portlet A
Search Portlet
JSP Spec JSP Future Directions JSP References JSP Examples JSP & Servlets JSP Books JSP Tips
JSP Tips:
Tip 1: Lorem Ipsum torqueo loquor luptatum ut iriure commoveo ille. Duis sed jugis ideo in iriure te distineo nutus quibus torqueo. Tip 2: Nunc neque et
Content
Close Window
As with the SOLO example, the mode is VIEW and the links in the main view of the search portlet are coded with JavaScript to open the pop-up window. In this example, though, the portlet uses RAW window state to display a frameset
231
HTML document within the pop-up window. The top frame contains document controls, the middle frame displays the document content, and the bottom frame closes the window. Each frame tag includes a URL to get the content of that frame. The portlet generates these URLs with SOLO window state; as a result, Vignette Portalbefore calling the portlet to create the content for the framewrites out the <HTML> and <BODY> tags as well as the CSS. When the user clicks Close Window, the portlet itself, in the markup of the bottom frame, includes JavaScript that closes the pop-up window. The parent Portal page is never refreshed.
RAW should be used only when the portlet must generate the entire HTML document. Because it is a proprietary window state, RAW should not be used to
232
12
Summary: Audience: Topics: See also:
PortalBean Portlets
Describes Vignettes legacy (PortalBean) portlets and compares them to Java standard portlets; documents PortalBean enhancements and other changes since the introduction of Java standard portlets Portlet developers
Java Standard Portlets vs. PortalBean Portlets (below) Vignette Portal and the PortalBean Framework on page 234 AJAX-Enabling PortalBean Portlets on page 237 CAR Tool on page 241 <mod:i18nAlias> JSP Tag on page 242 Retiring a Prototype PortalBean on page 243
Chapter 7, Using the Site Development APIs, for discussion of the ways that portlets can be displayed on Portal pages
233
See also:
Chapter 9, Java Standard Portlets and Vignette Portal, for a description of how Portal works with Java standard portlets
Later sections of this chapter describe these enhancements. This section describes post-4.5 changes to Vignette Portal itself that affect the PortalBean framework. The remainder of the PortalBean documentation is in version 4.5 of the Vignette Application Portal Module Developers Guide.
See also:
Latest update to version 4.5 of the Vignette Application Portal Module Developers Guide for documentation of PortalBeans Appendix E, Compatibility with Version 4.x, for information about possible coding issues if you need to upgrade 4.x PortalBeans or other components to Portal 7.x
234
PortalBean Portlets
remote portlets; addition of remote portlet types; and instantiation, import, and export of all types of portlets.
See also: Vignette Portal Administrators Guide for details about using the Portal administration consoles
NOTE: The Web Services Manager was removed from version 7.0 of Portal, in favor of standards-based initiatives.
(Note that the third argument of createPortletURI() expects key/value pairs where the value is a string array.)
Minimizing Portlets
In version 4.x, PortalBean portlets used a MINIMIZABLE attribute within the PortalBean descriptor (PBD) file to control whether a portlet was minimizable by default, and the administration consoles exposed a Minimizable permission controlling the behavior per PortalBean instance. Now, MINIMIZED is one of the Java standard portlet window states, and the related functionality within the PortalBean framework has been deprecated. Methods on com.vignette.portal.portlet.website.PortletWindo wBean can get, set, and check whether the minimized window state is supported for a given portlet. Calls to these methods are now typically in the chrome style, which is responsible for rendering the portlet window and content within a portlet display page. Portal administrators can still prevent a particular portlet from being minimized by locking the page panel that contains the portlet. To prevent any
235
portlet from being minimized, you can remove the logic for the minimize button from the portlet chrome.
See also:
Chapter 2, Controlling Navigation and Appearance with Styles, for details about customizing portlet chrome Chapter 14, Users and Access Control, for discussion of checking portlet permissions Vignette Portal Administrators Guide for details about locking a portlet display page
alteration of proxied content. WebConnector 3.0 uses these two APIs. You can also use them for your own version of the WebConnector portlet or other custom portlets.
See also: Chapter 18, Remote Content Retrieval and Manipulation, for documentation of these two APIs
NOTE: The com.epicentric.common.WebData class should no longer be used for retrieving and manipulating remote content.
236
PortalBean Portlets
internationalization and localization, content search, usability, Section 508 compliance, administration, and other features. NOTE: Because of API changes, the Vignette Application Portal Module Developers Guide in some cases might not reflect current best practices. In addition, the tutorials within that guide might not work using currently supported operating system, application server, and JDK versions.
Technical Library on Vignette Connect (http://connect.vignette.com) for Portal API documentation (javadocs) as well as lists of version-to-version API changes
See also:
Name Changes
Table 19 lists global changes in product, feature, and file names. Note that the Vignette Application Portal Module Developers Guide refers to these items by their old names.
Table 19: Old Name Vignette Application Portal module epicentric.jar file epi_html tag namespace container page Name Changes Since Version 4.5 Current Name Vignette Portal PortalBean portlet vgn-portal-core.jar file vgn-portal tag namespace portlet display page
237
String nameSpace = view.getBean().getID(); String formName = nameSpace +".myForm"; String callbackFunction = nameSpace +".callbackFunction"; // more nameSpace declarations...
NOTE: In namespacing your functions, keep in mind that both pages and styles can include the same PortalBean instance, and therefore the same ID. Ensure that namespaces are unique in those scenarios. For those situations where a widget toolkit does not fit your use case ideally, the Portal AJAX Library is a convenient API providing an abstraction layer over the lower-level details. The Portal AJAX Librarys JavaScript functions are located at PortalInstallDir/portal/jslib/vapajaxlibrary.js. The following sections provide examples of the use of the library with PortalBean portlets.
See also:
Chapter 7, Using the Site Development APIs, for a description of the Portal AJAX library and general discussion of AJAX support within Vignette Portal Latest update to version 4.5 of the Vignette Application Portal Module Developers Guide for details about developing PortalBean portlets
This URL maps to a RAW view in the PortalBean descriptor (PBD file):
<VIEW ID="form-submit-response" USERLEVEL="guest" IS_NAVIGATION_ROOT="true" PREFERRED_PAGE_ID="raw" > </VIEW>
Each AJAX URL has its own view and mapping in the PBD file. Interacting with an AJAX URL invokes the portlet view and aggregates the markup without including the surrounding Portal accoutrements.
238
PortalBean Portlets
Note this examples use of the Portal AJAX Librarys sendForm() function.
239
type as multipart/form-data, and use the sendMultiPartForm() library function. This function supports text/plain, text/html, and text/javascript responses. Here is a multipart form example where the response is text/plain content (the default):
<form name="<%=formName%>" action="<%ajaxURL%>" enctype="multipart/form-data" onSubmit="new VignettePortal.AJAXClient().sendMultiPartForm (this,<%=callbackFunction%>);return false" method="POST"> <input type="file" name="fileContent"> ... </form>
For a text/html or text/javascript response, specify the response MIME type as wellfor example:
onSubmit="new VignettePortal.AJAXClient().sendMultiPartForm (this,<%=callbackFunction%>,text/html);return false"
The Portal AJAX Library uses an IFrame to achieve this functionality. As a result, the only reliable, cross-browser way of knowing when the response is loaded is by using an HTML document as the return type. For text/plain and text/javascript responses, the response must be within the first textarea of the response document. The library returns the contents of the textarea as the response to your callback function. For text/html responses, the callback functions parameter is the complete HTML document. Consult the Dojo documentation for further details.
Auto-Completing a Textbox
The following example illustrates providing immediate feedback based on what is entered into a textbox, without any explicit button interaction.
// Create the AJAX URL String ajaxURL = view.getBean().getFullViewURL("ajaxview", params); // Declare namespace variables // (beware of potential ID collisions) String nameSpace = view.getBean().getID(); String formName = nameSpace +".myForm"; String inputName = nameSpace +".myInput"; String callbackFunction = nameSpace +".doAutoCompleteCallback"; %>
240
PortalBean Portlets
CAR Tool
<form name="<%=formName%>" action=<%=ajaxURL%> method="POST"... > <input type="text" size="20" autocomplete="off" name="<%=inputName%>" onkeyup="new VignettePortal.AJAXClient().sendForm(document .forms[formToSubmit],callbackFunction);return false" /> </form> <script language="JavaScript"> function callbackFunction(req) { var responseText=req.responseText; // code to update DOM in browser } </script>
Handling Errors
AJAX request error-handling follows the same pattern as handling any other PortalBean error conditions: Your code should gracefully recover from AJAX errors and display appropriate messages in PortalBean views.
See also: Latest update to version 4.5 of the Vignette Application Portal Module Developers Guide for more about PortalBean error handling
CAR Tool
Portal ships with a CAR tool for building PortalBean CAR files. This tool packages all of the files for a PortalBean, optionally creates its component.xml file, and generates the CAR file.
241
The CAR tool is based on Ant and can accept either scripted or manual command-line inputs. You can integrate the tool into existing build scripts to automate the packaging of one or more PortalBeans.
See also: PortalInstallDir/ant/doc for complete documentation of the CAR tool and examples of its use
Alternatively, you can use <mod:i18nAlias> to create an alias for the unique ID for use by <mod:i18nValue/>, as follows:
<% Iterator iter = view.getModuleIterator(); while (iter.hasNext()) { PortalBean bean = (PortalBean)iter.next(); %> <mod:i18nAlias alias="bean" key="<%=bean.getUID() %>"> Title: <mod:i18nValue alias="bean" key="title" defaultValue="<%= bean.getTitle() %>"/>
242
PortalBean Portlets
Description: <mod:i18nValue alias="bean" key="description" defaultValue="<%= bean.getDescription() %>"/> </mod:i18nAlias> <% } %>
Typically, such a PortalBean is deployed only in a development, prototyping, or other non-production environment. In such environments, once a prototype PortalBean is obsolete you can retire it by simply deleting its files. However, such deletions can cause upgrade, database integrity, and cluster problems and therefore should not be performed on a production system. Instead, the recommended way to retire a prototype PortalBean is by adding the following <FIELD> element to its PBD file:
<FIELD NAME="obsolete" VALUE="true" TYPE="java.lang.Boolean" > </FIELD>
Add this element within the <DATA> element of the PBD file. The presence of this element removes the PortalBean from all lists within the administration consoles and end-user pages. It also removes any instances of the PortalBean from end-user pages. Note that this element works only in the case of PortalBeans that use JSPBean and JSPView. PortalBeans having their own PortalBean and PortalBeanView classes can be retired by overriding the isObsolete()
243
method in its PortalBean class, recompiling the class, creating a new CAR file, and deploying the new CAR file.
See also: Vignette Application Portal Module Developers Guide for documentation of the other elements of the PortalBean descriptor as well as details about prototyping, creating production-quality PortalBeans, and retiring production-quality PortalBeans
244
PortalBean Portlets
13
Summary: Audience: Topics: Table 20: Service MetaStore
Available Portal Services (below) Storing Data in the MetaStore on page 250 Services API on page 251
Store serializable data Create a hierarchy of folders containing documents or other folders Assign properties to documents and folders
Storing Data in the MetaStore on page 250 Vignette Portal Configuration Guide for further information about configuring and using the MetaStore
247
User management
Programmatically access users and user groups Customize the information collected about users Configure and customize the back-end systems that store the user data Use the Portal administration consoles to access and maintain user and user group data
Chapter 14, Users and Access Control, for information about the user and user group access APIs Chapter 4, Controlling Functionality with Secondary Pages, for information about customizing secondary pages such as the selfregistration and user account pages Vignette Portal Configuration Guide for details about customizing the user management back-end systems Vignette Portal Administrators Guide for details about using the administration consoles Chapter 14, Users and Access Control, for details about creating a custom authenticator Chapter 4, Controlling Functionality with Secondary Pages, for information about customizing secondary pages such as the login page Chapter 2, Controlling Navigation and Appearance with Styles, for an example of how to add login functionality to a style Vignette Portal Configuration Guide for details about configuring authentication Vignette Portal Administrators Guide for details about guest access Chapter 14, Users and Access Control, for a list of permissionchecking methods Vignette Portal Administrators Guide for details about setting permissions on various Portal objects
Authentication
Create a custom authentication mechanism Customize how users log in to your portal Configure one of the supplied authentication mechanisms (SQL, NT, LDAP, or single sign-on) and how it works with the user management system Configure guest access
Authorization
Programmatically check Portal access permissions that a particular user or user group has Set Portal access permissions
248
Programmatically use or customize the Portal caching system Configure the Portal caching system Collect custom metrics about Portal usage Configure the metrics system
Chapter 15, Caching, for details about the caching API Vignette Portal Configuration Guide for information about using the Portal properties file to configure caching Chapter 16, Metrics, for details about implementing custom metrics Vignette Portal Configuration Guide for information about using the Portal properties file to configure metrics Chapter 17, Connection Pooling, for details about using the Portal connection pooling API Vignette Portal Configuration Guide for details about connection pool configuration options and best practices Chapter 18, Remote Content Retrieval and Manipulation, for details about retrieving, inspecting, and altering remote content, as well as about customizing WebConnector Vignette Portal WebConnector Administrators Guide for details about instantiating and configuring WebConnector portlets Chapter 19, Customizing Federated Search, for details about using the Federated Search API Vignette Portal Administrators Guide for details about configuring and using the Federated Search portlet
Metrics
Connection Pooling
Programmatically initialize and use Portal connection pools Configure the Portal connection pooling system
Programmatically retrieve content from remote sources Inspect and alter proxied content Customize the way the WebConnector portlet handles remote content Use the WebConnector portlet Programmatically integrate external content repositories into federated searches Develop custom search functionality Configure the out-of-thebox Federated Search portlet
Federated Search
249
Develop custom content management applications Develop connectors between Portal and thirdparty content management systems Customize the way the Story Publisher portlet renders content Use CAM portlets shipped with Portal
Chapter 20, Using the Content Access Management and Indexing APIs, for details about developing content management applications, connectors, and custom Story Publisher renderers Vignette Portal Content Access Management Administrators Guide for details about instantiating and configuring CAM portlets
250
Services API
If your company has more than one component or service that uses the MetaStore to store global information, one folder for each should be placed within the company-specific folderfor example:
/vendor/domain_name/service_name
In general, complex Java objects (such as data tables) should be stored as MetaStoreDocument objects, whereas frequently accessed string-based data (such as boolean values) can be stored as folder properties. To improve data retrieval efficiency, avoid storing multiple properties; combine them into a data object, then store that object as a document. Another storage technique is to store frequently accessed data in the user session, saving values to the MetaStore only when session values are committed (when users update data).
See also: Vignette Portal Configuration Guide for information about configuring the MetaStore
Services API
The Vignette Portal Services API supports the development of custom servicesfor example, a connector to a search engine, a new persistence mechanism, or a method of accessing a back-end information system. Services can be exposed through the Service Manager of the server console, thereby enabling Portal server administrators to configure them through a consistent user interface. The Services API is capabilities-based. When you develop a custom service, you have the option of delegating configuration to the Service Manager. You can also specify your services default configuration.
See also: Chapter 21, Developing and Deploying Custom Services, for details about custom services
251
Services API
252
14
Summary: Audience: Topics:
Introduction (below) User Management on page 253 Authentication on page 260 Authorization on page 267
Introduction
This chapter addresses three related but distinct topics:
The Portal user management system, which is responsible for storing data
about registered Portal users and the user groups they belong to
The Portal authentication system, which uses a customizable login process
User Management
The Portal user management system provides access to the data for Portal users and user groups. Data can be persisted in a SQL database, an LDAP directory server, or a combination of the two. Portal supports two types of users: registered and guest.
253
User Management
Registered users are those who have accounts (also known as user profiles)
in the user data store. Registered users can be preloaded from an external data store or added through the Portal administration consoles. In addition, Portal administrators have the option of allowing visitors to self-register for one or more sites.
Guest users are visitors to a Portal site who either do not have user accounts
or who are not currently logged in. Each guest can specify his or her preferred language; this preference is stored in a cookie for use in subsequent sessions. All guests have access to the same, configurable set of site features. Guest access can be disallowed globally or at the individual site level. A user group is a collection of users. Typically, members of a user group have something in common: a job role, a geographical area, an interest, or whatever other grouping is meaningful for a site. A Portal site has two main types of user groups:
Standard groups are those created and managed by Portal administrators. A
standard user can belong to any number of standard groups. These groups typically mirror an organization chart (Marketing, Sales, Human Resources, for example) or portal interest groups (NFL, NBA, PGA, and so on). Portal administrators can delegate specific server and site administration functions to standard groups.
System groups are internally created and managed by Portal; you cannot
Registered Users is the parent of all standard users. All users who can log into Portal are members of this group. Everyone is the parent of the Registered Users system group and also includes guest users. Standard maintains the list of site administrators, who are users who have access to all of the functionality provided by the Portal site console for one or more sites. Each Portal site has a standard system group, which is automatically created when the site is created. Admin maintains the list of all Portal server administrators, who are users who have access to all of the functionality provided by the Portal server console.
User groups are hierarchical: a group can be designated as a child of any number of groups, which in turn can be children of other groups. User groups have parent relationships with users and can have either parent or child
254
User Management
relationships with other user groups; users have child relationships with user groups. ("Parent" and "child" simply denote a membership relationship.) User groups are also additive: a single user can belong to any number of user groups and has the combined access rights of all of the groups to which he or she belongs. The com.epicentric.user package implements the Portal user management layer. Portal users and user groups are backed by com.epicentric.entity.Entity objects. An entity is an object that has configurable properties and is uniquely identifiable (users and user groups are the only types of entities supported at this time). Entity properties are defined in a configuration file named entity_management.xml.
See also:
Vignette Portal Configuration Guide for details about configuring the Portal user management system Vignette Portal Administrators Guide for details about managing users and user groups through the Portal administration consoles
In addition, Portal has a custom JSP tag, <vgn-portal:inSegment>, that supports dynamic, rules-based classification of users. This section provides a few examples of the uses of these APIs.
See also: Chapter 7, Using the Site Development APIs, for more about user-related APIs
255
User Management
Another way to retrieve a user is by querying the UserManager instance for a particular user property (as defined in the entity configuration file):
UserManager userManager = UserManager.getInstance(); try{ User userToGet = userManager.getUser("email", "sample@company.com"); }catch (EntityNotFoundException exception){ // The user was not found. }catch (EntityPersistenceException exception){ // Handle database error. }
You can get the user for a specified logon and realm using a convenience method on com.epicentric.common.website.EntityUtils:
User user = EntityUtils.getUserByLogonAndRealmID(logon, realmid);
256
User Management
Because users are entities, they have configurable properties. These properties vary according to entity type. To access information about the properties of a user, you must first get the user com.epicentric.entity.EntityType object:
EntityType userType = currentUser.getEntityType();
You can then query the entity type to retrieve the user property IDs:
Set propertyIDs = userType.getPropertyIDs();
To retrieve the value of a specific property, call getProperty(String propertyID) on the User object:
String firstName = (String)currentUser.getProperty("firstname");
Each property has a set of attributes, such as id, title, and description. Methods on com.epicentric.entity.EntityProperty enable you to access information about property attributes. An EntityProperty is a representation of one property. It acts as a property descriptor: it does not contain the value of the property but rather describes the property. You can get a list of property descriptors for the current user as shown in the following statement:
Iterator i = userType.propertyIterator();
A user segment is a dynamic categorization of users based on specified criteria. A user segment could be created for users whose Zip code or email address matches a particular pattern, who have a particular portal site as their primary site, who meet a combination of criteria, and so on. The <vgnportal:inSegment> custom JSP tag can be used to conditionally present content based on whether a user meets the criteria of a user segment. For example, a user segment whose friendly ID is customer_site could be used to display content that is appropriate only if the current user is a customer:
<vgn-portal:inSegment
257
User Management
friendlyID="customer_site"> <%-- customer-specific content... --%> </vgn-portal:inSegment> See also: Vignette Portal Administrators Guide for details about using the administration consoles to set up user segments
A user group, like a user, can be retrieved from the UIDRegistry. In addition, the com.epicentric.user.UserGroupManager class has user group accessor methods:
getUserGroup(String propertyID, Object propertyValue) getUserGroups(String propertyID, Object propertyValue) getAllUserGroups() Retrieving User Group Properties
You can use the EntityType class to retrieve the property IDs for a user group as well as to retrieve the value of a particular property using its property ID. You can also use the EntityProperty to get a list of property descriptors or the value of a particular attribute. For example:
EntityType userGroupType = userGroup.getEntityType(); // Get the groups property IDs. Set propertyIDs = userGroupType.getPropertyIDs(); // Get the list of property descriptors for the user group. Iterator i = userGroupType.propertyIterator(); // Get the value of the title property. String title = (String)userGroup.getProperty("title"); // Check if the title is read-only. EntityProperty titleProperty = userGroupType.getProperty("title"); boolean canEdit = titleProperty.isEditable();
258
User Management
A user group can return the set of all children of one entity type (either users or user groups). This set can be either immediate children or recursive. The following example gets users that are immediate members of a particular user group:
EntityType userType = UserManager.getInstance().getUserEntityType(); try{ Set users = userGroup.getChildren(userType, false); }catch (EntityPersistenceException exception){ // Handle exception. }
You can also get all of the parents of a particular user group (recursively, in this example):
try{ Set parentUserGroups = userGroup.getParents(userGroup.getEntityType(), true); }catch (EntityPersistenceException exception){ // Handle exception. }
Conversely, you can check a users group membership. The following example gets the immediate user groups that the current user belongs to and checks whether groupA is an immediate parent for the current user:
EntityType userGroupType = UserGroupManager.getInstance() .getUserGroupEntityType(); try{ Set userGroups = currentUser.getParents(userGroupType, false); }catch (EntityPersistenceException exception){ // Handle exception. } try{ boolean isMember = currentUser.hasParent(groupA, false); }catch (EntityPersistenceException exception){ // Handle exception. }
259
Authentication
Authentication
Portal provides configurable authentication of users against a data source. As users log on, Portal determines whether they have permission to access the portal by checking the information provided (typically, user name and password). If guest access is enabled for a site, Portal can also provide guest users with a configurable level of access to that site. During the authentication process, Portal uses an authenticatora Java class that manages authentication for a specific data sourceto validate the login information. Portal ships with a number of authenticator implementations, such as for authenticating against a SQL database, a Windows domain, and an LDAP directory. In addition, you can create custom authenticators as described in the following pages. One Portal custom JSP tag, <vgn-portal:realmSelector/>, is related to authentication. This tag displays a control enabling a user to select from a list of available realms.
See also:
Appendix A, Vignette Portal Custom JSP Tag Reference, for details about the <vgn-portal:realmSelector/> tag Vignette Portal Configuration Guide for information about configuring the authenticators that ship with Portal
260
Authentication
source or product
Extending GenericAuthenticator Defining the authenticator in a configuration file (authentication.xml)
This section explains how to perform these steps to implement a very simple custom authenticator: one that authenticates against a flat file and does not support some of the features of the Authentication API (password changes, account creation, account removal, or retrieval of forgotten passwords).
Preparing the Authentication Source
Ordinarily, a custom authenticator would work with third-party authentication software, such as a single-sign-on or other security product. This software would need to be installed and configured according to the instructions from the vendor. For this simple example, the custom authenticator is instead a flat file storing one user name and password per line, in the format username, password. (The custom authenticator will use the space as its parsing token, so user names and passwords cannot contain spaces.) If a user has an authentication record (in this flat file) but no user record (in the user data store used by Portal), the user will be able to log on to Portal but then will be presented with the registration page. This page enables users to add themselves to the user data store (assuming that the site allows selfregistration). NOTE: To ensure that at least one Vignette Portal administrator has both an authentication account and a user account, the flat file should include the administrator user name and password that were provided during Portal installation. This user account is used to create the initial Portal administrator record in the user data store.
Extending the GenericAuthenticator Class
GenericAuthenticator is an abstract class that implements the Authenticator interface to provide the basic functionality that
261
Authentication
authentication features are added in future versions of Portal, custom authenticators should extend GenericAuthenticator rather than implement Authenticator directly. A GenericAuthenticator subclass needs to implement the following methods (which are part of the Authenticator interface but are not implemented by GenericAuthenticator):
getID()
An authenticator must have a unique ID. Often, the simplest way to get a unique authenticator ID is to return the realm ID.
getName()
An authenticator also has a name associated with it. The name does not need to be unique.
init()
Every authenticator must implement an initialization method, which is run on first startup and after each restart of the Portal web application. This method is responsible for passing initialization properties into the authenticator before it is used, for loading information from the data source, and for initializing the realm for the authenticator.
authenticate(String logon, String password)
This method supports the core purpose of an authenticator. Every authenticator must have its own implementation of this method. NOTE: authenticate(String logon, String password, String domain) is a second, deprecated authentication method. It should be implemented simply to call the two-parameter method. In addition to implementing the above methods, a GenericAuthenticator subclass needs to override any of the capability methods that the authentication mechanism supports. These methods all have stub implementations in GenericAuthenticator that simply throw a "notsupported" exception:
doesAccountExist(String logon) changePassword(String logon, String newPassword) createAccount(String logon, String password, Map attributes) removeAccount(String logon) retrieveForgottenPassword(String logon)
For this example, only the doesAccountExist(String logon) method needs to be overridden.
262
Authentication
263
Authentication
* Overrides a deprecated method. * Redirects to the two-parameter method. */ public void authenticate(String logon, String password, String domain) throws AuthenticationException { authenticate(logon, password); } /** * Checks the supplied logon against the users Hashmap. */ public boolean doesAccountExist(String logon) { return users.containsKey(logon); } /** * Uses the realm ID as this authenticators unique ID. */ public String getID() { return realm.getID(); } /** * Uses this authenticators unique ID as the authenticator * name. */ public String getName() { return getID(); } /** * Performs authenticator initialization. * @param realm This authenticators Realm * @param props Properties for initialization (set in * XML file) */ public void init(Realm realm, Properties props) throws AuthenticationException { this.realm = realm; users = new HashMap(); // Gets location of flat file String filename = props.getProperty("filename"); File file = new File(filename); if (file.exists()) { try { // Reads in flat file contents FileReader fr = new FileReader(file); BufferedReader reader = new BufferedReader(fr); String nextline; while ((nextline = reader.readLine()) != null) {
264
Authentication
try { StringTokenizer tokens = new StringTokenizer(nextline, " ,"); users.put(tokens.nextToken(), tokens.nextToken()); LOG.debug("FileAuthenticator: Reading user."); } catch (NoSuchElementException nseex) { LOG.warning("FileAuthenticator: Cant read user."); } } } catch (FileNotFoundException fnfex) { // Since we check for file.exists(), this should // never happen. LOG.error("FileAuthenticator file not found: "+filename); } catch (IOException ioex) { LOG.error("FileAuthenticator exception while reading file: "+filename, ioex); } } else { throw new AuthenticationException("FileAuthenticator file not found: "+filename); } } }
The authentication.xml file defines each authenticator for a Portal installation. This file is in the config subdirectory of the Portal installation directory. The following XML shows the section of authentication.xml that supports this flat-file example:
<!-- Example Realm (also the Default Realm) --> <REALM id="File" title="Flat-File Example Realm" description="Flat-File Example Realm Description" self-register-description="Flat-File Example Realm SelfRegister Description" default="true" > <!-- Custom authenticator for flat-file data source --> <AUTHENTICATOR class="com.yourcompany.authentication.FileAuthenticator"
265
Authentication
authenticate="true" create-account="false" remove-account="false" retrieve-forgotten-password="false" change-password="false" does-account-exist="true"> <PROPERTYLIST> <!-- Location of flat file --> <PROPERTY name="filename" value="D:/Vignette/Portal/demos/authentication/ users.txt" /> </PROPERTYLIST> <ACCOUNT-TYPE-DESCRIPTOR> <ACCOUNT-PROPERTY-DESCRIPTOR id="username" title="Username" description="Username" data-type="java.lang.String" max-size="64" datasource-field="user_name" /> <ACCOUNT-PROPERTY-DESCRIPTOR id="password" title="Password" description="Password" data-type="java.lang.String" max-size="32" datasource-field="password" /> <ACCOUNT-PROPERTY-ALIAS alias="logon" property-id="username" /> </ACCOUNT-TYPE-DESCRIPTOR> </AUTHENTICATOR> </REALM>
Note that the above XML defines a REALM element for this example. The id attribute must be unique for each realm in authentication.xml and should help distinguish this realm from other realms. The id attribute can be any String value, but it should start with an alpha (not numeric or symbolic) character. The title attribute is the display text for the realm.
AUTHENTICATOR is a child element of REALM defining the authentication mechanism. The class attribute is the fully qualified class name for the authenticator class. The authenticate attribute must be set to true for the authenticator to be able to perform authentication. For this example, doesaccount-exist is the only other attribute that should be set to true, since
266
Authorization
this is the only other capability supported by the flat-file authentication mechanism.
PROPERTYLIST is a child element of AUTHENTICATOR. It can have any number of PROPERTY child elements, each of which has two attributes: name and value. For this example, only one PROPERTY needs to be defined. It
that provides the mapping to authentication information contained in the data source. Each piece of information is a child element of ACCOUNT-TYPEDESCRIPTOR named ACCOUNT-PROPERTY-DESCRIPTOR. For the example, two pieces of information in the flat file provide the authentication information: username and password.
ACCOUNT-PROPERTY-ALIAS enables aliasing of an account property. For the example, logon is aliased to the username property; the effect is that users will log on by entering their name. The Authentication API requires there to be either a logon property or (as in this example) a logon alias. The only alias that is supported is logon, except in the case of JNDI authentication, which supports a second alias: rdn. Any other aliases defined in the authentication.xml file are simply ignored.
See also: Vignette Portal Configuration Guide for further documentation of the authentication.xml elements and attributes
Authorization
Portal controls access privileges through permissions. Server and site administrator permissions are granted to individual users; end-user permissions are granted to user groups. In addition, server and site administrators can delegate many administrative functions to user groups. Permissions are set only through the administration consoles, but you can programmatically check various types of permissions using methods on the following classes:
267
Authorization
isEditModeAllowed() on PortletWindowBean isHelpModeAllowed() on PortletWindowBean isViewModeAllowed() on PortletWindowBean isMaximizedStateAllowed() on PortletWindowBean isMinimizedStateAllowed() on PortletWindowBean isNormalStateAllowed() on PortletWindowBean isAuthorizedUser() on SessionInfo isAdminUser() on SessionInfo EndUserUtils.isUserAuthorized(User user, Site site) isSystemAdministrator() on User isAdminUser() on SessionInfo EndUserUtils.canUserAcessSiteConsole(User user, Site site) EndUserUtils.canUserAcessSystemConsole(User user, Site site)
Site
Administrative
(Note that the portlet-checking methods listed in Table 21 actually check the current users permissions as well as all of the other factors that determine the portlet modes and window states enabled for a particular portlet and request, such as what modes and window states the portlet itself supports.) Because user group membership is additive, a particular user has the combined access rights of all of the groups to which that user belongs plus all of the groups that are direct or indirect parents. Portal also includes a number of ways to control access to specific objects, rather than to users and user groups. For example, a site can be enabled or disabled through the Portal site console, and the setting can be checked through the isEnabled() method on the com.epicentric.site.Site object. The Portal site console also controls whether the My Pages feature is turned on, and the setting can be checked through
com.epicentric.mypage.MyPageList .isEnabledForSite(Site site).
268
15
Summary Audience: Topics:
Caching
Describes the Vignette Portal caching system and provides examples of how to use and customize it Java developers responsible for customizing Vignette Portal
The Vignette Portal Caching System (below) Caching Examples on page 272
single JVM) or a distributed environment (where caching is synchronized across multiple JVMs within a cluster)
See also: Technical Library on Vignette Connect (http://connect.vignette.com) for API documentation (javadocs) of the com.vignette.portal.cache package
269
Caching Strategies
A set of "strategies," represented by the CacheStrategy class, drives the way a cache acts. Vignette has implemented a number of strategies. For most cases, you can use these strategies rather than having to build your own. The caching system has three classifications of strategy:
Time-based strategies are driven by the passage of time. They map to
Hard: Guarantees that the cache will never have more items than it has been configured to allow, expiring items as new ones are added. A hard size-based strategy is typically used only when strict size management is of utmost importance. Soft: Allows the total to grow beyond the configured maximum size, but periodically trims the cache back to the upper limit. Due to thread safety issues, the soft variety is more efficient during normal cache operations, and therefore is generally the one used for size-based strategies.
Other strategies include the BroadcastingStrategy for synchronization across the cluster, MonitoringStrategy for caching usage metrics, and
any custom strategies. Table 22 lists and describes the strategies that are provided.
Table 22: Type Timebased Strategy Classifications Description Supports expiration based on how long an object has been in the cache. Supports expiration of an object if it has not been accessed for a particular length of time. Supports expiration of objects based on size, expiring those added first over those added later. Supports expiration of objects based on size, expiring those accessed least recently over those accessed more recently.
Sizebased
FirstInFirstOutStrategy
LeastRecentlyUsedStrategy
270
Caching
Strategy Classifications (Continued) Description Sends invalidation messages to other nodes in the cluster. Allows monitoring of events sent to the strategies; typically not used in production environments.
Most of the provided caching strategies extend ActionBasedCacheStrategy, which supports a choice of function for invoking their expiring action. The default is traditional expiration: the expired object is removed from the cache.
Passivation
One alternative to the default expiration action is passivation, which is implemented by the PassivatingCacheAction class. Passivation is the removal of a cache value from memory to some external location, thereby reducing the memory usage but not losing the cached value. If the cached value is requested from the cache, the PassivatingCacheAction reloads it. A PassivationStorageHandler, provided to the PassivatingCacheAction on construction, determines where the PassivatingCacheAction stores the value while passivated. Portal includes a simple storage handler implementation (FileSerializingPassivationStorageHandler), which serializes the value of the object in a temporary file. Of course, this implementation requires that the value be serializable.
Distributed Caching
Managing a cache across a cluster can be accomplished in one of two ways: cache clearing or cache loading. Cache clearing is the process of invalidating a value in all caches if the value changes. The classic use case for cache clearing is to invalidate the local cache when a cached object is saved after an update, thereby forcing the cache to reload the value the next time it is requested. If the broadcasting strategy is used, it will broadcast the invalidation message to the other nodes, ensuring
271
Caching Examples
that they also remove the object from memory and forcing them to reload when the object is next requested. Cache loading automatically adds a value to other caches when the value is added to one cache. The caching system, as shipped, does not support cache loading for two reasons: in many cases only one node in the cluster needs the data; and due to the asynchronous nature of communications via the broadcaster, a race condition could occur, resulting in the wrong value in the cache.
Caching Examples
This section provides four caching examples:
Simplest Case Using Multiple Strategies Using a Broadcasting Strategy Using a Custom Cache Data Source
Simplest Case
Suppose that you want to cache all Widget objects and expire them after 20 minutes has elapsed since last modification. This behavior can be defined using a single strategy: TimeToLiveStrategy. First, initialize the cache:
// Get the CacheFactory PortalInitialContext context = new PortalInitialContext(); CacheFactory factory = (CacheFactory)context.lookup(CacheFac tory.CONTEXT_URI); // Create the TimeToLiveStrategy TimeToLiveStrategy strategy = new TimeToLiveStrategy(20*60*1000); List strategies = Collections.singletonList(strategy); // Create a Cache try { Cache widgetCache = factory.createCache( "com.companyname.widget.widgetcache", strategies); } catch (CacheAlreadyExistsException caee) { // Handle error . . . }
272
Caching
Caching Examples
if (widget != null) { try { widgetCache.put(widgetID, widget); } catch (CacheException ce) { // Handle error . . . } }
Alternatively, you can use the three-parameter form of the put() method to specify the expiration time for the object when caching it:
if (widget != null) { long timeToLive = 90*60*1000; Map properties = new HashMap(); properties.put(strategy.getOverrideTimeoutProperty(), new Long(timeToLive)); try { widgetCache.put(widgetID, widget, properties); } catch (CacheException ce) { // Handle error . . . } }
Note that the override key is specific to the strategy. As a result, if you have multiple strategies the override can be provided to the right one. To retrieve an object, use the get() method of the Cache:
try { Widget widget = (Widget)widgetCache.get(widgetID); } catch (CacheException ce) { // Handle error . . . }
Finally, if appropriate use the invalidate() method of the Cache to clear it (for example, when deleting an object):
if (widget != null) { widget.delete(); try { widgetCache.invalidate(widgetID); } catch (CacheException ce) { // Handle error . . . } }
(If you dont use the invalidate() method, the cache will automatically expire the object after the expiration time has elapsed.)
273
Caching Examples
It is possible to add a strategy that negates the function of another strategy for example, two time-to-live strategies where one expires faster than another. You can also have two time-until-unused strategies that complement each otherfor example, one passivating after five minutes and the other expiring after an hour. IMPORTANT: Never have more than one passivation strategy in a cache, as this practice would confuse the state of the cache.
This method throws an exception if there is no broadcaster defined for Portal (so it is highly unlikely that you will ever have such a problem).
274
Caching
Caching Examples
You also need to supply the CacheDataSource implementation to the createCache() method:
try { Cache widgetCache = factory.createCache("com.mycom pany.widget.widgetcache", strategies, new WidgetCacheDataSource()); } catch (CacheAlreadyExistsException caee) { // Handle error . . . }
Whenever the data store is updated, you must clear the contents of the cache:
// UPDATE, INSERT, or DELETE operation here widgetCache.invalidate(widgetID);
275
Caching Examples
The get() method of the Cache looks for the requested object in the cache and returns it if found. If the object is not in the cache, the caching system calls the load() method of the objects CacheDataSource. The load() method retrieves the requested object from the external data store. The caching system returns the requested object to the caller of the get() method and places it in the cache.
With a custom cache data source, the get() method of the Cache will never return null.
276
Caching
16
Summary: Audience: Topics:
Metrics
Explains how to use the Portal metrics system Java developers responsible for customizing Vignette Portal
The Vignette Portal Metrics System (below) First-Time Database and Connection Pool Setup on page 278 Creating a Custom Metric on page 280 Using Table Aliases on page 284 Metrics Code Example on page 286
277
This chapter explains how to use the metrics system to gather your own usage data.
See also: Portal Developer Community of Vignette Connect (http://connect.vignette.com) to download the Portal Metrics Viewer application template
After creating the metrics database and XML file, create the tables in the metrics database by running table_installer.bat for Windows or table_installer.sh for UNIX (in the bin subdirectory of the Portal installation directory). Enter the name of your new XML file in the Table
278
Metrics
Definition File field, complete the database connection fields to connect to the metrics database, and click Go.
See also: Vignette On-Line Support System (http://support.vignette.com) for the Portal release notes, which list the databases that Portal supports for each platform
Add metrics database connection properties to the Portal configuration file (PortalInstallDir/config/properties.txt). For example, for an Oracle database, the values of these properties might be something like this:
metrics.db.driver=oracle.jdbc.driver.OracleDriver metrics.db.url=jdbc:oracle:thin:@PortalHost:1521:ORCL metrics.db.user=portal metrics.db.password=portal To define the connection pool for the metrics database:
Add connection pool properties to the Portal configuration filefor example (where PortalMetrics corresponds to the name of the connection pool):
connectionpool.PortalMetrics.code=com.epicentric.jdbc.Connect ionPoolService connectionpool.PortalMetrics.db=metrics.db connectionpool.PortalMetrics.name=MetricsConnectionPool connectionpool.PortalMetrics.description=Connection Pool for Portal Metrics DB To configure the metrics system: 1
Find these properties in the METRICS section of the Portal configuration file:
metrics.log.connectionpool=default metrics.archive.connectionpool=default
279
Replace the default values from the previous step with the name of the metrics connection pool that you createdfor example:
metrics.log.connectionpool=PortalMetrics metrics.archive.connectionpool=PortalMetrics
Check the values for the other properties in the METRICS section to ensure that they are appropriate for your installation.
See also:
Chapter 17, Connection Pooling, for documentation of the Portal connection pooling API Vignette Portal Configuration Guide for more about defining database connections, creating connection pools, and setting additional connection pool properties
Defining the metric in an XML file named mbeans.xml Adding a table to the metrics database for archival of metrics data Making calls to the Portal metrics API to record the metric
280
Metrics
<mbean> Element
Category of metrics to be collected, such as page, portlet view, or user usage. ATTRIBUTES:
name
Name for the mbean; must be unique across all mbean names. Required attribute. Example: com.companyname.metrics.portlets
name-space
Table name where the mbean data is to be collected. For portability across databases, the table name should be all lower case and must not contain spaces. Required attribute. Example: portletviews
key
Primary key for the table identified in name-space. For portability across databases, the key should be all lower case and must not contain spaces. Required attribute. Example: userid
<attribute-integer/> Element
Child element of mbean for collecting integer data. An mbean can have zero or more of these elements. ATTRIBUTES:
name
Name for the attribute-integer; must be unique for the parent mbean. For portability across databases, the name should be all lower case and must not contain spaces. Required attribute. Example: pagehits
method
Type of value to be stored in the attribute-integer; must be either Incremental (if the stored value is to be incremented) or Overwritten (if the stored value is to be overwritten by a new, specified value). Required attribute.
<attribute-string/> Element
Child element of mbean for collecting string data. An mbean can have zero or more of these elements.
281
ATTRIBUTE:
name
Name for the attribute-string; must be unique for the parent mbean. For portability across databases, the name should be all lower case and must not contain spaces. Required attribute. Example:
username
<attribute-date/> Element
Child element of mbean for recording dates. An mbean can have zero or more of these elements. ATTRIBUTE:
name
Name for the attribute-date; must be unique for the parent mbean. For portability across databases, the name should be all lower case and must not contain spaces. Required attribute. Example: last_hit
282
Metrics
<tablegroup name="metrics archive" java-package="com.epicentric.metrics.archive"> <!-- Portal log tables go here --> </tablegroup> <tablegroup name="custom metrics"> <comment> Custom metrics archive tables </comment> <!-- add custom tables here --> </tablegroup> </schema>
To use aliases for table and/or column names (explained in Using Table Aliases on page 284), a separate XML file (metrics_map.xml) must be modified to contain the mappings; otherwise (if you do not map aliases), each metrics table must have the following relationships to mbeans.xml elements:
The table name must match the name-space attribute of the mbean
element.
The tables primary key must match the key attribute of the mbean
element.
Each column name must match the name attribute of its corresponding attribute-integer, attribute-string, or attribute-date
element. The attribute type must also match the columns data type (integer, varchar, or timestamp).
283
CustomMBeanFactory.getCustomMonitor(String name) returns the CustomMonitor object for the mbean whose name attribute matches the name parameter value.
These are the only method calls involved in logging metrics data. Once logged, the data is automatically imported into archive tables.
<name-space> Element
Mapping between the table name in mbeans.xml and the actual table name. Each mbean in mbeans.xml must have its own name-space element in metrics_map.xml. ATTRIBUTES:
name
name-space attribute value for the corresponding mbean in mbeans.xml. This value can be an alias to the actual table name; it can
Actual database table name corresponding to name-space. Required attribute. Example: portletviews
parent
Name of the parent name-space. This attribute enables you to create a name-space hierarchy. Required attribute. Examples: root for the top
284
Metrics
of the hierarchy; or com.companyname.metrics.custom for the top of the custom metrics hierarchy.
<key/> Element
Child element of name-space that maps the key name in mbeans.xml to the actual key name in the table. ATTRIBUTES:
name
value can be an alias to the actual table key; it can contain spaces and use mixed case. Required attribute. Example: User Identifier
tablekey
Actual table key name corresponding to key. Required attribute. Example: userid
<attribute/> Element
Child element of name-space that maps the attribute name in mbeans.xml to the actual column name in the table. ATTRIBUTES:
name
name attribute value for the corresponding mbean child element in mbeans.xml. This value can be an alias to the actual column name; it
can contain spaces and use mixed case. Required attribute. Example:
Date of Last Hit
tablecolumn
Actual table column name corresponding to name. Required attribute. Example: last_hit Note that if metrics_map.xml contains alias mappings, then the corresponding values in mbeans.xml (the name-space and key attributes of mbean as well as the name attributes of the child elements of an mbean) can contain spaces and use mixed case. For example, mbeans.xml could include the following mbean:
285
<mbean name="com.companyname.metrics.portlets" namespace="Portlet Views" key="User Identifier"> <attribute-integer name="Total Page Hits" method="Incremental"/> <attribute-date name="Date of Last Hit"/> </mbean>
The following addition to metrics_map.xml would map the aliases used in mbeans.xml to a table named portletviews having a key of userid and columns named pagehits and last_hit:
<name-space name="Portlet Views" table="portletviews"> <key name="User Identifier" tablekey="userid"/> <attribute name="Total Page Hits" tablecolumn="pagehits"/> <attribute name="Date of Last Hit" tablecolumn="last_hit"/> </name-space>
This information will be stored in a table named portletviews, whose key is userid and whose column names are report_id, pagehits, and last_hit. (Note that report_id is required to be the first column in a custom metrics table.) Your company will use a database tool to create reports on these metrics; therefore, no aliasing of table or column names is required. NOTE: This example assumes that you have already created a separate metrics database and connection pool, as outlined in First-Time Database and Connection Pool Setup on page 278.
286
Metrics
NOTE: If there is not an mbeans.xml file already in the config subdirectory of the Portal installation directory, you can use config/examples/mbeans-sample.xml as the model for creating mbeans.xml.
NOTE: Not passing a key (userid) provides a counter of all page hits, as demonstrated in the call to recordIncrementalNumberValue("pagehits").
287
For example:
CustomMonitor monitor = CustomMBeanFactory.getCustomMonitor( "com.companyname.metrics.portlets"); try { // code here gets user ID as a string monitor.recordIncrementalNumberValue("pagehits", userid); } catch (NoSuchMBeanException e) { // handle exception here }
Or:
try { CustomMonitor monitor = CustomMBeanFactory.getCustomMonitor( "com.companyname.metrics.portlets"); // code here gets user ID as a string monitor.recordIncrementalNumberValue("pagehits", userid); } catch (AttributeNotFoundException e) { // handle exception here }
288
Metrics
17
Summary: Audience: Topics:
Connection Pooling
Describes how to use connection pooling with Vignette Portal Java developers responsible for customizing Vignette Portal
The Vignette Portal Connection Pooling System (below) Connection Pooling Code Examples on page 290 Support for Oracle LOBs on page 294
database cursor, which remains open and is not released by the database unless you explicitly close it. Note that result sets are closed when statements are closed; so if you dont close a statement, its result set may also stay open.
Return all connections to the connection pool when you are finished with them by calling close() method on the connection. Consider closing statements and connections in a finally block.
289
See also:
Vignette Portal Configuration Guide for details about configuring Portal connection pools and about data storage options
For statically configured connection pooling, properties are defined in the Portal configuration file, PortalInstallDir/config/properties.txt. Adding the following properties creates a custom connection pool named my_pool that connects to the database named my_db:
#JDBC Database section my_db.db.driver=oracle.jdbc.driver.OracleDriver my_db.db.url=jdbc:oracle:thin:@myserver:1521:orcl my_db.db.user=Portal my_db.db.password=password #Connection Pool Support section connectionpool.my_pool.db=my_db.db connectionpool.my_pool.code=com.epicentric.jdbc. ConnectionPoolService
The name my_pool is the ID of the pool of connections to the my_db database. Once Portal is running, every request for the my_pool connection pool always returns the same connection pool object (as long as the requests are within the context of the same JVM). The pool is instantiated the first time it is accessed.
See also: Vignette Portal Configuration Guide for an explanation of the Portal properties file
290
Connection Pooling
Dynamic Configuration
initialize a new connection pool with a given set of properties. Simply create a
java.util.Properties object and add the same key-value pairs to it that
would otherwise be added to the properties file for a static configuration, but without the namespace.name prefix on the keys. For example, to dynamically create the same connection pool that was statically configured in the example above, use the following statements:
Properties cpProps - new Properties(); cpProps.setProperty("db", "my_db.db"); ConnectionPoolConfiguration cpConfig = new ConnectionPoolConfiguration(cpProps);
Note that the connection.my_pool.db key from the static example has been shortened to just db in the second line above. As long as the my_db.db database definition has been set up in the properties file, this code will work correctly. To refer instead to a new database definition that has not been defined in the properties file, just set the driver, url, user, and password keys in the Properties object. Once you have a ConnectionPoolConfiguration object, you can use it to create a new connection pool by calling the
ConnectionPoolManager.createConnectionPool( ConnectionPoolConfiguration cpConfig) method. Note that unlike
statically configured connection pools, dynamically configured pools are unnamed and therefore are not accessible via the ConnectionPoolManager.getPool(String cpName) method.
291
String sql = "select email from table1"; // Get a connection, execute the statement, and print the // results. try { connection = pool.getConnection(); statement = connection.createStatement(); resultSet = statement.executeQuery(sql); while(resultSet.next()) { resultSet.getString(1); out.println(resultSet.getString(1)); // Catch SQL or timeout exception, if any. } catch (SQLException sql_e) { // code to handle SQLException... } catch (TimeoutException toe) { // code to handle TimeoutException, a Vignette exception // thrown if an attempt to retrieve a connection from the // pool times out... } finally { // Close the statement, then return the connection to the // pool. try { statement.close(); connection.close(); // Catch general exception. } catch (Exception e){} }
In the next example, a java.sql.PreparedStatement object is executed, then explicitly closed before it is used to open and execute another statement. This second statement is closed and the connection is returned to the pool in the finally block.
public void someMethod() { // Get a connection pool named "customdatabase". ConnectionPool pool = ConnectionPoolManager.getPool("customdatabase"); // Initialize variables. Connection conn = null; PreparedStatement statement = null; // Get a connection; prepare, execute and close the first // statement; then prepare and execute the second statement. try { conn = pool.getConnection(); String sql_1 = "some sql"; statement = conn.prepareStatement(sql_1); statement.executeUpdate(); // Explicitly close the statement before using it again. statement.close(); String sql_2 = "some other sql"; statement = conn.prepareStatement(sql_2);
292
Connection Pooling
statement.executeUpdate(); //Catch SQL or timeout exception, if any. } catch (SQLException sql_e) { // code to handle SQLException... } catch (TimeoutException toe) { // code to handle TimeoutException... } finally { // Close the second statement, then return the connection // to the pool. try { statement.close(); conn.close(); //Catch general exception. } catch (Exception e){} } }
In the final example, two PreparedStatement objects are used. Both are closed in the finally block.
public void someMethod() { // Get a connection pool named "customdatabase". ConnectionPool pool = ConnectionPoolManager.getPool("customdatabase"); // Initialize variables. Connection conn = null; PreparedStatement statement1 = null; PreparedStatement statement2 = null; // Get a connection, then prepare and execute both // statements. try { conn = pool.getConnection(); String sql_1 = "some sql"; statement1 = conn.prepareStatement(sql_1); statement.executeUpdate(); String sql_2 = "some other sql"; statement2 = conn.prepareStatement(sql_2); statement.executeUpdate(); // Catch SQL or timeout exception, if any. } catch (SQLException sql_e) { // code to handle SQLException... } catch (TimeoutException toe) { // code to handle TimeoutException... } finally { // Close both statements, then return the connection to // the pool. try { statement1.close(); statement2.close(); conn.close();
293
NOTE: This limitation applies only to operations on Oracle LOBs. All operations on all other data types are fully supported by the Portal connection pool. If you want to use any other insert/update statements to manipulate Oracle LOBs in your custom tables using the Portal connection pool, you can bypass the special LOB handling provided by the abstraction layer. To do so, add the following property to the Portal configuration file (PortalInstallDir/config/properties.txt) for each custom table to be excluded from the special LOB handling:
connectionpool.poolID.exclude_table.n=tableName
where n is a numerical increment. Note that the list of excluded tables must begin with 0 and increment by 1. IMPORTANT: Do not use this property for any of the Portal system tables.
294
Connection Pooling
If you want to disable this special LOB handling for a specific Portal connection pool, add the following property to the configuration file:
connectionpool.poolID.disable_locators=true
If you disable the Portal LOB abstraction layer, you are fully responsible for handling the Oracle LOB in your custom code.
See also:
Vignette Portal Configuration Guide for a discussion of the properties.txt file properties.txt file comments for details about using the LOB properties
295
296
Connection Pooling
18
Summary: Audience: Topics:
Retrieving Content from Remote Sources (below) Inspecting and Altering Proxied Content on page 298 Customizing the WebConnector 3.0 Portlet on page 299
In your code, you create a representation of a session on a remote server. Using the session, you create a request to the remote server. You instruct the request to retrieve a response object. You use the response object to retrieve the content, which can be in the form of an input stream, a byte array, or a string.
The RSM API enables you to inspect the request and response, set remote session information, alter the request, and conditionally retrieve content. In the case of the HTTP implementation of this API, you can inspect the HTTP status code, MIME type, or other response state before deciding whether to retrieve body content. By performing conditional GET requests, you can also implement HTTP-based cache handling.
297
The base package for the RSM API is com.vignette.portal.rsm. This package defines RemoteSession, RemoteRequest, and RemoteResponse interfaces, which are implemented in protocol-specific subpackages. Vignette currently ships an HTTP implementation, a file system implementation, and a base implementation that uses a java.net.URLConnection object to connect to a remote server.
See also:
Technical Library on Vignette Connect (http://connect.vignette.com) for API documentation (javadocs) of the com.vignette.portal.rsm package and subpackages Extension Library of the Portal Developer Community on Vignette Connect for sample usage of the RSM API
(group them into meaningful Java objects called tokens) for a particular MIME type.
Set mutator classes that can inspect and alter tokens as they are
encountered.
Allow segmentation of the content into sub-pieces for display purposes (a
responsible for managing the various operations on the content. This processor uses parsers to create MIME-specific tokens. The processor calls a Segmenter method and optionally one or more TokenMutator implementations to operate on each token as its created, then pushes the (potentially altered) tokens to one or more Segment implementations. The processors process(String mimeType, Reader reader) method returns an implementation of the UltimateDestination interface, which contains the results of the segmentation and transformation processing. These results consist of three segments: a segment before the body content, the body content segment, and a segment after the body content. Figure 55 summarizes this processing.
298
Figure 55:
Markup Text
Segmenter TokenMutator
UltimateDestination
See also:
Technical Library on Vignette Connect (http://connect.vignette.com) for API documentation (javadocs) of the
com.vignette.portal.text.processor
package and subpackages Extension Library of the Portal Developer Community on Vignette Connect for sample usage of the Segmentation and Transformation API
299
customize how a particular instance of a WebConnector 3.0 portlet uses the RSM and the Segmentation and Transformation APIs as explained next.
See also: Vignette Portal WebConnector Administrators Guide for details about creating and configuring WebConnector 3.0 portlet instances
after requesting proxied content. Here is the sequence of processing that WebConnector performs:
1 2 3 4 5
Builds the remote request Calls the processRequest() method Performs the request and gets a response Calls the processResponse() method Gets the content.
For each WebConnector request to the proxied site, a new interpolator instance is created. That same instance is used to process the response from the proxied site. Portal administrators specify the name of your interpolator class when configuring a WebConnector 3.0 portlet instance.
processRequest() Method
This method allows for inspection of the request to be sent to the remote site or other remote entity before WebConnector sends the request. Its signature is as follows:
public void processRequest(RequestResponseContext context, RemoteSession remote_session, RemoteRequest remote_request)
where
300
context is an implementation of the com.vignette.portlet .buildingblock.webconnector.interpolator.RequestRespons eContext interface, which WebConnector creates and populates with
represents the request to be sent to the remote entity Class-level data members created or modified during the call to processRequest() will be available in the subsequent processResponse() call, but are not available elsewhere.
processResponse() Method
This method allows for inspection of the response from the remote site or other remote entity before content retrieval, transformation, and rendering. Its signature is as follows:
public void processResponse(RequestResponseContext context, RemoteSession remote_session, RemoteResponse remote_response)
The first two parameters are the same as for processRequest(). The remote_response parameter is an implementation of the com.vignette.portal.rsm.RemoteResponse interface, which represents the response received from the remote entity.
RequestResponseContext Interface
The com.vignette.portlet.buildingblock.webconnector .interpolator.RequestResponseContext interface is used to pass context-specific information to your RequestResponseInterpolator implementation. When WebConnector calls the interpolators
processRequest() and processResponse() methods, it passes its implementation of RequestResponseContext to the interpolator.
301
is the string that a Portal administrator specifies when configuring an instance of WebConnector 3.0.
Other objects currently included in the interpolator context. These objects
may not exist in future versions of the portlet, especially as it moves to a Java standard portlet (JSR 286) architecture. When writing your interpolator, check whether the context object is an instance of
com.epicentric.portalbeans.beans.webconnectorbean .interpolator.PortalBeanRequestResponseContext (an interface that extends RequestResponseContext). If so, this context object provides access to the calling PortalBeanView object through its public getView() method.
302
To perform custom content clipping, create your own implementation of com.vignette.portal.text.processor.Segmenter. The Portal administrator specifies the class name for your implementation when configuring a WebConnector 3.0 portlet instance.
Custom Transformations
Here are a few examples of reasons you might want to alter the proxied content:
Adding a URL parameter required by a remote applet or plugin Altering proxied HTML element IDs (for example, to handle namespace
collisions)
Handling navigation constructs within JavaScript eval() calls (which
WebConnector does not alter) You can perform such alterations by developing classes that extend the appropriate mutator: HTMLTokenMutator, JavaScriptTokenMutator, or CSSTokenMutator. Any number of mutators can be called in sequence. WebConnector 3.0 portlet configuration enables Portal administrators to specify the class names as well as the order in which they are to be invoked.
303
304
19
Summary: Audience: Topics:
Introduction Federated Search Architecture on page 306 Creating a Custom Search Connector on page 309
Introduction
Vignette provides an open, pluggable framework for performing seamless federated searches across all content repositories within an organization. For example, search results can be federated across the Portal content repository, the repositories of other Vignette products, the repositories of third-party content management systems, the content of intranet sites, and the content of public web sites. Vignette Portal includes support for some of these content repositories, a portlet that provides a highly configurable user interface for both administrators and end users, and a public Federated Search API. You can use this API to integrate additional content repositories into federated searches, to create your own Federated Search portlet, or to create other custom user interfaces that expose Federated Search capabilities. This chapter provides an overview of the Federated Search API and explains how to create integrations with other content repositories.
305
Portal is the out-of-the-box user interface for federated search functionality. Alternative user interfaces can also be developed.
Federated Search API This tier includes the classes in the com.vignette.portal.search package. The purpose of these classes
is to retrieve and consolidate search metadata (searchable field names, supported search operations, collections where contents are indexed, etc.) from content repositories that are participating in federated searches; encapsulate search query execution against participating repositories; and process the results of federated searches. The Federated Search API supports the Federated Search portlet as well as custom search portlets or applications.
Connectors Search connectors are adaptors between the Federated
Search API and applications content repositories. A search connector can search a specific respository; each repository that is to participate in federated searches must have its own connector. Connectors implement the search connector interface (com.vignette.portal.search.ISearchConnector), which defines the expected services. These services correlate with those of the Federated Search API: retrieving metadata from a repository that is participating in federated searches and executing basic and advanced search queries against the repository. The Federated Search API is implemented as a thin veneer on top of Federated Search connectors. It enables you to plug a preexisting federated search infrastructure into the Vignette Federated Search framework. Figure 56 illustrates the architecture of the Federated Search framework.
See also: Technical Library on Vignette Connect (http://connect.vignette.com) for API documentation (javadocs) of com.vignette.portal.search
306
Figure 56:
Custom Connectors
CAM API
Products
Collections
3rd-party Collections
Search Connectors
As shown in Figure 56, Vignette Portal provides the following search connectors:
The CAM search connector uses the Content Access Management API to
search repositories that are accessible through the CAM system. CAM has its own repository as well as a connector architecture for aggregating content from other sources, such as file systems and Vignette Content delivery stages. The CAM search connector can also integrate with search engine connectors, which are implemented using the connector architecture of the Indexing API and configured through properties in the Portal configuration file (PortalInstallDir/config/properties.txt).
307
NOTE: The Indexing API is designed for use with the CAM system to expose content within search engine repositories. The purpose of this API is now primarily to provide backwards compatibility with versions of Vignette Portal prior to the introduction of the Federated Search framework (in version 7.3). To take advantage of the capabilities of the Federated Search framework, you should implement connectors to search engine repositories by creating a custom search connector rather than by using the Indexing API.
A Vignette product connector provides a bridge between the Federated
Search API and the content repository of another Vignette product, thereby enabling that repository to participate in federated searches. Vignette is in the process of developing product connectors. Portal administrators can use these Federated Search connectors simply by configuring them. In addition, to enable other applications repositories to participate in federated searches, you can create any number of custom search connectors. These connectors can integrate either with a third-party repository through its application, or with a third-party repository directly.
See also:
Chapter 20, Using the Content Access Management and Indexing APIs, for details about CAM and search/indexing engine connectors. Creating a Custom Search Connector on page 309 for details about developing your own implementation of the search connector interface
308
strings
Creating XML files known as component descriptors in preparation for
Chapter 21, Developing and Deploying Custom Services, for a description of service types, implementations, and instances Vignette Portal Administrators Guide for more about the Service Manager
309
The interaction between your connector and its target repository can use one of a variety of models, such as in-process Java method invocation, calls to a remote web service, or XML over HTTP requests. One important design consideration is that your search connector should not introduce tight coupling between Portal and other products. To avoid the inherent issues with tight coupling, such as product version dependencies and incompatibility between JAR file versions, Vignette strongly recommends that you consider using a web service or other XML-over-HTTP model for connector/repository interactions.
Delegating Searching to the Underlying Application
Federated searches should return only those search results that the current user has permission to view; and clicking the link for a result should render the content within its proper context. To meet these requirements, a search connector should use the search APIs of the repositorys application to perform searches, rather than executing searches directly. This design approach enables the application to enforce permissions and provide presentation context. Each search connector is responsible for ensuring that the returned search results account for the access permissions of the current user, in accordance with the authorization policy of the target repository. To support this requirement, the Portal object representing the current user is available to search connectors. Your ISearchConnector implementation must map this user object to its counterpart in the target repository. In addition, your implementation should map two special Portal usersguests and members of the Admin system groupto their counterparts in the target repository.
Permission-Aware Results. See also: Chapter 14, Users and Access Control, for discussion of guest users, administrative users, and the current user object
Context-Aware Results.
For each result of a search, your connector must construct a URL that contains the information required to present the content
310
within its application context. When designing your connector, also be sure the results URLs will point to resources that Federated Search portlet users can access.
Sorting the Results
The Federated Search framework supports two sort options: relevance and modified date. For both options, search connectors must sort the results in descending order before returning them. For relevance sorts, the framework uses a uniform scale of 0 to 100, where 100 is the highest relevance. Unless this scale matches the one used by the target repository, your connector must transform the relevance assigned to search results before returning them.
Analyzing the Target Repository
hierarchical, and which of these collections should be available for federated searches
Any parameters that the connector will need, such as the web server host
Connectors expose the following localizable text in the Portal server console:
title and description of the connector itself (exposed through the Service
Manager)
title and description of the component containing your connectors
311
public class SampleSearchConnector implements ISearchConnector{ private static final LogWrapper LOG = new LogWrapper(GoogleSearchConnector.class);
Other class variables include a reference to the configuration object (SearchConnectorConfig) and any initial values to be passed infor example, the number of times to retry if the connectors attempt to obtain search results fails:
protected SearchConnectorConfig config; protected int retries = 3; // Default number of retries
described next.
See also:
Technical Library on Vignette Connect (http://connect.vignette.com) for API documentation (javadocs) of com.vignette.portal.search .ISearchConnector Chapter 7, Using the Site Development APIs, for information about using the Portal logging API
init()
The init() method takes one parameter: the SearchConnectorConfig object. At minimum, your connector must store a reference to this object:
public void init(SearchConnectorConfig config) {
Any initial parameter values should also be retrieved from the config object as wellfor example:
try { retries = Integer.parseInt(config.getInitParameterVa lue("retries")); } catch (Exception ex) { }
These initial parameter values are stored as a Map in the config object.
getSubCollections()
The backing store of the data being searched might be organized hierarchically; for example, the Portals Content Access Management system stores data within folders that can be nested to an arbitrary depth. In such a case, implement the getSubCollections() method to return the fully qualified names for the subcollections. If security restrictions determine who
312
can access which collections, pass in a Portal User object as well. For example:
public Set getSubCollections(User user, String collection) { Set subCollections = null; try { // check whether given collection is valid for given user String userid = user.getID(); Folder folder = MyFolders.getFolderForUser(userid); String[] subfolders = folder.getSubFolderNames(); if (subfolders == null || subfolders.length == 0) return null; subCollections = new HashSet(); for (int i=0; i<subfolders.length; i++) { subCollections.add(subfolders[i]); } } catch (InvalidPathException ex) { // invalid collection name or path LOG.error("Invalid collection encountered "+collection, ex); } catch (SecurityException ex) { // user doesnt have access LOG.error("Access forbidden", ex); } return subCollections; }
If the data in the backing store is not hierarchical, simply return null in this method.
isValidCollection()
Given a collection and a user, this method indicates whether the collection can be returned. You can use the configuration to perform this checkfor example:
public boolean isValidCollection(User user, String collection) { Set collections = this.config.getRootCollections(); return collections.contains(collection); }
executeBasicSearch()
This method passes in the data required for a basic search to be executed against the backing data store. This method has four parameters:
the users search text input
313
either the set of search collection names against which this search should be
environment information, such as the request, user, and site objects, the start position and sort order for the search, and the connector ID
a Boolean indicating whether the search should be recursive (simply
ignored if the collections are not hierarchical or the connector does not support recursive searching) This method returns a SearchResults object, which you construct in the body of the method. SearchResults has a number of constructors, but at minimum this object contains the string identifying the connector. Most of the implementation of this method involves calls to the underlying application; however, here is an example of the basic structure (where SearchResults, SearchResult, ConnectorSearchContext, and SearchException are all com.vignette.portal.search classes):
public SearchResults executeBasicSearch(String text, Set targetCollectionNames, ConnectorSearchContext context, boolean recursive) throws SearchException { SampleSearchApp search = null; SearchResults sr = null; try { // Assume a fictitious SampleSearchApp here; // set its query string, page size, start position, and // collections to be searched search = new SampleSearchApp(); search.setQueryText(text); search.setPageSize(context.getPageSize()); search.setStartPosition(context.getStartPosition()); for (Iterator iter=targetCollectionNames.iterator(); iter.hasNext(); ) { String collection = iter.next().toString(); search.addCollection(collection); } // perform search and iterate over the results SampleSearchResults results = search.search(); SearchResult[] r = new SearchResult[results.size()]; while (results.hasNext()) { SampleSearchResult result = results.next(); SearchResult r = new SearchResult(result.getTitle(), result.getDescription(), result.getAuthor(),
314
result.getDate(), result.getUrl(), result.getRelevance(), result.getSize(), config.getId()); // config is from init() use SampleSearchApp to execute search here... pass in pageSize + start (and any other context) then construct SearchResults--for example, assuming search returned results and results count: = new SearchResults(config.getId(), results.getTotalCount(), r); } catch (SampleSearchAppException ex) { // write error to portal log LOG.debug("Search failed with: "+ex); throw new SearchException("SampleSearch failed", ex); } return sr; } } // // // // sr
executeAdvancedSearch()
This method differs from executeBasicSearch() only in the specificity of the data being passed in. The greater degree of specificity is provided by the first parameter of this method: an object of type SearchCriteria, which can contain any number of search terms rather than the input string used in a basic search. If a search term can take only a single operator, it is an instance of
SingleValueSearchTerm. If a search term has two operatorsmost
315
sb.append(" "); } sb.append(sterm.getName()+":\""+sterm.getValue()+"\""); } else if (term instanceof DoubleValueSearchTerm) { DoubleValueSearchTerm dterm = (DoubleValueSearchTerm) term; if (FIELD_DATE.equals(dterm.getName())) { if (OPERATOR_BETWEEN.equals(dterm.getOperator())) { Calendar startDate = null; Calendar endDate = new GregorianCalendar(); if (dterm.getValues()[0] instanceof Calendar) { startDate = (Calendar) dterm.getValues()[0]; } else if (dterm.getValues()[0] instanceof Long) { startDate = new GregorianCalendar(); startDate.setTime(new Date(System.currentTimeMillis() - ((Long) dterm.getValues()[0]).longValue())); } if (dterm.getValues().length > 1) { if (dterm.getValues()[1] instanceof Calendar) { endDate = (Calendar) dterm.getValues()[1]; } else if (dterm.getValues()[1] instanceof Long) { endDate = new GregorianCalendar(); endDate.setTime(new Date(System.currentTimeMillis() -((Long) dterm.getValues()[1]).longValue())); } } other.append(" daterange:" +toJulianDate(startDate)+"-" +toJulianDate(endDate)); } } } // pass search string to the basic search method return executeBasicSearch(sb.toString(), targetCollectionNames, context, false); }
316
PortalInstallDir/config/federated_search_master_vocabulary.xm l file. Each search field is identified by a <connector-field id="commonName" name="connectorName"/> element. The XML file must begin with a <connector-fields> element and end with a </connector-fields> element. For example:
<!-- Maps common fields to connector fields --> <connector-fields> <connector-field id="TITLE" name="title" /> <connector-field id="BODY" name="content" />
Each search connector instance can have its own vocabulary file. Alternatively, search connectors can share a vocabulary file. When you specify the connectors configuration (as explained in Step 5: Create Component Descriptors on page 318), you define the location of the vocabulary file to be used.
317
Execute UniqueIDFactory twiceonce for each of the default property files. For each of the display strings, define two key/value pairs in the property files:
keyname=value keyname_comment=value
The first pair provides the default value, which will be displayed if there is no locale-specific value. The second pair provides a description of the keys purpose so that translators can provide appropriate text for a particular locale. For example:
title=Sample Search Connector title_comment=Text to appear in Service Managers Name field description=Sample Federated Search Connector description_comment=Service Managers Description field
If you are also supplying locale-specific property files for your connector, name the files according to the Java conventions (using the two-character language code optionally followed by the country code, and possibly a dialect or variant codefor example, 20d276fcfee3062ac49b5461f29341a0_fr_FR.properties). Once your search connector is deployed, any number of additional translations can be supplied using the administration consoles.
See also: Chapter 6, Internationalizing and Localizing Site Components, for more about the Portal I18N framework
implementation and all other classes upon which the connector depends; visible from the PortalBean Manager
318
a component that configures an instance of the FederatedSearchService class; visible from the Service Manager
This separation of the connectors service instance from its code enables you to develop multiple custom connectors that share common code. Connectors service instances can be deployed and undeployed independently, without affecting each other or the underlying code.
See also:
Vignette Portal Administrators Guide for discussion of the PortalBean Manager and Service Manager
Support Component
The component.xml file for a custom search connectors support file must have the following structure:
<?xml version="1.0" encoding="UTF-8"?> <epideploy:component component-id="string" component-type="ModuleTypes" major-version="integer" minor-version="integer" build-version="string" epi-version="7.3" epi-build="integer" title="string" description="string" xmlns:epideploy="http://www.epicentric.com/deployment"> <epideploy:detail> <module-config auto-deploy="true" | "false"> <web-deployment-path>string</web-deployment-path> <locale-key>string</locale-key> </module-config> </epideploy:detail> </epideploy:component>
The remainder of the structure of this file conforms to the requirements of a shared component. The following sections explain each element.
<epideploy:component> Element. This element is the parent for all of the other elements of any component.xml file. Here is a description of the attributes of <epideploy:component>:
319
Manager.
major-version and minor-versionCombination of values that
identify the version of the shared components code. These values appear in the PortalBean Manager.
build-versionString identifying the components build; useful in
troubleshooting connector upgrade issues. This string is not used by the deployment system but is displayed by the PortalBean Manager.
epi-version and epi-buildOldest version of Portal that the component will run on. The value for epi-version should be "7.3" and the value for epi-build should be "1". title and descriptionStrings having a maximum length of 255
characters each; displayed by the PortalBean Manager. These strings should be localized, as explained in Step 4: Create the I18N Property Files on page 317.
xmlns:epideployA required attribute whose value is fixed:
xmlns:epideploy="http://www.epicentric.com/deployment"> <epideploy:detail> Element.
<epideploy:component>. In the case of a custom connectors support component,<epideploy:detail> contains one element: <moduleconfig>.
This element is required for a shared component. This element has one attribute: auto-deploy, which controls deployment behavior in the event an earlier version of a component having the same component-id has already been deployed. In such a case, autodeploy="true" causes this component to be deployed, replacing the preexisting component; auto-deploy="false" causes this component to be uploaded into the Portal database and displayed by the PortalBean Manager, but a Portal server administrator must use the PortalBean Manager to explicitly deploy it. (The deployment system uses the major-version and minor-version attributes in this component.xml file to determine the version of this component.)
<module-config> Element.
320
<web-deployment-path> Element.
<module-config>. It specifies the deployment location of any files that should not be deployed under the WEB-INF directory. The value of this
element is relative to the Portal web application. If files are to be deployed to the Portal web applications root, the value of this element should be /. (If all files in your connectors support component are to be deployed under PortalWebApp/WEB-INF, the deployment system simply ignores this element.)
<locale-key> Element.
<module-config>. It specifies the unique ID of the I18N property file(s) for this components title and description localizable text. The value of
this element must match the hexadecimal value that you generated for the PortalBean Manager property file(s), as explained in Step 4: Create the I18N Property Files on page 317.
Example.
Here is an example of a component.xml file for Version 1.0 of a custom connectors support component:
<?xml version="1.0" encoding="UTF-8"?> <epideploy:component component-id="SampleSearchSupport001" component-type="ModuleTypes" major-version="1" minor-version="0" build-version="1" epi-version="7.3" epi-build="1" title="Sample Search Support Component" description="Support component for Sample Search custom connector" xmlns:epideploy="http://www.epicentric.com/deployment"> <epideploy:detail> <module-config auto-deploy="true"> <web-deployment-path>/</web-deployment-path> <locale-key> 31e387adfdd4173bd50c6572a30452b1 </locale-key> </module-config> </epideploy:detail> </epideploy:component> See also:
Vignette Application Portal Module Developers Guide for further explanation of component descriptor files for shared "ModuleTypes" components Vignette Portal Administrators Guide for further information about the PortalBean Manager
321
The component.xml file for your connectors service instance specifies connector configuration values. These values can be viewed and modified by Portal administrators using the Service Manager (Service Manager>>Federated Search>>Custom Connector Name). The service instance component.xml file must have the following structure:
<?xml version="1.0" encoding="UTF-8"?> <epideploy:component component-id="string" component-type="Service Instances" major-version="integer" minor-version="integer" build-version="string" epi-version="7.3" epi-build="1" title="string" description="string" xmlns:epideploy="http://www.epicentric.com/deployment"> <epideploy:required-component component-id="Support Component ID" component-type="ModuleTypes" major-version="integer" minor-version="integer" /> <epideploy:detail> <service-instance enabled="true"|"false" id="string"> <implementation-id> com.vignette.portal.search.FederatedSearchService </implementation-id> <type-id> com.vignette.portal.search.FederatedSearchService </type-id> <locale-key>string</locale-key> <property-set> <property key="id">string</property> <property key="name">string</property> <property key="desc">string</property> <property key="supportHierarchicalCollection"> true|false </property> <property key="supportRecursiveSearch"> true|false </property> <property key="connectorClassname"> full.path.to.class </property> <property key="vocabFile">filename.xml</property> <property key="vocabFileComponentID">
322
string </property> <property key="vocabFileComponentType"> string </property> <property key="connectorTimeout">integer</property> <property key="initCollections"> comma-separated list of collection names </property> <property key="ips.int.runtimeKey"> string </property> <property key="ips.int.runtimeValue"> string </property> </property-set> </service-instance> </epideploy:detail> </epideploy:component>
Some of the elements included in a connectors service instance component.xml file are common to all Portal components, others are specific to components that are instances of a service implementation, and the remainder are specific to instances of the FederatedSearchService implementation. The following sections explain each of these elements.
See also:
Chapter 21, Developing and Deploying Custom Services, for more about component.xml files for services Appendix B, Deployment Reference, for details about the elements and attributes of component.xml files Vignette Portal Administrators Guide for more about the Service Manager
<epideploy:component> Element.
The <epideploy:component> element is the parent for all of the other elements of any component.xml file. Here is a description of the attributes of <epideploy:component>: be properly namespaced to ensure uniqueness.
component-idThe unique ID of the service instance. This string must component-typeThe literal value of "Service Instances", used to
identify an instance of a service implementation. Services are listed in the server consoles Service Manager; configurable service instances (such as custom connectors) can also be configured via the Service Manager.
major-version and minor-versionCombination of values that
323
troubleshooting connector upgrade issues. This string is not used by the deployment system but is displayed by the Service Manager.
epi-version and epi-buildOldest version of Portal that the instance will run on. The value for epi-version should be "7.3" and the value for epi-build should be "1". title and descriptionStrings having a maximum length of 255
characters each; displayed by the Service Manager. These strings should be localized, as explained in Step 4: Create the I18N Property Files on page 317.
xmlns:epideployA required attribute whose value is fixed:
xmlns:epideploy="http://www.epicentric.com/deployment"> <epideploy:required-component> Element. This element is a required child element of <epideploy:component> specifying this components dependency on its support component. This element must have the following attributes:
component-idSupport components ID. The value of this attribute must match the component-id value in the support components component.xml file. component-typeThe literal value "ModuleTypes" (which matches the component-type value in the support components component.xml
file).
major-version and minor-versionCombination of values that
identify the support components version. Either the specified version or a later version of the support component must be available at deployment time; otherwise, your custom connector will not be deployed.
<epideploy:detail> Element.
<epideploy:component>. In the case of a FederatedSearchService instance, <epideploy:detail> contains one element: <serviceinstance>.
<service-instance> Element.
This element contains all of the configuration details for your custom connector. This element has two attributes: id, which is a unique string referring to this instance of your connector; and enabled, which is a Boolean determining whether the connector is automatically enabled upon deployment. (Note that if you deploy this connector more than once, each instance must have a unique service instance ID.) The <service-
324
instance> element has four child elements: <implementation-id>, <type-id>, <locale-key>, and <property-set>.
This child element of <service-instance> is required and must have the literal value com.vignette.portal.search.FederatedSearchService, since custom connectors are instances of this implementation.
<implementation-id>.
This child element of <service-instance> is also required and must have the literal value com.vignette.portal.search.FederatedSearchService, which is the predefined service type for Federated Search.
<type-id>.
This child element of <service-instance> specifies the unique ID of the I18N property file(s) for this service instances title and description localizable text. The value of this element must match the
<locale-key>.
hexadecimal value that you generated for the Service Manager property file(s), as explained in Step 4: Create the I18N Property Files on page 317).
<property-set>.
The <property-set> element is the parent for a list of connector <property> elements, each representing a key/value pair. The keys correspond to labels that are displayed in the Service Manager UI for Federated Search instances, and the values that you define in your component.xml file are modifiable from that UI. The following keys are predefined:
<property> Elements.
display purposes. If you deploy this connector more than once, this ID must be unique for each instance.
nameName of the connector name descConnector description supportHierarchicalCollectiontrue or false value indicating
whether the backing store of the data being searched is organized hierarchically. For example, the Portals Content Access Management system stores data within folders that can be nested to an arbitrary depth.
supportRecursiveSearchtrue or false value indicating whether a
325
connectorClassnameFully qualified classname of your implementation of the ISearchConnector interface (described in Step 2:
search field names shared by allor a set ofsearch connectors. If this connector has its own vocabulary file, the value of this key must match the value of this component.xml files component-id attribute.
vocabFileComponentTypeType of the component that contains the file identified by vocabFile. The value of this key must match the value of the component-type attribute of the components <epideploy:component> element. This key, along with the vocabFileComponentID key, enables you to maintain a global list of
search terms shared by allor a set ofsearch connectors. If this connector has its own vocabulary file, the value of this key must be Service Instances (the value of this component.xml files component-type attribute).
connectorTimeoutNumber of milliseconds to give the connector to
complete its search before the Federated Search system times out the search.
initCollectionsComma-separated list of collections to be searched.
For hierarchical collections, this list represents the default collections available to be searched; if the entire hierarchy is to be searched by default, the value of this key should be / (a single forward slash). For a connector that does not support hierarchies, this list defines all of the collections that this connector can search. In addition to the above predefined keys, you can pass any number of initial settings to your connector by including property elements in the form ips.n.runtimeKey and ips.n.runtimeValue, where n is an incremented integer starting with 0. For example, an initial value for specifying the number of times to retry a search can be configured as follows:
<property key="ips.0.runtimeKey">retries</property>
326
<property key="ips.0.runtimeValue">3</property>
The sample code in Step 2: Implement the ISearchConnector Interface on page 311 illustrates initializing and using a retries class variable. Here is an example of a component.xml file for a connector named SampleSearchConnector, which is dependent on the support component shown in the Example on page 321 and which connects to three nonhierarchical search collections named sample1, sample2, and sample3:
Example. <?xml version="1.0" encoding="UTF-8"?> <epideploy:component component-id="com.companyname.portal.SampleSearchConnector" component-type="Service Instances" major-version="1" minor-version="0" build-version="gold" epi-build="1" epi-version="7.3" title="Sample Search Connector" description="Sample Federated Search Connector" xmlns:epideploy="http://www.epicentric.com/deployment"> <epideploy:required-component component-id="SampleSearchSupport001" component-type="ModuleTypes" major-version="1" minor-version="0" /> <epideploy:detail> <service-instance enabled="true" id="searchsample1"> <implementation-id> com.vignette.portal.search.FederatedSearchService </implementation-id> <type-id> com.vignette.portal.search.FederatedSearchService </type-id> <locale-key> 20d276fcfee3062ac49b5461f29341a0 </locale-key> <property-set> <property key="id">Sample</property> <property key="name">Sample Federated Search </property> <property key="desc">API for Sample Search Connector </property> <property key="supportHierarchicalCollection">false </property> <property key="supportRecursiveSearch">false </property> <property key="connectorClassname">com.companyname .portal.connectors.search.SampleSearchConnector </property>
327
<property key="vocabFile">sample_vocabulary.xml </property> <property key="vocabFileComponentID">com.companyname .portal.search.SampleSearchConnector </property> <property key="vocabFileComponentType">Service Instances </property> <property key="connectorTimeout">10000</property> <property key="initCollections">sample1,sample2,sample3 </property> <property key="ips.0.runtimeKey">retries</property> <property key="ips.0.runtimeValue">3</property> </property-set> </service-instance> </epideploy:detail> </epideploy:component>
The support CAR file contains the code on which your connector depends: your ISearchConnector implementation, any other custom code you implemented for this connector, and the code of the underlying application. At the root of this CAR file is the support components descriptor (component.xml file). The following sections explain these contents.
328
Connector Code.
Compile your custom code, and place the full path and Java class (or classes) in the WEB-INF/classes directory of the CAR file. The directory structure for your class must reflect the fully qualified package name, as identified in the connectorClassname property of the service instance component.xml file.
See also:
Step 2: Implement the ISearchConnector Interface on page 311 for details about creating your connector code Page 326 for an explanation of the connectorClassname property
Third-Party Code. Place the underlying applications code that your connector requires in the WEB-INF/lib directory of the CAR file. Typically, the thirdparty classes and any other types of files are contained in one or more JAR files. Component Descriptor.
Place the support components component.xml file in the root of the CAR file. Table 23 summarizes the directory structure and files to be included in the support CAR file.
Support CAR File Contents Files component.xml file described in Support Component on page 319
/WEB-INF/classes/class_path Your implementing class(es) as described in Connector Code on page 329 /WEB-INF/lib /WEB-INF/i18n Third-party JAR or other files described in ThirdParty Code on page 329 .properties files for the PortalBean Manager localizable text, described in Step 4: Create the I18N Property Files on page 317
329
Use the Java jar commandor any compression utility that uses the ZIP formatto create a second CAR file containing the directory structure and files shown in Table 24.
Table 24: Directory root /WEB-INF/i18n /WEB-INF/misc Configuration CAR File Contents Files component.xml file described in Service Instance Component on page 322 .properties files for the Service Manager localizable text, described in Step 4: Create the I18N Property Files on page 317 Connector vocabulary file created in Step 3: Define the Connectors Search Field Names on page 316, unless your connector shares a vocabulary file that is deployed in a different component (in this case, simply do not include this subdirectory)
Create a third CAR file to contain the service instance CAR file and the support CAR file described in the previous sections. Add the CAR files to the root of this third CAR file. Once you are satisfied that your custom connector is working properly, Portal administrators can deploy the connector to staging and production systems using this container CAR file.
330
server console, then restart the Portal web application twice. IMPORTANT: Do not use the server consoles Import Components tool to import service CAR files. or
Place the CAR file in the PortalInstallDir/deployment/upload
directory, then restart the Portal web application twice. (For both of the above mechanisms, the first restart uploads the CAR files and deploys your Java classes, and the second deploys the third-party JAR files.)
2 3
Using the Portal server console, go to Tools>>Service Manager. Verify that your connector appears as a new instance of the Federated Search service within the Service Manager. If your connector does not appear on the Federated Search services list, check the structure of your CAR files and the values in your component.xml files, correct any errors, recreate the CAR files, and redeploy the container CAR file. (Portal will redeploy a CAR file as long as its version is the same as or greater than the currently deployed version.)
Go to the service instance details page for your connector. If you see any errors, correct them in the configuration component.xml file, recreate the configuration and container CAR files, and redeploy the container CAR file.
331
Create an instance of the Federated Search portlet. On the portlets Details page, click Collections. Verify that the collections that your connector can search are displayed, and that one or more of the collections is enabled. The collections that are enabled by default depend upon the value of the initCollections property (explained on Page 326) in your connectors configuration component.xml file.
3 4
Use the portlets Permissions page to enable the portlet for the appropriate user groups. Using the site console, ensure that the portlets category is available on a page of the site, that the page is assigned to an enabled navigation item, and that the site has been enabled. Switch to the end-user view of the site, and add the Federated Search portlet to the navigation item from the previous step. Perform searches against content within your connectors collection(s), and verify that the appropriate results are returned.
See also:
5 6
Vignette Portal Administrators Guide for details about using the Portal administration consoles
332
20
Summary: Audience: Topics:
Introduction (below) CAM Architecture on page 335 Using the Access API on page 337 Developing Data Source Connectors on page 341 Developing Search Engine Connectors on page 347 Customizing Content Rendering on page 355
Introduction
Vignette Portal includes flexible and extensible systems that support creating, organizing, reviewing, updating, tracking, selectively sharing, searching, and indexing documents. These capabilities are provided through the Content Access Management (CAM) framework, CAM APIs, and the Indexing API. CAM provides a suite of portlets, its own content repository, and lightweight workflow management and publishing capabilities for documents in the Portal content repository. In addition, CAM can be integrated with third-party content management systems (CMSs). The CAM portlets that ship with Portal can provide unified views of content that resides in the Portal content repository and one or more third-party CMSs; users are unaware of the origin or storage locations of the various content. For some CMSs, integration merely requires modifying configuration files.
333
Introduction
You can customize CAM to support use cases that the framework as shipped does not fulfill. For example, you might need either augmented or diminished Portal display capabilities, or you might want to integrate Portal with a CMS that is not supported out of the box. To meet such requirements, CAM supports two kinds of custom development:
Custom content management portlets or applications Connectors to provide integration to additional CMSs
Similarly, the Indexing API provides a pluggable means of integrating search engines into your Portal installation. Portal ships with search engine connectors for specific third-party search engines as well as a connector between Portal and Vignette Content; if the Vignette Content Delivery Connector is installed, the Indexing API can be used to search content from a Vignette Content delivery stage. In addition, you can use the Indexing API to implement connectors between Portal and other products. CAM content repositories use the Indexing API to search and index CAM content. NonCAM collections can be searched through the Indexing API as well; the field/property names indexed in the search engines follow the field/property names used by CAM. NOTE: The Indexing API primarily provides backwards compatibility with versions of Vignette Portal prior to 7.3. For most cases, Vignette recommends that you use the Federated Search API instead of the Indexing API. Whereas the Federated Search API connects to other products search APIs, the Indexing API connects to the search engine products themselves. As a result, the Indexing API does not maintain the presentation context of non-CAM applications, does not honor a non-CAM collections user-based access restrictions, and requires tighter coupling between Portal and other products. In addition, the Federated Search API allows you to map field names. However, it allows implementation of search-only (that is, readonly) repositories. If you need the ability to write indexes or to integrate CAM features with a search engine (for example, to expose a search engine collection through the CAM Content Explorer portlet or the Categorization Manager), you need to implement the Indexing API as explained in this chapter.
334
CAM Architecture
See also:
Chapter 19, Customizing Federated Search, for an explanation of the Federated Search API Technical Library on Vignette Connect (http://connect.vignette.com) for API documentation (javadocs) of the com.epicentric.contentmanagement, com.epicentric.contentmanagement.connect or, and com.epicentric.indexing packages Vignette Portal Content Access Management Administrators Guide for information about configuring CAM, configuring search engine connectors that ship with Portal, and using the CAM portlets Vignette Content Delivery Connector Configuration Guide for information about using CAM to surface content from Vignette Content
CAM Architecture
The CAM framework consists of four layers:
Data Source layer This layer is where the content itself is stored. Data
sources can include the Portal relational database, file systems, and thirdparty CMSs.
Connector layer As the name implies, connectors handle the details of
connecting to the Data Source layer. Each type of data source must have its own connector. Some connectors ship with Portal, including a connector for the Portal content repository (referred to as the MetaStore connector because the content is stored in the Portal MetaStore) and a file system connector.
Application layer This layer can include content delivery mechanisms
such as portlets, JSP files, or other applications, provided that they run in the same JVM/web application as Portal. Vignette supplies an Application layer consisting of out-of-the-box CAM portlets.
Content Management Middleware (CMM) layer This layer is the
intermediary between the Connector layer and the Application layer. It includes two public APIs: Access and Connector. The Access API is the com.epicentric.contentmanagement package, which you can use to create your own Application layer implementations. The Connector API is the com.epicentric.contentmanagement.connectors package, which you can use to implement your own connectors.
335
CAM Architecture
Access API
(com.epicentric.contentmanagement)
CMM layer
Connector layer
Connector 1 Connector 2 Connector n
Capabilities
The CAM architecture is capabilities-based. Connectors use the Connector API to define the capabilities of an underlying CMS; the Access API supports querying and accessing those capabilities. Here is a partial list of the capabilities that the CAM architecture supports:
Properties that are intrinsic to connectors (name, path, size, MIME type,
336
author, document title, document keywords, image width, image height, and so on)
Custom numeric, string, and date properties that you can define yourself Document locking Ability to create, update, rename, copy, move, and delete documents and
folders
Content search and indexing capabilities Workflow control of documents and folders, enabling workflow tasks to be
337
Workflow Support
CAM has built-in support for lightweight workflow control. This system defines workflow as a set of stages, with each stage consisting of a set of tasks. The names, purposes, and functions of stages and tasks are defined by the CAM users. Workflow is exposed through two interfaces of the Access API: com.epicentric.contentmanagement.WorkflowStage and com.epicentric.contentmanagement.WorkflowTask. Folders and documents have methods for verifying that workflow is supported, for retrieving workflow stages, and for checking whether the current user can create documents in a particular folder at a particular workflow stage. In addition, a WritableDocument interface has methods for executing a specified workflow task and for setting the workflow stage or stages that are initially valid for a new document. In the CAM portlets that ship with Portal, tasks are used to move documents from one stage to another, and workflow rules determine which tasks are available to each user. The Portal portlets also support actions (such as copying or moving content) that can be executed when documents enter a new stage.
ContentManager Class
Access to CAM functionality depends on two factors: the underlying connectors and the current users permissions. ContentManager is an abstract class that provides access per user to any number of connectors. You use the getContentManager(User) method of ContentManager to instantiate a separate ContentManager object for each content management user. This object handles errands for its userfor example:
determining which folders and documents the user is allowed to see retrieving folders, documents, the search engine, and mount points (which
define the content folders that are available to the user based on configuration by the CAM administrator)
closing content resources that are no longer needed for the user
338
Example
This section describes a simple class that demonstrates common calls to the Access API. Using the Access API requires retrieving the current user and instantiating a ContentManager for that user:
String username = "Jean Deer"; UserManager userManager = UserManager.getInstance(); User user = userManager.getUser("username", username); ContentManager myCM = ContentManager.getContentManager(user);
The ContentManager object can now be used to retrieve folders and documentsfor example, the folder that is the root of the integrated content management system, the documents in that root folder, a particular folder, and a particular document:
Folder folder = myCM.getRootFolder(); Collection c = folder.getAllDocuments(); Folder folder2 = myCM.getFolder("/local_drive"); doc = myCM.getDocument("/movies/ABeautifulMind.doc");
Note that the parameters for getFolder() and getDocument() above are paths relative to the root folder. Next, if the doc document is writable, two standard properties and two custom properties are set:
if (doc.canWriteProperties()) { WritableDocument wa = (WritableDocument)doc.getWritable(); wa.setCategory("Drama"); wa.setPublicationDate(new Date()); wa.setCustomProperty("rating", "R"); wa.setCustomProperty("sweep", "Good"); }
339
When the ContentManager object is no longer needed, its close() method should be called to release content management resources:
if (myCM != null) { myCM.close(); }
340
Log.info("Error caught by CMSample", e); } } finally { // Free resources. if myCM != null) { myCM.close(); } } } } To run this example: 1 2 3
Compile the class and use the Java jar command to create an archive file. Copy the JAR to the PortalInstallDir/portal/WEB-INF/lib directory. From the PortalInstallDir/bin directory, run the following command:
runs_with_classpath.bat FullyQualifiedClassName (Windows) runs_with_classpath.sh FullyQualifiedClassName (UNIX)
or
Implement the base interfaces required by all connectors. Implement the appropriate capability interfaces. Provide the Portal administrator information to configure the connector.
This section explains each of these steps using custom connector examples.
341
Base Interfaces
All connectors must implement four base interfaces:
ContextAwareConnectorPortal service loaded at run time for
translating Folder paths, such as directory paths of a file system, into content management middleware views of those paths (Note that this interface replaces the Connector interface, which accepted a nowdeprecated com.epicentric.users.User rather than a com.epicentric.user.User.)
ConnectorContextEncapsulation of resources allocated for the
current user.
ConnectorDocumentRead-only document methods. ConnectorFolderRead-only folder methods.
Capability Interfaces
The Connector API includes many interfaces related to specific capabilities. Table 25 categorizes and summarizes these interfaces.
Table 25: Folder, Document, and Connector Capabilities Applies to Capability Folder Document X Connector Interface X PropertyAware (folder and document) PropertyAwareConnector Setting of properties Searching of content Indexing of content Getting the published documents "Published" flag Deleting and renaming X X X X X X X X X WritablePropertyAware1 SearchableConnector Indexable PublicationAwareFolder2 PublicationAwareDocument3 Writable
Querying of properties X
342
Table 25:
Capability Creating documents and subfolders; creating document aliases Storing content Locking and unlocking Generating content URLs by CMM Copying and moving documents or folders
Folder X
Document
X X
Checking connector capabilities Querying of workflow stages Writable workflow stages and tasks Creating documents and cards in workflow stage
1
X X X
X X
WorkflowManagableDocument5 WritableWorkflowAwareFolder8
9
Extends PropertyAware6Extends LockableDocument 2 Extends ConnectorFolder7Extends Movable 3 Extends ConnectorDocument8Extends WorkflowAwareFolder 4 Extends Writable9Extends WritableConnectorFolder 5 Extends WritableConnectorDocument
These capability interfaces have corresponding functionality in the Access API. For example, a connector that can create documents and subfolders implements the WritableConnectorFolder interface of the Connector
343
API, and the methods for creating documents and subfolders are implemented in the WritableFolder interface of the Access API. Similarly, a connector that can query workflow stages for folders and documents implements the WorkflowAwareDocument and WorkflowAwareFolder interfaces of the Connector API, and the methods for performing the workflow queries are found in the Document and Folder interfaces of the Access API. For example:
WorkflowStage stage = null; if (document.supportsWorkflowControl()) { stage = document.getWorkflowStage(); }
Connector Configuration
Once you have implemented all of the interfaces required by your custom connector, you need to provide the system administrator for your Portal installation with the compiled class files and the fully qualified name of the class that implements the ContextAwareConnector interface. The system administrator installs and configures your connector by following the instructions in the PortalInstallDir/config/examples/camproperties.sample file. Here are the properties that are required for a connector:
contentmanagement.default.enumerator.connectorid=uniqueID contentmanagement.default.enumerator.mountpath=/DisplayName contentmanagementconnector.uniqueID.code=fully.qualified.ClassN ame contentmanagementconnector.uniqueID.name=CAM Connector Name contentmanagementconnector.uniqueID.description=CAM Connector Description contentmanagementconnector.uniqueID.rootpath=physicalPathToSour ce See also: Vignette Portal Content Access Management Administrators Guide for discussion of CAM and connector configuration
344
Examples
This section shows the class diagrams for three custom connectors:
Most basic read-only Writable Writable with workflow Read-only Connector
The most basic connector implements nothing but the four required interfaces. The result is a connector that supports read-only folders and documents. Figure 58 shows the four classes that implement this connector.
Figure 58: Most Basic (Read-only) Connector
Interface ConnectorContext
Interface ContextAwareConnector
MyReadOnlyConnector
MyReadConnectorContext
Interface ConnectorFolder
Interface ConnectorDocument
MyReadOnlyFolder
MyReadOnlyDocument
Writable Connector
Suppose a connector supports creating documents and subfolders, storing content in documents, and writing properties. Such a connector would implement the PropertyAware, WritablePropertyAware, PropertyAwareConnector, WritableConnectorFolder, and
345
Interface ContextAwareConnector
Interface PropertyAwareConnector
Interface ConnectorContext
MyWritableConnector
MyWritableContext
Interface ConnectorFolder
Interface PropertyAware
Interface ConnectorDocument
MyReadableFolder
MyReadableDocument
MyWritableFolder
MyWritableDocument
Interface WritableConnectorFolder
Interface WritablePropertyAware
Interface WritableConnectorDocument
Note that MyWritableFolder and MyWritableDocument indirectly extend Writable; therefore, the connector must support document renaming and deleting.
Writable Workflow Connector
The final example, shown in Figure 60, implements the same capabilities as the previous one, plus workflow capabilities.
346
Figure 60:
Interface ContextAwareConnector
MyWorkflowConnector
MyWorklfowContext
Interface ConnectorFolder
Interface PropertyAware
Interface ConnectorDocument
MyReadableFolder
MyReadableDocument
MyWritableWorkflowFolder
MyWritableWorkflowDocument
Interface WritableConnectorFolder
Interface WritablePropertyAware
Interface WritableConnectorDocument
Interface WritableWorkflowAwareFolder
Interface WorkflowManageableDocument
347
As implementations of the Indexing API, search engine connectors can take advantage of many of the benefits of the CAM framework:
Connector architectureOnce developed and tested, a search engine
connector can be used by the CAM framework. It also participates in Vignette federated searches through an out-of-the-box federated search connector and portlet. (See Chapter 19, Customizing Federated Search, for an explanation of the Federated Search architecture. Note that in Portal versions prior to 7.3, federated searching was provided through the Content Search portlet.)
Transparent content indexingCAM synchronizes its content modification
with search/indexing engines by instructing the search engine connectors to add to, update, and remove from the engines.
PermissioningCAM permissions documents and their indexes. CAMs
specific to the content of different repositories. CAM employs the capabilities of the search engine for extracting document metadata, so that the metadata is usable in CAM without having to be reentered.
Taxonomy functionalityThe Categorization Manager administrative
component (available in the Portal server console) provides search-based taxonomy capabilities. The Indexing API consists of two sets of interfaces, one for search and the other for indexing. The indexing-related interfaces extend from the searchrelated interfaces. A particular search engine connector implements the appropriate interfaces as follows:
Search-related interfaces only, enabling the capabilities that are specific to
collection searching
Both the search-related and indexing-related interfaces, enabling collection
searching as well as indexing into the sink collection To use the indexing capabilities of the Indexing API, the underlying search engine must support indexing. (Such a search engine is often referred to as an indexing engine.)
348
Search Interfaces
For a search engine connector to support search, you must implement the following interfaces (see Figure 61):
SearchEngineObject that is responsible for connecting to a search
engine, which can be either a search server (such as Autonomy) or a search web service (such as the Google web service). A search engine can also be indexable.
SearchCollectionCatalog, database, or other collection of document
indexed document. It contains the metadata of the document, including a link to the document content.
Figure 61: Search-Only Search Engine Connector
Interface SearchCollection Interface SearchQuery
Interface SearchEngine
MyEngine
MyCollection
MyQuery
Interface SearchResultSet
Interface SearchResult
MyResultSet
MyDocument
If you want to exclude collections from a search engines search, you can optionally implement an additional interface, HiddenCollectionAwareEngine, and list the collections to be excluded in the Portal configuration file. To retrieve an array of all collections, including
349
Indexing Interfaces
For a search engine connector to support indexing, in addition to the search interfaces you must implement the following interfaces (see Figure 62):
IndexCollectionRepresentation of an indexing collection, which
350
Figure 62:
Interface SearchEngine
Interface IndexCollection
Interface SearchQuery
MyEngine
MyCollection
MyQuery
Interface SearchResult
Interface SearchResultSet
Interface IndexEntry
MyResultSet
MyDocument
The implementation in Figure 62 is for a "parsable" search/indexing engine that is, one that can parse different types of documents (HTML, XML, Microsoft Office, PDF, etc.) for the purpose of extracting metadata. Ultraseek is an example of a parsable indexing engine. Some indexing engines do not support document parsing; or they parse documents but do not return the documents metadata. For such unparsable engines, you must also implement the UnparsableEngine interface (see Figure 63). Autonomys IDOL Server and K2 products are examples of unparsable engines.
351
Figure 63:
Interface UnparsableEngine
Interface SearchEngine
Interface IndexCollection
Interface SearchQuery
MyEngine
MyCollection
MyQuery
Interface SearchResult
Interface SearchResultSet
Interface IndexEntry
MyResultSet
MyDocument
(Note that for a parsable engine implementation, you do not need to do anything in the engine class other than implementing the SearchEngine interface.)
Here is an example of how you can search for the word "Portal" in the body of all documents of a search engines "Default" collection for guest users (site visitors):
352
User guest = //... //retrieves guest user here SearchCollection collection; try { collection = engine.getCollection("Default"); SearchQuery query = engine.createQuery(); query.addCollection(collection); query.addField(SearchQuery.FIELD_BODY, "Portal", SearchQuery.MODIFIER_REQUIRED); query.setSearchContext(new SearchContext(guest)); SearchResultSet rs = query.execute(); int totalResult = rs.getTotalResults(); System.out.println("Total Result = " + totalResult); SearchResult result; while(rs.hasMoreResults()){ result = rs.next(); System.out.println(result.getTitle()); System.out.println(result.getAuthor()); System.out.println(result.getDateLastModified()); } } catch (SearchException e) { e.printStackTrace(); }
353
details depend upon the search engine that youre integrating as well as your specific Portal environment.
To configure a search engine: 1
Specify the required properties for the search engine. Add to the configuration file these three properties that are common to all engines:
indexing_engine.engine_id.code=com.companyname.package.engine _id.EngineClass indexing_engine.engine_id.name=Your Engine Name indexing_engine.engine_id.description=Your Engine Description
Also add the properties needed to connect to the engine, such as the engines host name, port, user name, and password. These connectionrelated properties should be used in the search engines init() method.
2
If you want to exclude certain collections from the searches performed by the engine, add a comma-delimited list of the collections as the value for the following property:
indexing_engine.engine_id.hiddencollections=collection1,colle ction2,collectionn...
For an unparsable indexing engine, add the following property (indicating indexing delay time in minutes):
indexing_engine.engine_id.indexdelay=1
For each CAM connector that is searchable by this engine, enable search by adding the following properties:
contentmanagementconnector.uniqueID.search_engine=engine_id contentmanagementconnector.uniqueID.search_collection=collect ion_id
If you are enabling search of the MetaStore connector, check for the following property, and add it if it does not exist:
contentmanagementconnector.meta.metadata_extraction=true | false
(Note that the Portal installer typically adds the above property and sets it to true.)
354
If CAM indexes content into the engine, then add the following properties:
portal.contentservlet.host=host_name:port portal.contentservlet.protocol=http | https portal.contentservlet.indexing_expiration_interval_millis=nnn nn
The last property above is the timeout value for this search engine connector.
See also:
Connector Configuration on page 344 for a listing of the CAM connector properties PortalInstallDir/config/examples for sample properties for the connectors shipped with Portal Vignette Portal Administrators Guide for information about configuring Federated Search and the search engine connector timeout value Vignette Portal Content Access Management Administrators Guide for discussion of CAM and search/indexing engine configuration
355
Figure 64:
For greater, per-instance control over Story Publishers display capabilities, you can create your own content renderers. All custom renderers that have been deployed are included in a drop-down list, enabling Portal administrators to choose one of them rather than using the default renderer (see Figure 65).
Figure 65: Custom Story Publisher Renderer
356
Vignette Portal Administrators Guide for details about using the administration consoles to instantiate portlets Vignette Portal Content Access Management Administrators Guide for information about configuring Story Publisher
You must name your files as shown in this table, and when you refer to views within your JSPs you must use the view IDs shown above. The reason is that the default JSP is always invoked when one of these views is invoked. The default JSP checks whether a custom renderer was selected for the portlet instance. If so and a custom JSP having the same name as the default JSP is available, then the default JSP performs an include on the custom JSP before returning. Otherwise, the default JSP renders the view. NOTE: An exception is that for the main view, you can use
PortalBeanView.MY_PORTAL_VIEW instead of FRONT_VIEW as the ID.
In your custom JSPs, include only the content for the <BODY> tag; the Vignette Portal framework provides the portlet container and surrounding page.
357
Story Publisher has a set of custom JSP tags for displaying URLs, images, and documents. Table 27 lists and describes each of these tags.
Table 27: Tag Name <content:viewableDocuments> Story Publisher Custom JSP Tags Description Provides access to the documents that the current user can view. Defines a requestscoped viewableDocuments page variable of type Collection that contains zero or more com.epicentric.con tentmanagement.Document objects. Prints the URL of a document to the response, with or without retaining the current site context. (Using this tag without retaining the current site context is equivalent to calling getContentURL(request) on the document.) Prints the URL of a document image to the response. The URL can be absolute; if instead it is relative, it is first resolved. (Using this tag is equivalent to calling getProperty(Attributable.IMAGE _URL)on the document.) Provides access to the document selected by the current user from the list of documents whose URLs were generated by the <printDocumentURL/> tag. Defines a request-scoped selectedDocument page variable of type com.epicentric.con tentmanagement.Document. Used only in the content.jsp view. Prints the transformed content of a document to the response. If Story Publisher caching is enabled, reads the content from the cache. (Using this tag with caching off is equivalent to calling getContent() on the document.)
<content:printDocumentImageURL document="string"/>
<content:selectedDocument>
<content:printDocumentContent document="string"/>
358
Story Publisher is a PortalBean portlet and therefore must also include the PortalBean taglib directive ("module-tags"). In addition, the <mod:view> PortalBean tag must precede any use of Story Publisher tagsfor example:
<%@taglib uri="module-tags" prefix="mod" %> <%@taglib uri="/beans/storypublisher/jsp/taglib/storypub lisher.tld" prefix="content" %> <mod:view class="com.epicentric.portalbeans.beans.storypub lisherbean.ContentView"> <content:viewableDocuments> See also:
Appendix A, Vignette Portal Custom JSP Tag Reference, for additional details about the Story Publisher tags Vignette Application Portal Module Developers Guide for documentation of PortalBean portlets
Examples
<content:printDocumentImageURL/> and <content:printDocumentURL/> tags within the <content:viewableDocuments> tag body to create links to up to five
documents and display their titles, descriptions, and images. The view also provides a link to FULL_VIEW.
<%@ page import="com.epicentric.portalbeans.beans.storypub lisherbean.StoryPublisherBean, com.epicentric.contentmanagement.Document, com.epicentric.contentmanagement.connectors.At tributable, com.epicentric.contentmanagement.ContentExcep tion, com.vignette.portal.util.StringUtils, com.epicentric.portalbeans.PortalBean, com.epicentric.portalbeans.beans.storypublish erbean.Screens, java.util.*" contentType="text/html; charset=UTF-8" %> <%@taglib uri="module-tags" prefix="mod" %> <%@taglib uri="/beans/storypublisher/jsp/taglib/storypub lisher.tld" prefix="content" %>
359
<!-- Create FrontView, or retrieve from request stream --> <mod:view class="com.epicentric.portalbeans.beans.storypub lisherbean.FrontView"> <!-- Start tag providing access to available documents --> <content:viewableDocuments> <% Document doc; int start = 0; int range = 5; int end = start+range; int length = viewableDocuments.size(); if(start start } if(end > end = } >= length){ = 0; length){ length;
List list = new ArrayList(viewableDocuments).subList(start, end); ListIterator iter = list.listIterator(); // Get PortalBean for this view PortalBean bean = view.getBean(); %>
<div> <table> <% // Loop through all documents, collecting properties while(iter.hasNext()){ doc = (Document)iter.next(); %> <% String title = (String)getProperty(doc, Attributable.PROP_TITLE); String desc = (String)getProperty(doc, Attributable.PROP_ABSTRACT); String width = (String)getProperty(doc, Attributable.PROP_IMAGE_WIDTH); String height = (String)getProperty(doc, Attributable.PROP_IMAGE_HEIGHT); if(StringUtils.isEmpty(title)){ title = doc.getName(); } if(StringUtils.isEmpty(desc)){
360
desc = ""; } %> <tr> <td> <% if(!StringUtils.isEmpty(width) && !StringUtils.isEmpty(height)){ %> <!-- Display each documents image (if any) --> <img src="<content:printDocumentImageURL document="<%=doc%>" />" alt="<%=""%>" /> <% } %> <!-- Display link to each document --> <a href="<content:printDocumentURL document="<%=doc%>" inSiteContext="true" documentIndex="<%=iter.nextIndex()-1%>" />" target="_blank"> <%=title%> </a> </td> <td><%=desc%></td> </tr> <% } %> </table> <hr class="epi-HR" size="1" noshade="noshade" /> <!-- Provide link to full view --> <a href="<%= bean.getFullViewURL(Screens.FULL_VIEW) %>" class="epi-menu">View All Content</a> </div> <!-- Close tags --> </content:viewableDocuments> </mod:view> <%! Object getProperty(Document doc, String propertyID){ try{ return doc.getProperty(propertyID); } catch(ContentException ex){ return null; } } %>
361
full.jsp.
This example is very similar to view.jsp, except that it displays links to up to 10 documents, includes Previous and Next links, and provides a link back to the main view.
<%@ page import="com.epicentric.portalbeans.beans.storypub lisherbean.StoryPublisherBean, com.epicentric.contentmanagement.Document, com.epicentric.contentmanagement.connectors.At tributable, com.epicentric.contentmanagement.ContentExcep tion, com.vignette.portal.util.StringUtils, com.epicentric.portalbeans.PortalBean, com.epicentric.portalbeans.PortalBeanView, com.epicentric.portalbeans.beans.storypublish erbean.Screens, java.util.*" contentType="text/html; charset=UTF-8" %> <%@taglib uri="module-tags" prefix="mod" %> <%@taglib uri="/beans/storypublisher/jsp/taglib/storypub lisher.tld" prefix="content" %> <!-- Create ContentView, or retrieve from request stream --> <mod:view class="com.epicentric.portalbeans.beans.storypub lisherbean.ContentView"> <!-- Start tag providing access to available documents --> <content:viewableDocuments> <% Document doc; // Get "start" variable from request, or 0 if nonexistent int start = view.requestInt("start", 0); int range = 10; int end = start+range; int length = viewableDocuments.size(); if(start start } if(end > end = } >= length){ = 0; length){ length;
List list = new ArrayList(viewableDocuments).subList(start, end); ListIterator iter = list.listIterator(); boolean hasNext=false; boolean hasPrevious=false;
362
if(start > 0){ hasPrevious = true; } if(end < length){ hasNext = true; } Hashtable params; // Get PortalBean for this view PortalBean bean = view.getBean(); %> <div> <table> <% // Loop through all documents, collecting properties while(iter.hasNext()){ doc = (Document)iter.next(); %> <% String title = (String)getProperty(doc, Attributable.PROP_TITLE); String desc = (String)getProperty(doc, Attributable.PROP_ABSTRACT); String width = (String)getProperty(doc, Attributable.PROP_IMAGE_WIDTH); String height = (String)getProperty(doc, Attributable.PROP_IMAGE_HEIGHT); if(StringUtils.isEmpty(title)){ title = doc.getName(); } if(StringUtils.isEmpty(desc)){ desc = ""; } %> <tr> <td> <% if(!StringUtils.isEmpty(width) && !StringUtils.isEmpty(height)){ %> <!-- Display each documents image (if any) --> <img src="<content:printDocumentImageURL document="<%=doc%>" />" alt="" /> <% } %> <!-- Display link to each document --> <a href="<content:printDocumentURL document="<%=doc%>" inSiteContext="true"
363
documentIndex="<%=iter.nextIndex()-1%>" />" target="_blank"> <%=title%> </a> </td> <td><%=desc%></td> </tr> <% } %> </table> <hr class="epi-HR" size="1" noshade="noshade" /> <table> <tr> <!-- Provide link back to main view --> <td width="100%" nowrap="nowrap"><a href="<%=bean.getFullViewURL(PortalBeanView.MY_POR TAL_VIEW)%>">Main View</a></td> <td align="right" nowrap="nowrap"> <% // Create Previous and Next links if(hasPrevious){ params = new Hashtable(); params.put("start", String.valueOf(start-range)); %> <a href="<%=bean.getFullViewURL(Screens.FULL_VIEW, params)%>" class="epi-nextPrev">< Prev</a> <% }else{ %> <span class="epi-dim">< Prev</span> <% } %> | <%=end>0?start+1:start%>-<%=end%> of <%=length%> <% if(hasNext){ params = new Hashtable(); params.put("start", String.valueOf(start+range)); %> <a href="<%=bean.getFullViewURL(Screens.FULL_VIEW, params)%>" class="epi-nextPrev">Next ></a> <% }else{ %> <span class="epi-dim">Next ></span>
364
<% } %> </td> </tr> </table> </div> <!-- Close tags --> </content:viewableDocuments> </mod:view> <%! Object getProperty(Document doc, String propertyID){ try{ return doc.getProperty(propertyID); } catch(ContentException ex){ return null; } } %> content.jsp.
<content:printDocumentContent/> tag to display the selected document within the body of the <content:selectedDocument> tag.
<%@ page import="com.epicentric.portalbeans.beans.storypub lisherbean.StoryPublisherBean, com.epicentric.contentmanagement.Document, com.epicentric.contentmanagement.connectors.At tributable, com.epicentric.contentmanagement.ContentExcep tion, com.vignette.portal.util.StringUtils" contentType="text/html; charset=UTF-8" %> <%@taglib uri="module-tags" prefix="mod" %> <%@taglib uri="jstl-tags" prefix="c" %> <%@taglib uri="/beans/storypublisher/jsp/taglib/storypub lisher.tld" prefix="content" %> <!-- Create ContentView, or retrieve from request stream --> <mod:view class="com.epicentric.portalbeans.beans.storypub lisherbean.ContentView"> <!-- Start tag providing access to selected document --> <content:selectedDocument> <div> <table>
365
<% String title = (String)selectedDocument.getProperty(Attributable. PROP_TITLE); if(StringUtils.isEmpty(title)){ title = selectedDocument.getName(); } %> <tr> <td><strong><%=title%></strong></td> <tr> <!-- Display document --> <td><content:printDocumentContent document="<%=selectedDocument%>" /></td> </tr> </tr> </table> </div> <!-- Close tags --> </content:selectedDocument> </mod:view> <%! Object getProperty(Document doc, String propertyID){ try{ return doc.getProperty(propertyID); } catch(ContentException ex){ return null; } } %>
366
In addition, if you internationalized your JSP files, create a WEB-INF/i18n directory and place the default property file (and any locale-specific property files) in it.
See also:
Internationalizing Custom Renderers on page 368 for notes about including I18N code in your JSPs Vignette Application Portal Module Developers Guide for details about creating and uploading PortalBean CAR files
Custom renderers are a shared PortalBean component. The structure of the component.xml file is as follows:
<?xml version="1.0" encoding="UTF-8" ?> <epideploy:component xmlns:epideploy="http://www.epicentric.com/deployment" component-type="ModuleTypes" component-id= "string" major-version="integer" minor-version="integer" build-version="string" title="string" description="string"> <epideploy:detail> <module-config auto-deploy="true" | "false"> <web-deployment-path> file_system_directory </web-deployment-path> <locale-key>unique_ID</locale-key> </module-config> </epideploy:detail> </epideploy:component>
The component-type value must be the literal string "ModuleTypes", which identifies it as a shared PortalBean component. The component-id must be unique among renderers. The title value is displayed in the Story Publisher drop-down list of custom renderers (see Figure 65 on page 356). The <module-config> element is required for a shared component. This element has one attribute: auto-deploy, which controls deployment behavior in the event an earlier version of a component having the same component-id has already been deployed. In such a case, autodeploy="true" causes this component to be deployed, replacing the preexisting component; auto-deploy="false" causes this component to be uploaded into the Portal database and displayed by the PortalBean Manager,
367
but a Portal server administrator must use the PortalBean Manager to explicitly deploy it. (The deployment system uses the major-version and minor-version attributes in this component.xml file to determine the version of this component.) The <web-deployment-path> identifies the path, relative to the Vignette Portal web application, where the JSP files are to be deployed. Here is an example of a component.xml file for a set of custom JSPs named "StoryPublisher_Renderer1":
<?xml version="1.0" encoding="UTF-8" ?> <epideploy:component xmlns:epideploy="http://www.epicentric.com/deployment" component-type="ModuleTypes" component-id= "StoryPublisher_Renderer1" major-version="1" minor-version="10" build-version="0" title="Story Publisher Renderer1" description="Example of a custom renderer"> <epideploy:detail> <module-config auto-deploy="true"> <web-deployment-path> /beans/StoryPublisher_Renderer1/jsp/ </web-deployment-path> <locale-key>32a1b702df957f66f46028118528deb1</localekey> </module-config> </epideploy:detail> </epideploy:component> See also: Vignette Application Portal Module Developers Guide for details about component.xml files for shared components
The Story Publisher portlet includes an I18N properties file that you can access from your custom JSPs using the <mod:i18nValue/> tag. For example:
<mod:i18nValue alias="type" key="MY_PORTAL_VIEW.no_content_message_text" defaultValue="No content available."/>
You can use the PortalBean Manager tool to download the Story Publisher CAR file, which includes its I18N properties file.
368
To access values from your custom renderers properties file, use the <mod:i18nValue/> tag but with the alias matching its locale key:
<mod:i18nValue alias="32a1b702df957f66f46028118528deb1" key="MY_PORTAL_VIEW.no_content_message_text" defaultValue="No content available."/>
The locale key must be unique within the Portal, so you should generate a unique ID and use it as the <locale-key> value in your component.xml file.
See also:
Vignette Application Portal Module Developers Guide for details about internationalizing PortalBeans Chapter 12, PortalBean Portlets, for updated information about I18N tags for PortalBeans
The value for this property must be a comma-separated list of custom renderers. Each renderer is identified by the value of the component-id attribute in its component.xml file. For example:
com.epicentric.portalbeans.beans.storypublisher.customrenderers
= StoryPublisher_Renderer1,StoryPublisher_Renderer2
369
370
21
Summary: Audience: Topics:
Services and Vignette Portal (below) Developing a Configurable Service on page 372 Service Components on page 374 Deploying Services on page 376
371
Such a service can be manipulated through the Service Manager UI of the Portal server console. Beyond these capabilities, there is no relationship between a service and a client applications usage of that service. Like other Portal components, a service is imported through a component archive (CAR file), which includes a component descriptor (component.xml file). The deployment system uploads the data from the component descriptor into the Portal database. The service itself can use any data storage mechanism it chooses: in-memory references, soft or weak references, the MetaStore (Vignette Portals hierarchical data repository), an external database, or its own mechanism. NOTE: The Services API was enhanced in Portal 4.0. As a result, a number of classes were deprecated. This chapter does not discuss these deprecated classes. Any service implemented using the pre-4.0 API does not use the Service Manager capabilities other than the ability to select the default.
See also:
Chapter 13, Portal Services Overview, for a discussion of the MetaStore Vignette Portal Configuration Guide for information about configuring services included with Portal Vignette Portal Administrators Guide for information about using the Service Manager
ServiceController Interface
ServiceController gets the services configuration information, initializes and starts the service, and optionally allows it to be stopped and restarted. You should implement this interface by extending AbstractServiceController, which has three abstract methods:
372
init(), where you initialize your service start(), which is called after init() getServiceInfo(), which returns a string description of the service
The init() method should read configuration values for the service and push configuration state into the service. If anything happens that would prevent the service from functioning, it should throw a ServiceException, thereby making the service unavailable from the Service Manager. The start() method is where you set up thread pools, caches, connection pools, or the like, and where you start any daemon threads used by the service. This method also should throw a ServiceException to cover circumstances that would prevent the service from functioning.
AbstractServiceController returns false for both the supportsStop() and supportsReinitialization() methods and, in its implementations of stop() and restart(), merely throws an UnsupportedOperationException. You therefore need to override these
methods if you want your service to support these capabilities. (Note, however, that the Portal framework does not currently use the stop and restart features.)
Controllable Interface
Controllable enables the Services API to pass configuration information to a service. This interface gets the services ServiceController and has its own init() and start() methods. AbstractControllable the
abstract implementation of this interface, which you should extend instead of implementing Controllable directly has one abstract "factory" method: createController(). This method creates a ServiceController that is held on behalf of your service implementation; it is called only once during the life of an instance of the service.
AbstractControllable implements the init() method by calling createController() followed by init(ServiceConfiguration config) on the services implementation of ServiceController. In the same vein, AbstractControllable implements the start() method by calling start() on the controller.
373
Service Components
Service Components
You can develop and deploy two service-related components: types and implementations. You can also configure and deploy a third kind of component: an instance of a particular service implementation. A service instance component is particularly useful for a configurable service, because you can preconfigure it through its component descriptor.
Service Type
A service type component contains the particular set of interfaces for a service. A service type typically includes one primary interface. If you intend for others to build different implementations of your service, you should include thorough Javadocs of all interfaces that are necessary to fulfill the service types contract. You might also want to provide an "abstract" or "generic" implementation of your service as part of the component archive (CAR file) containing the service type interfaces. Such a semi-implemented service type can provide some functionality on behalf of the implementation developer while also leaving appropriate space for the implementor to perform some specific operations. If you want to restrict what implementors can do with your service, your service type component can be an abstract implementation. Others would then use this implementation as the starting point for their own development. Consider what implementation developers might want to do with your service, but also consider what you do not want them to do. The most restrictive pattern would be to build a full implementation of your services interface(s), allowing others to implement only protected, abstract methods; in all other respects your service would never be directly callable by the client API. This pattern would create, in effect, an API "firewall" for your service. Any service type CAR file should be able to compile independently (with the exception of dependencies on Vignette APIs). Therefore, the service type CAR file must include all classes, interfaces, and exceptions that are referred to directly or indirectly from the service types "interface class." The component descriptor (component.xml file) for a service type provides all of the information required for the Portal deployment system to identify the service version, Java class names, and default I18N property file.
374
Service Components
NOTE: Service types cannot be removed or disabled from the Service Manager.
Service Implementation
A service type may have zero or more service implementations. A service implementation component contains the concrete classes that implement the interface(s) of its service type. The implementation of the primary interface must have a public no-argument constructor (or no explicitly defined constructors, so that the default constructor will be used). If the implementation extends AbstractControllable and AbstractServiceController, the Portal framework controls its lifecycle and can pass configuration information to it. If you want validation of a service implementation before it is initialized and during the configuration process within the Service Manager UI, you can implement the ConfigurationValidator interface. In your validator, walk through the rules about what values can and cannot be used. If a problem is encountered, return false and set localized reason messages, using the Portal formattable API (discussed in Chapter 6, Internationalizing and Localizing Site Components). For example:
public boolean validate(ServiceConfiguration configuration) { boolean valid = true; //ints in a range ValueProperty valueProperty = (ValueProperty)configuration.get("int"); if (valueProperty.getValue() != null) { long val = ((Long)valueProperty.getValue()).intValue(); if (val < -2 || val > 20) { valid = false; valueProperty.setErrorReason(new FormattableString("Must be greater than -2 and smaller than 20.", Locale.US)); } } // ...more tests... return valid; }
The component.xml file for a service implementation provides all of the information required for the Portal deployment system to identify the implementations version, Java class names, and default I18N property file. In addition, definitions of any configurable properties of the implementation are included in component.xml.
375
Deploying Services
Service Instance
A service implementation may have zero or more service instances. A service instance component is one particular instance of a service implementation. The service instance CAR file typically consists of the component.xml file and default I18N property file. The component.xml file contains the ID and other basic information about the instance. For a controllable service, it also contains configuration information. NOTE: A service instance cannot include Java classes or JARs.
Deploying Services
To deploy a service, you create its component descriptor (component.xml file), assemble its files into a component archive (CAR file), and then upload the CAR file into Portal. Each of these tasks is described next.
See also: Chapter 8, Deploying Site Components, for a general discussion of the Portal deployment system
376
Deploying Services
major-version="integer" minor-version="integer" /> <epideploy:detail> ... component-specific detail elements ... </epideploy:detail> </epideploy:component>
The <epideploy:component> element is the parent for all of the other elements of component.xml. Here is a brief description of the attributes of <epideploy:component>:
component-idThe unique ID of the component. This value should be
of values that identify the version of the service (note, however, that the deployment system ignores build-version).
epi-version and epi-buildOldest version of Portal that the service will run on (note that the deployment system ignores epi-build). title and descriptionStrings having a maximum length of 255
above. If a component has dependencies on other components, the <epideploy:component> element must include a child element named <epideploy:required-component/> for each dependency. The attributes of <epideploy:required-component/> uniquely identify the dependency. The <epideploy:component> element must include a child element named <epideploy:detail>. The structure and contents of <epideploy:detail> depend upon the kind of component.
See also: Appendix B, Deployment Reference, for details about every element and attribute in component.xml
377
Deploying Services
The structure of the <epideploy:detail> element for service types is as follows (with required elements and attributes in bold):
<epideploy:detail> <service-type-definition> <short-type-id>string</short-type-id> <locale-key>string</locale-key> <interface-class-name> full.path.to.class </interface-class-name> <diaglet-class-name> full.path.to.class </diaglet-class-name> </service-type-definition> </epideploy:detail>
The <short-type-id> element provides a mnemonic or useful name for the service type. The <interface-class-name> element must specify the fully qualified name of the interface or class. The <locale-key> element specifies the unique ID for the service types I18N property file (if any). The <diaglet-class-name> element is for internal use by Vignette only; it specifies the fully qualified name of the optional diaglet class (which provides diagnostics). The <service-type-definition> element simply encloses these child elements.
Component Details for Service Implementations
The structure of the <epideploy:detail> element for service implementations is as follows (with required elements and attributes in bold):
<epideploy:detail> <service-implementation-definition> <locale-key>string</locale-key> <type-version id="string" major="integer" minor="integer"/> <implementation-class-name> full.path.to.class </implementation-class-name> <diaglet-class-name> full.path.to.class </diaglet-class-name> <configuration-validator-class-name> full.path.to.class </configuration-validator-class-name>
378
Deploying Services
<property-set-definition> <value-property-definition key="string" required="true"|"false" advanced="true"|"false" type="integer"|"decimal"|"boolean"|"date"| "string"> <option-list> <option>string</option> </option-list> <default-value>string</default-value> </value-property-definition> <service-property-definition key="string" required="true"|"false" <service-type>string</service-type> <default-value>string</default-value> </service-property-definition> <indexed-property-set-definition key="string" minimum="integer" maximum="integer"> <property-set-definition> ... any number of value and service property elements ... </property-set-definition> </indexed-property-set-definition> </property-set-definition> </service-implementation-definition> </epideploy:detail>
property file.
<type-version/>Service type and version being implemented. The
379
Deploying Services
<implementation-class-name>Concrete class implementing the interface or abstract class specified in the service types <interfaceclass-name> element. <diaglet-class-name>Subclass of the class specified in the service types <diaglet-class-name> element. <configuration-validator-class-name>Concrete class implementing the ConfigurationValidator interface for this service
implementation.
<property-set-definition>Element enclosing definitions of
configurable properties for this service implementation. Although this element is required, it can be empty.
<value-property-definition>Child element of <propertyset-definition> that identifies a configurable property of this service
implementation. This element is repeated for each configurable property. The attributes identify the key, the type, whether the property is required, and whether the property is "advanced" (for future use in grouping properties together in the UI). The I18N property file should include a key/value pair for each configurable property; otherwise, the Service Manager UI will display the key attribute from component.xml instead.
<option-list>Child element of <value-property-definition>
that encloses a list of predetermined values for a property. The Service Manager displays these values in a drop-down list.
<option>Child element of <option-list> that defines one predetermined value whose type matches that of the parent <valueproperty-definition>. This element is repeated for each predetermined value. If <option-list> is present, at least one <option> is required.
380
Deploying Services
<default-value>Child element of <value-propertydefinition> that defines its default value. <service-property-definition>Child element of <propertyset-definition> that refers to a different service type from the one that
this service implementation uses. This element enables other services (such as a cache) to be configured for use with this service implementation.
<service-type>Child element of <service-propertydefinition> specifying the component ID of another service type. If <service-property-definition> is present, at least one <servicetype> element is required. <default-value>Child element of <service-propertydefinition> that specifies the default service types component ID. <indexed-property-set-definition>Child element of <property-set-definition> defining a set of properties that is
integers optionally specifying the minimum and maximum number of times the property set must be used for the configuration to be valid.
Component Details for Service Instances
The structure of the <epideploy:detail> element for service instances is as follows (with required elements and attributes in bold):
<epideploy:detail> <service-instance> id="string" enabled="true"|"false" > <type-id>string</type-id> <implementation-id>string</implementation-id> <locale-key>string</locale-key> <property-set> <property key="string">string</property> </property-set> </service-instance> </epideploy:detail>
381
Deploying Services
<service-instance>Element that encloses the child elements defining the service instance. The id attribute is a short name for referring to the service instance, and the enabled attribute determines whether the
implementation).
Examples
<?xml version="1.0" encoding="UTF-8"?> <epideploy:component xmlns:epideploy="http://www.epicentric.com/deployment" component-type="Service Types" component-id="com.companyname.ServiceTestType" major-version="1" minor-version="3" build-version="22" title="Test Service Type" description="Classes for the Test Service Type"> <epideploy:detail> <service-type-definition> <short-type-id>testtype</short-type-id> <locale-key> 78126d3eab5441303b9cba40980001ca </locale-key> <interface-class-name> com.companyname.services.TestType </interface-class-name>
382
Deploying Services
component.xml file:
<?xml version="1.0" encoding="UTF-8"?> <epideploy:component xmlns:epideploy="http://www.epicentric.com/deployment" component-type="Service Implementations" component-id="com.companyname.ServiceTestImplementation" major-version="2" minor-version="1" build-version="35" title="Test Service Implementation" description="Classes for Test Service Implementation"> <epideploy:detail> <service-implementation-definition> <locale-key> 5cb295dc3d48dc003b9cba40980001ca </locale-key> <type-version id="com.companyname.ServiceTestType" major="1" minor="3" /> <implementation-class-name> com.companyname.services.TestImplementation </implementation-class-name> <property-set-definition> <value-property-definition required="true" key="string" advanced="true" type="string"> <option-list <option>option 1</option> <option>option 2</option> <option>option 3</option> </option-list> </value-property-definition> <value-property-definition key="int" advanced="true" type="integer"> <default-value>5</default-value> </value-property-definition> <value-property-definition key="dec" required="true"
383
Deploying Services
advanced="true" type="decimal"> </value-property-definition> <value-property-definition key="bool" type="boolean"> <default-value>true</default-value> </value-property-definition> <value-property-definition key="date" type="date" required="true"> </value-property-definition> <service-property-definition key="service"> <service-type>other_service</service-type> <default-value>other_service_id</default-value> </service-property-definition> <indexed-property-set-definition key="ips" maximum="5"> <property-set-definition> <value-property-definition key="string" advanced="true" type="string"> <default-value>option 3</default-value> <option-list> <option>option 1</option> <option>option 2</option> <option>option 3</option> </option-list> </value-property-definition> <value-property-definition key="int" type="integer" required="true"> </value-property-definition> <value-property-definition key="dec" advanced="true" type="decimal"> <default-value>534.2436</default-value> </value-property-definition> <value-property-definition key="bool" advanced="true" type="boolean" required="true"> </value-property-definition> <value-property-definition
384
Deploying Services
key="date" type="date"> <default-value> 12/06/1997 13:34:00 PST </default-value> </value-property-definition> <service-property-definition key="service" required="true"> <service-type>other_service_2</service-type> </service-property-definition> </property-set-definition> </indexed-property-set-definition> </property-set-definition> </service-implementation-definition> </epideploy:detail> </epideploy:component> Service Instance.
file:
<?xml version="1.0" encoding="UTF-8"?> <epideploy:component xmlns:epideploy="http://www.epicentric.com/deployment" component-type="Service Instances" component-id="com.companyname.ServiceTestInstance" major-version="1" minor-version="0" build-version="5" title="Test Service Instance 1" description="Instance of TestImplementation Service"> <epideploy:detail> <service-instance id="test1" enabled="true"> <type-id>com.companyname.ServiceTestType</type-id> <implementation-id> com.companyname.ServiceTestImplementation </implementation-id> <locale-key> e40df694ca768f88db9cba40980001ca </locale-key> <property-set> <property key="string">option 1</property> <property key="dec">123.456</property> <property key="date"> 01/02/2007 10:10:10 GMT </property> <property key="service">the_service_id</property> <property key="ips.0.int">1999</property>
385
Deploying Services
<property key="ips.0.bool">false</property> <property key="ips.0.service"> the_other_service_id </property> </property-set> </service-instance> </epideploy:detail> </epideploy:component>
The files and directories in the CAR file are deployed as described in Table 28.
Table 28: Contents of CAR Files for Services Location in CAR file directory root WEB-INF/classes
Deployment location Loaded in database; not copied to the file system. PortalWebAppDir/WEBINF/classes PortalWebAppDir/WEBINF/lib
Comments This file provides instructions to the deployment system. This directory is for loose .class files. JAR files must be placed in WEB-INF/lib. See the Note on page 387 for information about uploading CAR files that contain JAR files. These files provide localized and default values for display strings.
JAR files
WEB-INF/lib
*.properties
WEB-INF/i18n
386
Deploying Services
All interfaces and classes that a service refers to must be packaged in the CAR file along with the class files of the service type or implementation itself. In fact, given a CAR file for a service type, you should be able to build a client for that service type, even without a specific implementation of that service. Files other than those specified in Table 28, such as image files, JSP files, and other miscellaneous files, are not deployed even if they are packaged in the CAR file. NOTE: In some environments, long paths to Java classes can exceed file system length limitations, causing deployment of loose classes to fail. If this limitation is a potential problem in your environment, create a JAR file that contains the component classes and place this JAR file in the /WEB-INFO/lib directory of the CAR file.
console, then restart the Portal web application. IMPORTANT: Do not use the server consoles Import Components tool to import service CAR files. or
Place the CAR file in the PortalInstallDir/deployment/upload
directory, then restart the Portal web application. NOTE: If your CAR file includes any JAR files, you need to restart the Portal web application twice. The first restart uploads the CAR file and deploys the loose Java classes. The second restart deploys the JAR files. (Loose Java classes require only one restart.)
See also: Vignette Portal Administrators Guide for information about using the Service Manager
387
Deploying Services
388
Appendices
A
Summary: Audience: Topics: See also:
Introduction (below) Web Site Tags on page 392 Story Publisher PortalBean Portlet Tags on page 402 Section I, Portal Site Development, for examples of the use of tags with various types of Portal components Chapter 14, Users and Access Control, for discussion of user management and authentication tags Chapter 20, Using the Content Access Management and Indexing APIs, for discussion of Story Publisher tags Vignette Application Portal Module Developers Guide for discussion of the PortalBean portlet tags
Introduction
A number of custom JSP tags handle functionality required by the Portal framework. Whenever an appropriate tag is available, use the tag instead of Java method calls for the following reasons:
Tags are easier to use than method calls. Using tags requires only an
within the tags can change, but changes are transparent to your code; they do not affect its operability.
Appendices
391
performance. If you use direct method calls instead of tags, you will not benefit from the performance improvements unless you revise your code as well.
<vgn-portal:i18nElement>
Wraps the <vgn-portal:i18nValue/> tag, transforming it into an attribute tag and thereby allowing the application of "begin string" and "end string" to I18N calls. SYNTAX:
<vgn-portal:i18nElement> i18nValue(s) to wrap... </vgn-portal:i18nElement>
392
<vgn-portal:i18nFormat/>
Converts numbers and dates to a localized format. This tag supports short, medium, long, full, and default formats for date and time values; and currency, percent, integer, and decimal formats for number values. SYNTAX:
<vgn-portal:i18nFormat value="string" pattern="string" />
ATTRIBUTES:
value.
pattern. Required. String defining the output format to be used. The following patterns are supported:
date.short, date.medium, date.long, date.full, date.default time.short, time.medium, time.long, time.full, time.default number.currency, number.percent, number.integer, number.decimal
<vgn-portal:i18nFormattableValue/>
Returns a formatted value for the given data. SYNTAX:
<vgn-portal:i18nFormattable id="string" formattable=object beginString="string" endString="string" ignoreAncestors="true" | "false" primary="true" | "false" />
ATTRIBUTES:
id.
Optional. Noninterpreted string that, when present, causes the internationalized value to be stored under this ID as an attribute of the page context object, instead of being printed to the HTML page.
Appendices
393
formattable.
Required. com.epicentric.i18n.format.Formattable object specifying the value to be formatted. Optional. String to be preprended to the localized value.
beginString. endString.
ignoreAncestors.
Optional. Boolean specifying whether any <vgnportal:i18nElement> tag wrapping this tag should be ignored. Defaults to "false".
Optional. Used in conjunction with <vgnportal:i18nElement/>. Boolean specifying whether this tags locale should be used by the <vgn-portal:i18nElement/> tag in a case where
primary.
there are two localizations. APPLIES TO THESE COMPONENTS: Styles, Secondary Pages
<vgn-portal:i18nParam/>
Allows the insertion of a value into a pattern from the <vgnportal:i18nValue> tag, and therefore must be surrounded by one. Pattern strings are of type java.text.MessageFormat. This tag encodes string values unless encode="false". SYNTAX:
<vgn-portal:i18nParam value="string" encode="true" | "false" />
ATTRIBUTES:
value.
portal:i18nValue> tag.
encode. Optional. Boolean specifying whether the string value is to be encoded.
394
<vgn-portal:i18nParams/>
Allows the insertion of multiple values from an Object[] into a pattern from the <vgn-portal:i18nValue> tag, and therefore must be surrounded by one. Pattern strings are of type java.text.MessageFormat. This tag encodes string values from the array unless encode="false". SYNTAX:
<vgn-portal:i18nParams value="<%= Object[] %>" encode="true" | "false" />
ATTRIBUTES:
value. Required. An Object[] containing the parameters to the <vgnportal:i18nValue> tag. encode. Optional. Boolean specifying whether the string values are to be encoded.
<vgn-portal:i18nValue>
Returns a localized value for the given UniquelyIdentifiable (ui) or UID (stringID); uses the given defaultValue if no localized value is found This tag either can be empty, or can enclose <vgn-portal:i18nParam/> or <vgn-portal:i18nParams/> tags. SYNTAXEMPTY FORM:
<vgn-portal:i18nValue id="string" stringID="string" | ui=object key="string" defaultValue="string" beginString="string" endString="string" ignoreAncestors="true" | "false" isHtml="true" | "false" primary="true" | "false" />
Appendices
395
ATTRIBUTES:
id.
Optional. Noninterpreted string that, when present, causes the internationalized value to be stored under this ID as an attribute of the page context object, instead of being printed to the HTML page. Required if ui is not specified. String that represents the UID of the object. This attribute and ui are mutually exclusive. Required if stringID is not specified. UniquelyIdentifiable object.
stringID.
ui.
key. Required. String identifying a particular localizable value in the resource bundle. defaultValue.
Required. String to be displayed if a localized value is not Optional. String to be prepended to the localized value.
found.
beginString. endString.
ignoreAncestors.
Optional. Boolean that indicates whether this tag disregards other tags (such as <vgn-portal:i18nElement>) in which it is wrapped. Defaults to "false". Optional. Obsolete; no longer has any effect.
isHtml. primary.
Optional. Used in conjunction with <vgnportal:i18nElement/>. Boolean specifying whether this tags locale should be used by the <vgn-portal:i18nElement/> tag in a case where there are two localizations. APPLIES TO THESE COMPONENTS: Styles, Secondary Pages
<vgn-portal:includeNavigation/>
Outputs the style or styles for the current navigation. SYNTAX:
<vgn-portal:includeNavigation friendlyID="string" args="<%= map%>" isSecondary="true" | "false" />
396
ATTRIBUTES:
friendlyID.
Required. Case-sensitive, meaningful string identifying the navigation style type. Optional. Map of key-value pairs to be passed to the navigation style.
args.
isSecondary.
Optional. Boolean specifying whether this navigation style is the secondary navigation for the page; applies to grids having a split navigation (two navigation styles: one horizontal and one vertical). Defaults to "false", which means this navigation style is the primary navigation. APPLIES TO THESE COMPONENTS: Grids
<vgn-portal:includePageContent/>
Outputs the content of the current secondary page. SYNTAX:
<vgn-portal:includePageContent args="<%= map%>" />
ATTRIBUTE:
args.
<vgn-portal:includeStyle/>
Outputs the current style. SYNTAX:
<vgn-portal:includeStyle friendlyID="string" args="<%= map%>" panelUID="string" />
ATTRIBUTES:
friendlyID. args.
Appendices
397
panelUID.
Optional; for use with chrome styles. String identifying the UID for the portlet panel. APPLIES TO THESE COMPONENTS: Grids, Secondary Pages
<vgn-portal:inSegment>
Checks whether the current user is a member of the specified user segment and, if so, displays the body content. SYNTAX:
<vgn-portal:inSegment friendlyID="string"> body content... </vgn-portal:inSegment>
ATTRIBUTE:
friendlyID.
<vgn-portal:insertPortletContent/>
Inserts content rendered by a portlet into the page. This tag must be nested within a <vgn-portal:onRenderSuccess> tag. SYNTAX:
<vgn-portal:insertPortletContent />
ATTRIBUTES: None APPLIES TO THESE COMPONENTS: Any JSP page that is part of the Portal web application and that is invoked after both page resolution and site resolution have taken place
398
<vgn-portal:onRenderFailure>
Executes when a portlet fails to render. This tag must be nested within a <vgn-portal:renderPortlet> tag. SYNTAX:
<vgn-portal:onRenderFailure> ...content to be displayed when portlet rendering fails... </vgn-portal:onRenderFailure>
ATTRIBUTES: None APPLIES TO THESE COMPONENTS: Any JSP page that is part of the Portal web application and that is invoked after both page resolution and site resolution have taken place
<vgn-portal:onRenderSuccess>
Executes when a portlet render operation succeeds. This tag must be nested within a <vgn-portal:renderPortlet> tag. SYNTAX:
<vgn-portal:onRenderSuccess> ...content before portlet-rendered content... <vgn-portal:insertPortletContent /> ...content after portlet-rendered content... </vgn-portal:onRenderSuccess>
ATTRIBUTES: None APPLIES TO THESE COMPONENTS: Any JSP page that is part of the Portal web application and that is invoked after both page resolution and site resolution have taken place
<vgn-portal:pageContentTitle/>
Sets the HTML title of the current page, wrapping it within opening and closing HTML <title> tags. If the page is linked to a menu item node, the display format of the title is as follows: Site Name > MenuItemNode Name
Appendices
399
If the page displays a portlet view other than its main view, the format is as follows: Site Name > MenuItemNode Name > Portlet Title For all other cases, the format is as follows: Site Name > Secondary Page Name SYNTAX:
<vgn-portal:pageContentTitle delimiterSymbol="string" />
ATTRIBUTE:
delimiterSymbol.
Optional. Character or string to be used as the delimiter. If not specified, the delimiter is the greater-than symbol (>). APPLIES TO THESE COMPONENTS:
Grids
<vgn-portal:realmSelector/>
Displays a control for selecting from a list of realms. SYNTAX:
<vgn-portal:realmSelector realms=List lastSelectedRealm="string" />
ATTRIBUTES:
realms.
lastSelectedRealm.
Optional. String representing the realm to be selected by default in the drop-down list. APPLIES TO THESE COMPONENTS: Secondary pages that display a list of realms (such as the login page)
<vgn-portal:renderPortlet>
Displays in a portlet window the content that is rendered by a portlet. The rendered content is that received by the call to getContent() on the PortletWindow instance.
400
SYNTAX:
<vgn-portal:renderPortlet portletWindow=object | portletFriendlyID="string"> <vgn-portal:onRenderSuccess> ...content before portlet-rendered content... <vgn-portal:insertPortletContent /> ...content after portlet-rendered content... </vgn-portal:onRenderSuccess> <vgn-portal:onRenderFailure> ...content to be displayed when portlet rendering fails... </vgn-portal:onRenderFailure> </vgn-portal:renderPortlet>
ATTRIBUTES:
portletWindow.
Optional. Object of type com.vignette.portal .portlet.website.PortletWindowBean that is the target of the rendered content. If this attribute is not specified or null, this tag looks for a
APPLIES TO THESE COMPONENTS: Any JSP page that is part of the Portal web application
<vgn-portal:styleBlock/>
Links to a CSS block that is aware of themes, fonts, and colors. SYNTAX:
<vgn-portal:styleBlock templateCSSFile="string" override="true" | "false" />
ATTRIBUTES:
templateCSSFile. override.
Appendices
401
ATTRIBUTE:
document.
com.epicentric.contentmanagement.Document.
<content:printDocumentImageURL/>
Prints to the response the URL for the selected documents image. If the URL is relative, it is resolved and then printed. SYNTAX:
<content:printDocumentImageURL document="string" />
ATTRIBUTE:
document.
com.epicentric.contentmanagement.Document.
<content:printDocumentURL/>
Prints to the response the URL for the selected document, with or without retaining the current site context. SYNTAX:
<content:printDocumentURL document="string" inSiteContext="true" | "false" documentIndex="integer" />
402
ATTRIBUTES:
document.
com.epicentric.contentmanagement.Document.
inSiteContext. Required. Boolean indicating whether this tag retains the current site context. documentIndex.
Required. Integer specifying the index of a document within a list of documents; used to increment or decrement through the list.
<content:selectedDocument>
Defines a request-scoped selectedDocument page variable of type com.epicentric.contentmanagement.Document, which is the document that the user selected. This tag is designed to be used on the CONTENT_VIEW. If it is used on one of the other Story Publisher views, it returns null. It also returns null if the document URL was not generated using the <content:printDocumentURL/> tag. must have access to the PortalBeanView object and therefore must follow the <mod:view> PortalBean tag. SYNTAX:
<content:selectedDocument> other content tags and JSP/HTML code... </content:selectedDocument>
ATTRIBUTES: None
<content:viewableDocuments>
Defines a request-scoped viewableDocuments page variable of type Collection that contains zero or more com.epicentric.contentmanagement.Document objects. This collection represents the documents that the current user can view. This tag must have access to the PortalBeanView object and therefore must follow the <mod:view> PortalBean tag. SYNTAX:
<content:viewableDocuments> other content tags and JSP/HTML code...
Appendices
403
</content:viewableDocuments>
ATTRIBUTES: None
404
B
Summary: Audience: Topics: See also:
Deployment Reference
Provides details about component.xml elements and attributes for Vignette Portal site components and services JSP or Java developers responsible for deploying Vignette Portal components
Component Descriptor Structure on page 406 Detail Elements for Styles, Grids, and Secondary Pages on page 410 Detail Elements for Style Types and Secondary Page Types on page 415 Detail Elements for Service Types on page 420 Detail Elements for Service Implementations on page 423 Detail Elements for Service Instances on page 431 Chapter 8, Deploying Site Components, for a discussion of the Portal component architecture and deployment system Chapter 2, Controlling Navigation and Appearance with Styles, for the procedures for deploying styles and style types Chapter 3, Controlling Page Structure with Grids, for the procedures for deploying grids Chapter 4, Controlling Functionality with Secondary Pages, for the procedures for deploying secondary pages and secondary page types Chapter 10, Deploying a Java Standard Portlet into a Portal Instance, for the procedures for deploying Java standard portlets Chapter 21, Developing and Deploying Custom Services, for the procedures for deploying services Vignette Application Portal Module Developers Guide for deployment procedures related to PortalBean portlets
Appendices
405
The required parent element of all elements is <epideploy:component>. The <epideploy:component> element must include a child element named <epideploy:detail>. If the component is dependent upon any other Portal components, those
<epideploy:component> Element
The <epideploy:component> element is the required parent for all of the other elements and attributes of a component. Every component.xml file must include an opening <epideploy:component> tag and a closing </epideploy:component> tag. The values of four attributes of this element determine the uniqueness of a component: component-id, component-type, major-version, and minor-version. If a CAR file is uploaded into the Portal database where these four values match the values for an existing record in the database, then the data from the new CAR file will replace the existing record.
Syntax
<epideploy:component component-id="string" component-type="string" major-version="integer" minor-version="integer" build-version="string" epi-version="string" epi-build="integer" title="string" description="string" xmlns:epideploy="http://www.epicentric.com/deployment"> ...<epideploy:required-component> elements (if any)... <epideploy:detail> ...component detail elements...
406
Deployment Reference
</epideploy:detail> </epideploy:component>
Attributes of <epideploy:component>
Required. String containing the unique ID for the component. The maximum length of this value is 32 characters; valid characters are a-z, A-Z, 0-9, and _. You can assign any value that suits your purposes, as long as it does not conflict with an existing component-id used by Portal. For components that have primary and (optionally) secondary files, Portal creates a subdirectory whose name matches the value of this attribute; this subdirectory is within the Portal web application and contains the primary and secondary files. For components that are duplicated or created through the administration consoles, Portal generates a unique ID (a 128-bit number in hexadecimal notation) and assigns it as the value of this field.
component-id.
Required. Literal identifying the type of component. The valid values are "Styles", "Grids", "Secondary Pages", "Style Types", "Secondary Page Types", "Service Types", "Service Implementations", and "Service Instances". An auto-generated component type of "Menuitem File Assets" identifies a CAR file that contains a menu item image. This type of CAR file is created when a menu item image is uploaded through the Portal site console.
component-type. major-version.
Required. Integer reflecting the major version for this release of the component. For example, if this CAR file contains the files for version 7.0 of the component, the value of this attribute would be "7". The deployment system uses a combination of this attribute and minor-version to determine the version of this component. If this component has a higher (later) version number than a component already in the system (where the existing component has the same component-id and component-type as this component), then this component will be deployed. A version older than the one already in the system will not be deployed.
minor-version.
Required. Integer reflecting the minor version for this release of the component. For example, if this CAR file contains the files for version 7.0 of the component, the value of this attribute would be "0". Required. String describing the build for this release of the component (for example, "58" or "Build58" or "gold"). The deployment system does not use this attribute in any way; however, it can be helpful in tracing bugs.
build-version.
Appendices
407
epi-version.
Required. String identifying the version of Portal for which this release of the component was developed (for example, "7.0" if the component was developed for Portal 7.0). The component will not be deployed to Portal versions that are prior to the version specified by this attribute.
epi-build. Required. Integer identifying the build number of the Portal version for which this release of the component was developed (for example, "58" for build 58). title.
Required. String providing the component title for display by the deployment system and the administration consoles. The maximum length of this value is 255 characters.
description.
Required. String providing the component description for display by the deployment system and the administration consoles. The maximum length of this value is 255 characters.
Required and fixed. Namespace for the component.xml file. The value of this attribute must be "http://www.epicentric.com/deployment".
xmlns:epideploy.
If the component requires the deployment of other components, an <epideploy:required-component/> element is a required child element defining each dependency. Every component requires one <epideploy:detail> element as a child element of <epideploy:component>.
<epideploy:required-component/> Element
The presence of the <epideploy:required-component/> element indicates that the component being deployed is dependent on one or more other components. This element identifies each component on which the component being deployed is dependent. Unless these dependencies are resolved, the current component will not be deployed. For a style, grid, or secondary page, this element should be included because these components will not work without their style type or secondary page type.
408
Deployment Reference
In the case of style types and secondary page types, the main use of this element is for secondary pages to share common code. The CAR file for such a shared component would consist of the component.xml file and the shared Java classes. This element is emptyit has no child elements.
Syntax
<epideploy:required-component component-type="Style Types"|"Secondary Page Types" component-id="string" major-version="integer" minor-version="integer" />
Attributes of <epideploy:required-component/>
component-type.
Required. Literal identifying the type of component upon which this component is dependent. For a style or grid, the value of this attribute is "Style Types"; for a secondary page component, the value of this attribute is "Secondary Page Types"; for a service component, the value of this attribute is "Service Types"; "Service Implementations", or "Service Instances".
Required. Unique ID of the component upon which the component being deployed is dependent. This value must match the component-id attribute of the required components <epideploy:component> element. For grids, the value of this attribute should be "template0005" (which is the grids style type).
component-id.
Required. Integer reflecting the major version of the component upon which the component being deployed is dependent. For example, if this component requires version 7.0 of another component, the value of this attribute would be "7". The combination of this attribute with the minor-version attribute defines the version of the required component. If the specified version or higher (later) of the required component has not already been deployed, this component will not be deployed.
major-version. minor-version.
Required. Integer reflecting the minor version of the component upon which the component being deployed is dependent. For example, if this component requires version 7.0 of another component, the value of this attribute would be "0".
Appendices
409
<epideploy:detail> Element
The <epideploy:detail> element is a required child element of <epideploy:component>. The component details must be enclosed within opening <epideploy:detail> and closing </epideploy:detail> tags. (An exception is the Menuitem File Assets component type, which has no details and contains only the <epideploy:detail/> tag.) The <epideploy:detail> element has no attributes. The remainder of this appendix describes the <epideploy:detail> child elements for each type of component.
Syntax
<epideploy:detail> ...component-specific elements... </epideploy:detail>
<style-info> Element
The <style-info> element is a required child element of <epideploy:detail> that describes the style, grid, or secondary page. This element must begin with the <style-info> tag and end with the closing </style-info> tag.
Syntax
<style-info id="string" friendly-id="string" title="string" description="string" primary-filename="string" template-uid="string" template-default="true"|"false" apply-template-header="true"|"false" is-system="true"|"false" visible="true"|"false"
410
Deployment Reference
Attributes of <style-info>
Required. String containing the unique ID for the component. This value must be the same as the component-id attribute value of <epideploy:component>.
id. friendly-id.
Optional for a new component, required for component upgrade. String providing a more meaningful identifier than id. If this attribute is not specified, the deployment system uses the components title to create a friendly ID. This string must be unique among all styles, grids, or secondary pages of the same type. Maximum length is 255 characters; valid characters are a-z, A-Z, 0-9, and _.
title.
Optional. String providing the title of this component. If this attribute is not defined, it is set blank.
description.
Optional. String providing the description of this component. If this attribute is not defined, it is set blank. Optional. String identifying the name of the primary JSP file for this component. If this value is supplied, the specified file must exist in the CAR file.
primary-filename.
template-uid. Required. String identifying the components style type or secondary page type. This value must match the <template-info> element, id attribute in the types component.xml file. Typically, this value also matches the value of the component-id attribute of this components <epideploy:required-component/> element. template-default.
Optional; defaults to false. Boolean that specifies whether this component is the default for its type, if a default has not already been set within Portal. Optional; defaults to true; applies only to styles. Boolean that specifies whether the primary JSP file will include the template header file for this styles style type. If this attribute is true and if the components type has a template header file, the deployment system adds a
apply-template-header.
Appendices
411
static include directive to the beginning of the styles primary JSP file. This include directive refers to the template header filefor example, <%@ include file="../template_header.inc" %>. The name of the template header file is specified by the header-filename attribute of the style types component.xml file, <template-info> element.
is-system.
Optional; defaults to false. Boolean that defines whether this component is a system component. All components that are shipped with Portal are system components. The administration consoles do not allow system components to be deleted, modified, or exported.
visible.
Optional; defaults to true. Boolean that defines whether this component is visible in the administration consoles. If this value is true, the component will be included in lists of components of its type. Optional; applies only to secondary pages; defaults to
processing-type.
JSP_BASED. Literal identifying secondary pages that have action classes (defined in the <ACTIONS> element). If the component type is Secondary Pages and the value of this attribute is ACTION_BASED, then the actions
defined for the secondary page are executed; if the value of this attribute is
JSP_BASED, then any actions defined for the secondary page are ignored. For
all components other than secondary pages and secondary page types, the deployment system ignores this attribute.
Child Element of <style-info>
For a secondary page, the <style-info> element can have one child element: <actions>. For styles and grids, <style-info> has no child elements.
<actions> Element
The <actions> element is an optional child element of a secondary page whose processing-type attribute is ACTION_BASED. The contents of this element must be enclosed within opening <actions> and closing </actions> tags. The sequence in which secondary page actions are executed is determined by the order in which they are listed within the <actions> element. If a secondary page is ACTION_BASED but has no <actions> element, it gets all of its actions (if any) from its secondary page type. An ACTION_BASED
412
Deployment Reference
secondary page that has an empty <actions> element (<actions></actions>) will not execute any actions, even if there are actions defined on its secondary page type. The <actions> element has no attributes.
Syntax
<actions> <action id="string" type="PROCESS"|"PRE_DISPLAY"> <class>fully.qualified.ClassName</class> </action> ...any number of additional <action> elements... <group-reference group-id="string"|"INHERIT_ALL" /> ...any number of additional <group-reference> elements... </actions>
The <actions> element can contain any number of <action> elements, including none, and any number of <group-reference> elements, including none.
<action> Element
The <action> element is an optional child element of an <actions> element that applies only to secondary pages and secondary page types. It defines a Java action class. The contents of this element must be enclosed within opening <action> and closing </action> tags.
Syntax
<action id="string" type="PROCESS"|"PRE_DISPLAY"> <class>fully.qualified.ClassName</class> </action>
Appendices
413
Attributes of <action>
Required. String identifying the action. The value of this attribute must be unique within the actions listed within this secondary pages <ACTIONS> element. Maximum length of this value is 64 characters; valid characters are a-z, A-Z, 0-9, -, and _.
id. type.
Required. Literal identifying the type of the action. Valid values are
<class> Element
Each <action> element must contain one, and only one, <class> child element. The <class> element identifies the fully qualified Java class for the action. The contents must be enclosed within opening <class> and closing </class> tags. The <class> element has no attributes and no child elements. Its syntax is as follows:
<class>fully.qualified.ClassName</class>
<group-reference> Element
The <group-reference> element is an optional child element of the <actions> element. It enables a group of actions, or all actions, defined on the secondary page type to be executed for this secondary page. Any <action> elements listed above <group-reference> will have their action classes executed before the actions defined by <group-reference>; any <action> elements listed below <group-reference> will have their action classes executed after the actions defined by <group-reference>. This element is emptyit has no child elements.
Syntax
<group-reference group-id="string"|"INHERIT_ALL" />
414
Deployment Reference
Attribute of <group-reference>
Required. String matching the id attribute of a <group> element within the component.xml file of this components secondary page type. All actions within that group will be inherited by this component. The reserved string "INHERIT_ALL" can be used to inherit all actions from the secondary page type (use of this reserved string does not require inclusion of any <group> elements within the secondary page type).
group-id.
<template-info> Element
The <template-info> element is a required child element of <epideploy:detail> that describes the style type or secondary page type. This element must begin with the <template-info> tag and end with the closing </template-info> tag.
Syntax
<template-info id="string" friendly-id="string" title="string" description="string" type="templatetype_ui_element"| "templatetype_page_content_include"| "templatetype_ui_grid_element"| "templatetype_standard_jsp_include" is-system="true"|"false" visible="true"|"false" allow-guest-access="true"|"false" header-filename="string"> <actions> ...list of actions (secondary page types only)... </actions> </template-info>
Appendices
415
Attributes of <template-info>
Required. String containing the unique ID for the component. This value must be the same as the component-id attribute value of <epideploy:component>.
id. friendly-id.
Optional for a new component, required for component upgrade. String providing a more meaningful identifier than id. If this attribute is not specified, the deployment system uses the components title to create a friendly ID. This string must be unique among all style types and secondary page types that exist in Portal. Maximum length is 255 characters; valid characters are a-z, A-Z, 0-9, and _.
title.
Optional. String providing the title of this component. If this attribute is not defined, it is set blank.
description.
Optional. String providing the description of this component. If this attribute is not defined, it is set blank. Required. Literal identifying the type of component. Valid values are as follows:
"templatetype_ui_element" for a style type other than grid or JSP
type.
include
"templatetype_page_content_include" for a secondary page
type
"templatetype_ui_grid_element" for the grid style type "templatetype_standard_jsp_include" for the JSP include style
type
is-system.
Optional; defaults to false. Boolean that defines whether this component is a system component. All components that are shipped with Portal are system components. The administration consoles do not allow system components to be deleted, modified, or exported.
visible.
Optional; defaults to true. Boolean that defines whether this component is visible in the administration consoles. If this value is true, the component will be included in lists of components of its type. Optional; defaults to true. Boolean that defines whether guests are allowed to access this component. (A guest is a site visitor who either does not have a Portal user account or is not currently logged in.)
allow-guest-access.
416
Deployment Reference
header-filename. Optional; applies only to style types. String that specifies the name of the template header file (if any) for this style type. If this attribute contains a file name, the deployment system uses this attribute in conjunction with the apply-template-header attribute of the styles component.xml file, <style-info> element, to determine which styles of this style type should include the template header. For each style of this style type where apply-template-header="true", the deployment system performs the following condition-checking and processing: Condition Template header file is added to an existing style type. Template header file is deleted for an existing style type. Newer version of an existing template header file is uploaded. Processing A static include directive, which refers to the template header file, is added to the beginning of the primary JSP file for each style of the template headers type. The modified primary JSP files are then redeployed. The static include directive is removed from the primary JSP file for each style of the template headers type. The modified primary JSP files are then redeployed. The primary JSP files time stamp is updated for each style of the template headers type, thereby causing the Portal application server to recompile those files. The primary JSP files are not redeployed.
For a secondary page type, the <template-info> element can have one child element: <actions>. For style types, <template-info> has no child elements.
<actions> Element
The <actions> element is an optional child element of the <templateinfo> element of a secondary page type. The contents of this element must be enclosed within opening <actions> and closing </actions> tags. Secondary pages of this secondary page type can inherit any or all actions defined within this element. If this element does not exist for a particular secondary page type, its secondary pages will have no actions to inherit. The sequence in which a secondary page types actions are executed is determined by the order in which they are listed within the <actions> element.
Appendices
417
The <actions> element can contain any number of <action> elements, including none, and any number of <group> elements, including none.
<action> Element
The <action> element is an optional child element of either an <actions> element or a <group> element for a secondary page type. It defines a Java action class. The contents of this element must be enclosed within opening <action> and closing </action> tags.
Syntax
<action id="string" type="PROCESS"|"PRE_DISPLAY"> <class>fully.qualified.ClassName</class> </action>
Attributes of <action>
Required. String identifying the action. The value of this attribute must be unique within the actions listed within this secondary page types <ACTIONS> element. Maximum length of this value is 64 characters; valid characters are a-z, A-Z, 0-9, -, and _.
id.
418
Deployment Reference
type.
Required. Literal identifying the type of the action. Valid values are
<class> Element
The <class> element is a required child element of an <action> element. Each <action> element must contain one, and only one, <class> element. The <class> element identifies the fully qualified Java class for the action. The contents must be enclosed within opening <class> and closing </class> tags. The <class> element has no attributes and no child elements.
<group> Element
The <group> element is an optional child element of the <actions> element for a secondary page type. It enables a group of actions to be defined so that secondary pages of this type can refer to the actions as a group. Any <action> elements listed above <group> will have their action classes executed before the actions defined by <group>; any <action> elements listed below <group> will have their action classes executed after the actions defined by <group>.
Syntax
<group id="string"> <action id="string" type="PROCESS"|"PRE_DISPLAY"> <class>fully.qualified.ClassName</class> </action> ...any number of additional <action> elements... </group>
Attribute of <group>
id.
Required. String identifying the group. The value of this attribute must be unique within the groups listed within this secondary page types <ACTIONS>
Appendices
419
element. Maximum length of this value is 64 characters; valid characters are a-z, A-Z, 0-9, -, and _.
Child Elements of <group>
The <group> element can contain any number of <action> elements. When a secondary page refers to a group defined in its secondary page type, that secondary page inherits all actions within the group, in the order listed. A secondary page uses its <group-reference> element to refer to a group that is defined with its secondary page type.
<service-type-definition> Element
<service-type-definition> is a required child element of <epideploy:detail>. It describes the service type, including its short ID,
localization identifier, and interface or class that all services of this type should implement.
<service-type-definition> does not have any attributes.
Syntax
<service-type-definition> <short-type-id>string</short-type-id> <locale-key>string</locale-key> <interface-class-name> fully.qualified.ClassName </interface-class-name> <diaglet-class-name> fully.qualified.ClassName </diaglet-class-name> </service-type-definition>
420
Deployment Reference
<service-type-definition> has three required child elements: <short-type-id>, <locale-key>, and <interface-class-name>. It also has one optional element: <diaglet-class-name>.
<short-type-id> Element
<short-type-id> is a required child element of <service-typedefinition> that provides a logical ID, also referred to as the short ID.
Portal uses the short ID to refer to a component within the code. For example, when asked for the name of a service, the Service Manager returns the short ID. The ID is a string that must be unique within components of this type. Typically, you would assign a short ID that is easy to remember. For example, the Portal MetaStore is a service whose <short-type-id> is metastore. The <short-type-id> element has no attributes or child elements. Its syntax is as follows:
<short-type-id>string</short-type-id>
<locale-key> Element
<locale-key> is a required child element of <service-typedefinition>. It provides the unique ID for the I18N property file(s) that
this component uses to support internationalization. This ID is a 128-bit number in hexadecimal notation that is unique across the Portal installation. When creating new components, you must generate this unique ID by executing the com.epicentric.uid.UniqueIDFactory class; the PortalInstallDir\bin\runs_with_classpath.bat (Windows) or PortalInstallDir/bin/runs_with_classpath.sh (UNIX) utility is the simplest way to execute the class. The string from the <locale-key> element must match the beginning of the I18N property file names in the /WEB-INF/i18n directory. The name of the default property file is the <locale-key> value followed by the literal .properties; locale-specific property filenames include the locale identifier (for example, locale-key_fr.properties for French, or localekey_en_US for U. S. English). The <locale-key> element has no attributes or child elements. Its syntax is as follows:
Appendices
421
<locale-key>string</locale-key>
<interface-class-name> Element
<interface-class-name> is a required child element of <servicetype-definition>. It contains the fully qualified name of the interface or class that every service of the type described in this component.xml file
Technically, this element can refer to an abstract or concrete class rather than an interface, but this practice is not advisable. The interface or class that is referred to in the interface-class-name element must be packaged in the CAR file for the service type. Furthermore, all other classes and interfaces that are used by or referred to in the <interface-class-name> element must also be included in the CAR file. For example, the MetaStoreDocument and MetaStoreFolder interfaces, as well as any exceptions or other structures, must be packaged in the CAR file together with the rest of the classes for a MetaStore service type. The <interface-class-name> element has no attributes or child elements. Its syntax is as follows:
<interface-class-name> fully.qualified.ClassName </interface-class-name>
<diaglet-class-name> Element
<diaglet-class-name> is an optional child element of <service-typedefinition> for internal Vignette use only. It contains the name of a class
that the component can use to provide diagnostics. This class must extend
com.epicentric.services.AbstractServiceDiaglet and must have
a no-arguments constructor. There can be only one diaglet per service type. The <diaglet-class-name> element has no attributes or child elements. Its syntax is as follows:
<diaglet-class-name> fully.qualified.ClassName </diaglet-class-name>
422
Deployment Reference
<service-implementation-definition> Element
<service-implementation-definition> is a required child element of <epideploy:detail>. It describes the service implementation, including
version, localization identifier, and interface or class that this component implements. This element does not have any attributes.
Syntax
<service-implementation-definition> <locale-key>string</locale-key> ...<type-version /> element... <implementation-class-name> fully.qualified.ClassName </implementation-class-name> <diaglet-class-name> fully.qualified.ClassName </diaglet-class-name> <configuration-validator-class-name> fully.qualified.ClassName </configuration-validator-class-name> <property-set-definition> ...list of properties... </property-set-definition> </service-implementation-definition>
The following elements are required child elements of this element: <locale-key>, <type-version/>, <implementation-class-name>, and <property-set-definition>. Two other elements are optional child elements of this element: <diaglet-class-name> and <configuration-validator-class-name>.
<locale-key> Element
<locale-key> is a required child element of <serviceimplementation-definition>. It provides the unique ID for the I18N
Appendices
423
property file(s) that this component uses to support internationalization.This ID is a 128-bit number in hexadecimal notation that is unique across the Portal installation. When creating new components, you must generate this unique ID by executing the com.epicentric.uid.UniqueIDFactory class; the PortalInstallDir\bin\runs_with_classpath.bat (Windows) or PortalInstallDir/bin/runs_with_classpath.sh (UNIX) utility is the simplest way to execute the class. The string from the <locale-key> element must match the beginning of the I18N property file names in the /WEB-INF/i18n directory. The name of the default property file is the <locale-key> value followed by the literal .properties; locale-specific property filenames include the locale identifier (for example, locale-key_fr.properties for French, or localekey_en_US for U. S. English). The <locale-key> element has no attributes or child elements. Its syntax is as follows:
<locale-key>string</locale-key>
<type-version/> Element
<type-version/> is a required child element of <serviceimplementation-definition>. Portal uses it to determine what service
Attributes of <type-version/>
Required. String. This attribute must have the same value as the long ID of its service type, specified in the component-id attribute of the <epideploy:component> element of the service type.
id.
Required. Integer. This attribute must have the same value as the major version of its service type, specified in the major-version attribute of the <epideploy:component> element of the service type.
major.
424
Deployment Reference
minor.
Required. Integer. This attribute must have the same value as the minor version of its service type, specified in the minor-version attribute of the <epideploy:component> element of the service type.
<implementation-class-name> Element
<implementation-class-name> is a required child element of <service-implementation-definition>. It is a concrete
MetaStore is an implementation of the MetaStore service type, with an <implementation-class-name> of com.epicentric.metastore.SQLMetaStore. This class, as well as all other classes that are used by or referred to in the
<implementation-class-name> element, must also be included in the CAR file. For example, the SQLMetaStoreDocument and SQLMetaStoreFolder classes, as well as any specialist exceptions or other
structures, must be packaged in the CAR file together with the rest of the classes for a SQL MetaStore service. NOTE: The implementation class referred to in this element must have a noarguments constructor.
<implementation-class-name> has no attributes or child elements. Its
syntax is as follows:
<implementation-class-name> fully.qualified.ClassName </implementation-class-name>
<diaglet-class-name> Element
<diaglet-class-name> is an optional child element of <service-typedefinition> for internal Vignette use only. It contains the name of a class
that the component can use to provide diagnostics. This class must extend
com.epicentric.services.AbstractServiceDiaglet and must have
a no-arguments constructor. There can be only one diaglet per service type.
<diaglet-class-name> has no attributes or child elements. Its syntax is as
follows:
<diaglet-class-name> fully.qualified.ClassName </diaglet-class-name>
Appendices
425
<configuration-validator-class-name> Element
<configuration-validator-class-name> is an optional child element of <service-type-definition>. It contains the name of a class that a component can use to do custom configuration validation. Typically, components that need to perform complex validation of properties would use a custom configuration validator, which must implement com.epicentric.services.ConfigurationValidator and must have a no-arguments constructor.
<configuration-validator-class-name> has no attributes or child
<property-set-definition> Element
<property-set-definition> is a required child element of <serviceimplementation-definition>, although its child elements are optional.
It lists any configurable properties of this service implementation. The ordering of elements within this element determines the order in which the property fields are displayed in the administration consoles. This element does not have any attributes. NOTE: Every property listed in the component.xml file of a service must have a corresponding property key and value pair in the .properties file for internationalization. Otherwise, the Service Manager of the Portal server console will display the key from the XML file instead of a humanreadable string.
Syntax
<property-set-definition> ... <value-property-definition> elements... ... <service-property-definition> elements... ... <indexed-property-set-definition> elements... </property-set-definition>
The following elements may occur zero or more times within the <property-set-definition> element: <value-property-
426
Deployment Reference
<value-property-definition> Element
<value-property-definition> is an optional child element of <property-set-definition>. It describes individual properties of the
service implementation. Note that this element does not provide the values of these properties; it merely lets Portal know that this property exists. There can be more than one <value-property-definition> in a <propertyset-definition>.
Syntax
<value-property-definition key="string" required="true"|"false" advanced="true"|"false" type="integer"|"decimal"|"boolean"|"date"| "string"> ...<option-list> element... <default-value>string</default-value> </value-property-definition>
ATTRIBUTES OF <VALUE-PROPERTY-DEFINTION>
key. Required. String that specifies a unique name for the property, which is used by the service implementation to refer to this property. The key is also used to provide translations for the property name in the internationalization properties file.
NOTE: When assigning property keys, do not use special characters, and limit the length of the key to 32 characters.
required.
Optional. If not specified, defaults to false. Boolean that determines whether users must specify a value for this attribute. Optional; for future use by Portal. If not specified, defaults to
advanced.
false. Boolean that allows Portal to group advanced properties together for
Required. String that specifies in which data type the system stores the property. The data type is one of the following:
Appendices
427
integer (maps to the long data type) decimal (maps to the double data type) boolean date string
The following elements may optionally occur one time each within the <value-property-definition> element: <option-list> and <default-value>.
<option-list> Element
<option-list> is an optional child element of <value-propertydefinition>. It allows Portal administrators to select from a list of
predetermined values for a property. Providing these values makes it easier for users to configure a property. It is also less error-prone than allowing users to enter values manually. Portal displays options as drop-down lists in the Service Manager. The <option-list> element does not have any attributes.
Syntax
<option-list> <option>string</option> ... any number of <option> elements ... </option-list>
<option> Element
<option> is a required child element of <option-list>. It defines a value
that Portal administrators can select for a specific property. The data type of the value must match the data type of the parent <value-propertydefinition>.
428
Deployment Reference
The <option> element does not have any attributes or child elements. Its syntax is as follows:
<option>string</option>
<default-value> Element
<default-value> is an optional child element of <value-propertydefinition> and <service-property-definition>. It enables a
default value to be specified for a property. The Service Manager displays the value of this element if a Portal administrator has not selected a different one or has entered an invalid value. <default-value> does not have any attributes or child elements. Its syntax is as follows:
<default-value>string</default-value>
<service-property-definition> Element
<service-property-definition> is an optional child element of <property-set-definition>. It refers to a service of a different service
type that the current service implementation uses. For example, if a caching service wants to store data in the MetaStore, this property would specify which MetaStore instance the cache is using. There can be more than one <service-property-definition> in a <property-setdefinition>.
Syntax
<service-property-definition key="string" required="true"|"false"> <service-type>string</service-type> <default-value>string</default-value> </service-property-definition>
Attributes of <service-property-definition>
key. Required. String that specifies a unique name for this property. The service implementation uses the key to refer to this property. This attribute is also used to provide translations for the property name in the internationalization properties file.
Appendices
429
required.
Optional. If not specified, defaults to false. Boolean indicating whether this property is required. If the value of this attribute is "true" and the property value is not provided when an instance of this implementation is configured, the Service Manager will not permit the instance to be enabled until a value is provided.
<service-property-definition> has one required child element: <service-type>. Like <value-property-definition>, this element also has one optional child element: <default-value> (see Page 429).
<service-type> Element
<service-type> is a required child element of <service-propertydefinition>. At least one <service-type> element must be included. It provides the long ID of a service typespecifically, its component-id
follows:
<service-type>string</service-type>
<indexed-property-set-definition> Element
<indexed-property-set-definition> is an optional child element of <property-set-definition>. It defines a set of properties that is
repeated for zero or more objects associated with the service. For example, here is a set of three properties that are repeated twice:
connectors.0.name connectors.0.description connectors.0.mountpath connectors.1.name connectors.1.description connectors.1.mountpath
connectors is the key, 0 and 1 are the indices, and name, description, and mountpath are properties defined within the indexed property set (specifically, in the <value-property-definition> elements contained in the <indexed-property-set-definition>).
430
Deployment Reference
A service implementation can have more than one <indexed-propertyset-definition>. However, <indexed-property-set-definition> cannot contain nested <indexed-property-set-definition> elements.
Syntax
<indexed-property-set-definition key="string" minimum="integer" maximum="integer"> <property-set-definition> ... any number of value and service property elements ... </property-set-definition> </indexed-property-set-definition>
Attributes of <indexed-property-set-definition>
key. Required. String that specifies a unique name for the property set, which is used by the service implementation to refer to this set of properties. minimum. Optional. If not specified, defaults to zero. Integer that indicates the minimum number of times the property set must be used for the configuration to be valid. maximum. Optional. If not specified, defaults to infinity. Integer that indicates the maximum number of times the property set must be used for the configuration to be valid.
<indexed-property-set-definition> contains one, and only one, <property-set-definition>. (See Page 426 for details about the <property-set-definition element.)
Appendices
431
<service-instance> Element
<service-instance> is a required child element of <epideploy:detail>. It describes the configuration of the service
instance, including its short ID, localization identifier, and the long ID of the service type and service implementation that this instance belongs to.
Syntax
<service-instance> id="string" enabled="true"|"false"> <type-id>string</type-id> <implementation-id>string</implementation-id> <locale-key>string</locale-key> <property-set> <property key="string">string</property> ... any number of <property> elements ... </property-set> </service-instance>
Attributes of <service-instance>
id.
Required. String that defines the short ID of the service instance, which Portal uses to refer to the instance in code. Optional. If not specified, defaults to false. Boolean that determines whether the instance is automatically enabled when deployed.
enabled.
This element has four required child elements: <type-id>, <implementation-id>, <locale-key>, and <property-set>.
<type-id> Element
<type-id> is a required child element of <service-instance>. It is the
long ID of the service type this service instance belongs to. It must match the component ID of the applicable type, which is the same as the type for the associated implementation. This element has no attributes or child elements. Its syntax is as follows:
<type-id>string</type-id>
432
Deployment Reference
<implementation-id> Element
<implementation-id> is a required child element of <serviceinstance>. It is the long ID of the service implementation this service
instance belongs to. It must match the component ID of the applicable implementation. This element has no attributes or child elements. Its syntax is as follows:
<implementation-id>string</implementation-id>
<locale-key> Element
<locale-key> is a required child element of <service-instance>. It
provides the unique ID for the property file(s) that this component uses to support internationalization. This ID is a 128-bit number in hexadecimal notation that is unique across the Portal installation. When creating new components, you must generate this unique ID by executing the com.epicentric.uid.UniqueIDFactory class; the PortalInstallDir\bin\runs_with_classpath.bat (Windows) or PortalInstallDir/bin/runs_with_classpath.sh (UNIX) utility is the simplest way to execute the class. The string from the <locale-key> element must match the beginning of the I18N property file names in the /WEB-INF/i18n directory. The name of the default property file is the <locale-key> value followed by the literal .properties; locale-specific property filenames include the locale identifier (for example, locale-key_fr.properties for French, or localekey_en_US for U. S. English). This element has no attributes or child elements. Its syntax is as follows:
<locale-key>string</locale-key>
<property-set> Element
<property-set> is a required child element of <service-instance>,
although its child elements are optional. It lists the properties of the service instance. These properties are a subset of those defined in the <propertyset-definition> element of the service implementation.
<property-set> does not have any attributes.
Appendices
433
Syntax
<property-set> ... any number of <property> elements ... </property-set>
<property> Element
<property> is an optional child element of <property-set>. It defines a property of the service instance and provides a value for the property; it is a key-value pair. <property> is an empty elementit has no child elements.
Syntax
<property key="string">string</property>
Attribute of <property>
Required. String containing the value of key, which is the name of the property. It must match the key attribute of one of the <value-propertydefinition> elements in the service implementation that the instance belongs to.
key.
434
Deployment Reference
C
Summary: Audience: Topics: Note:
AJAX Library (below) Generic Functions on page 437 Drag-and-Drop Functions on page 441
AJAX Library
sendForm
Sends the data of an HTML form using the forms attributes (such as action or method), and invokes the callback method. SYNTAX:
sendForm(formNodeValue, callbackMethod)
PARAMETERS:
formNodeValue. callbackMethod.
EXAMPLE:
new VignettePortal.AJAXClient().sendForm(document.forms[InputS uggestions'],<%=callbackFunction%>);
Appendices
435
AJAX Library
sendMultiPartForm
Sends the multipart data of an HTML form using the forms attributes (such as action or method), and invokes the callback method. SYNTAX:
sendMultiPartForm(formNodeValue, callbackMethod, responseMimeType)
PARAMETERS:
formNodeValue. callbackMethod.
responseMimeType.
MIME type of the response. Default is text/plain. Other supported MIME types are text/html and text/javascript.
EXAMPLE:
new VignettePortal.AJAXClient().sendMultiPartForm(document.form s['FileUpload'],<%=callbackFunction%>,text/html );
sendURL
Makes an AJAX-style request to a server URL and invokes the callback method. SYNTAX:
sendURL(url, callbackMethod)
PARAMETERS:
url.
callbackMethod.
EXAMPLE:
new VignettePortal.AJAXClient().sendURL("<%=AJAXUrl%>","<%= autoCompletecallbackFunction %>");
436
Generic Functions
Generic Functions
appendToHandler
Appends the function(s) in the string sFunctions to a handler sHandler. SYNTAX:
appendToHandler(sHandler,sFunctions);
EXAMPLE:
appendToHandler("onload", "runThisOnLoad()"); appendToHandler("onresize", "runThisOnResize()");
cm_bwcheck
Provides option definitions for the client browser object. The results are stored in the client browser object, bw, for use by other functions. SYNTAX:
cm_bwcheck();
EXAMPLE:
var bw=(bw?bw:(new cm_bwcheck()));
cm_makeObj
Provides the Div or Layer object constructor. SYNTAX:
cm_makeObj(obj,nest,o);
EXAMPLE:
var o = new cm_makeObj("myDiv");
cm_makeObj.prototype.clipTo
Appendices
437
Generic Functions
PARAMETERS:
t. r. b. l.
Objects y pixels from the top of the page. Objects x pixels from the left margin of this object. Objects y pixels from the top margin of this object. Objects x pixels from the left of the page. Objects width and height to the clip size.
setwidth.
cm_makeObj.prototype.getHeight
cm_makeObj.prototype.getLeft
cm_makeObj.prototype.getTop
cm_makeObj.prototype.getWidth
438
Generic Functions
cm_makeObj.prototype.hideIt
cm_makeObj.prototype.moveIt
cm_makeObj.prototype.setCssClass
cm_makeObj.prototype.setHeight
cm_makeObj.prototype.setLeft
cm_makeObj.prototype.setTop
Appendices
439
Generic Functions
cm_makeObj.prototype.setWidth
cm_makeObj.prototype.showIt
cm_page
Provides the Page object constructor. SYNTAX:
cm_page();
EXAMPLE:
var p = new cm_page();
_getPageOffsetLeft
Gets a page elements starting X-axis location on the page (from left, in pixels) on the client browser. SYNTAX:
_getPageOffsetLeft(objElement);
_getPageOffsetTop
Gets a page elements starting Y-axis location on the page (from top, in pixels) on the client browser. SYNTAX:
_getPageOffsetTop(objElement);
440
Drag-and-Drop Functions
Drag-and-Drop Functions
cm_scrolldown
Scrolls down from y1 to y2. The scrolling speed is predefined by the global variable, SCROLL_SPD. SYNTAX:
cm_scrolldown(y1,y2);
cm_scrollleft
Scrolls left from x1 to x2. The scrolling speed is predefined by the global variable, SCROLL_SPD. SYNTAX:
cm_scrollleft(x1,x2);
cm_scrollright
Scrolls right from x1 to x2. The scrolling speed is predefined by the global variable, SCROLL_SPD. SYNTAX:
cm_scrollright(x1,x2);
cm_scrollup
Scrolls up from y1 to y2. The scrolling speed is predefined by the global variable, SCROLL_SPD. SYNTAX:
cm_scrollup(y1,y2);
Column
Provides the Column object constructor for DHTML page rendering.
Appendices
441
Drag-and-Drop Functions
SYNTAX:
Column(divID,width,modType,spcBtwCols,btmSpace,absPos, miniHeight,topSpace,toChildWidth);
PARAMETERS:
divID.
ID of the DIV element on the page body that this Column object is going to represent.
width.
Width in percent or pixels for this Column object to be set to when it is rendered. Portlet type: MOD_FIX=0 or MOD_DRG=1. Spacing between this Column and its neighboring columns.
modType.
spcBtwCols. btmSpace.
Amount of space between the last child and the bottom of this
Whether this Column is the outermost column (1) or not (0). Only the outermost column sets absPos to 1. The rest should always be set to 0. Minimum height of this Column when it is rendered.
miniHeight. topSpace.
Amount of space between the first child and the top of this Column when it is rendered
Whether this Column should be rendered to its own width (0) or adjusted to its childrens widths (1).
toChildWidth.
Column.prototype.addIndicator
Column.prototype.addRow
442
Drag-and-Drop Functions
Column.prototype.insertRow
Inserts the specified row at the index location in this Column object. SYNTAX:
insertRow(row,index);
Column.prototype.render
Column.prototype.setIndicatorLoc
PARAMETERS:
l. t. w.
Left location=true (1) or false (0). Top location=true (1) or false (0). Width=true (1) or false (0).
Row
Provides the Row object constructor for DHTML page rendering. SYNTAX:
Row(divID, width, modType, anchorId, spcBtwRows, sameChildH, equalDist, endItem);
PARAMETERS:
divID.
ID of DIV element on the page body that this Row object is going to represent.
width.
Width in percent or pixels for this Row object to be set to when it is rendered.
Appendices
443
Drag-and-Drop Functions
modType. anchorId.
Portlet type: MOD_FIX=0, MOD_DRG=1, or MOD_NOT=2. ID of the element inside the DIV for activating the dragging Spacing between this Row and its neighbor rows.
operation.
spcBtwRows. sameChildH.
Whether this Row should render all its children to the same height (1) or not (0). Whether this Row should equally space its children (1) or not (0).
equalDist. endItem.
Row.prototype.addColumn
Row.prototype.addIndicator
Row.prototype.render
Renders this Row object as well as its child objects, optionally using a fixed width. SYNTAX:
render(left,top,fixw);
Row.prototype.setIndicatorLoc
444
Drag-and-Drop Functions
PARAMETERS:
l. t. w.
Left location=true (1) or false (0). Top location=true (1) or false (0). Width=true (1) or false (0).
Appendices
445
Drag-and-Drop Functions
446
D
Summary: Audience: Topics: See also:
Font and Color Settings in the Administration Consoles (below) Vignette Portal Type Selectors on page 449 Vignette Portal CSS Classes (Class Selectors) on page 450 Mapping of Theme Settings to CSS Classes on page 464 Deprecated Classes on page 483
Chapter 5, Using Cascading Style Sheets, for discussion of Vignette Portal CSS
Appendices
447
Figure 67:
448
HTML Element Body font settings BODY, PRE, TR, TD, TH, P
Body Font Normal Size Body Text None. Hardcoded (normal). None. Hardcoded (0px). None. Hardcoded (1em). None. Hardcoded (bold).
margin-top margin-bottom
TH
font-weight
Standard link colors and treatment A:link color text-decoration A:visited color text-decoration A:active, A:hover color text-decoration select, textarea font-family font-size color Normal Links: Normal Underline normal links Normal Links: Visited Underline normal links Normal Links: Hover None. Hardcoded (underline). Body Font Normal Size Input Field Text fontColor.linkNormal textDecoration.linkNormal fontColor.linkVisited textDecoration.linkNormal fontColor.linkHover N/A font.body.face font.body.normal fontColor.formField bgColor.formField
Appendices
449
Table 29:
Type Selectors Defined for Vignette Portal (Continued) Theme Property HTML Property (in UI) Theme Property (in Code)
HTML Element
Miscellaneous: Link colors and treatment for horizontal rules and bullets HR color height LI padding Line Breaks, Horizontal Rules (<hr>) None. Hardcoded (1px line). None. Hardcoded (2em line). color.hr N/A N/A
GUI element. For example, the Fonts and Colors page does not contain a theme setting for Section Title Background. Instead, .epi-sectionTitleBG is controlled by the Content Block Background theme setting.
Table 30: Mapping of CSS Classes to Theme Properties HTML Property Theme Property (in UI) Theme Property (in Code)
CSS Class Basic portlet settings .portlet-font, .portlet-section-body, .portlet-section-footer, .portlet-section-text, .portlet-table-text
450
Table 30:
Mapping of CSS Classes to Theme Properties (Continued) HTML Property Theme Property (in UI) Theme Property (in Code)
CSS Class Page background color epi-pageBG Normal Font Settings epi-font, wsui-font
bgColor.page
Body Font Normal Size Body Text Body Font Small Size Body Text Body Font Large Size Body Text None. Hardcoded (bold). Underline Links
font.body.face font.body.normal fontColor.bodyText font.body.face font.body.small fontColor.bodyText font.body.face font.body.large fontColor.bodyText N/A textDecoration.headlineNormal
epi-fontSm, wsui-font-small
epi-fontLg, wsui-font-large
font-weight textdecoration
Navigational trails epi-trail, wsui-trail (Figure 69) font-family font-size color font-weight marginbottom Title, Trail Font Trail Size Navigation Trail: Normal None. Hardcoded. None. Hardcoded (0px). font.title.face font.title.trail fontColor.trailActive N/A N/A
Appendices
451
Table 30:
Mapping of CSS Classes to Theme Properties (Continued) HTML Property font-family font-size color font-weight marginbottom Theme Property (in UI) Title, Trail Font Trail Size Navigation Trail: Active None.Hardcoded (bold). None. Hardcoded (0px). Theme Property (in Code) font.title.face font.title.trail fontColor.trailActive N/A N/A
Page titles, subtitles, and subsection titles epi-pageTitle, wsui-page-title, portlet-section-header (Figure 70) font-family font-size color font-weight marginbottom epi-sectionTitle, wsui-section-title, portlet-section-subheader, portlet-form-label (Figure 70) font-family font-size color font-weight epi-sectionTitleBG (Figure 70) Error and warning messages epi-error, wsui-error, portlet-msg-error, portlet-msg-alert font-family font-size color Body Font Normal Size Error & Warning Messages font.body.face font.body.normal fontColor.error Title, Trail Font Page Size Page and Section Titles None. Hardcoded (bold). None. Hardcoded (0px). Title, Trail Font Section Size Page and Section Titles None. Hardcoded (bold). font.title.trail font.title.page fontColor.title N/A N/A font.title.trail font.title.section fontColor.title N/A bgColor.contentBlock
452
Table 30:
Mapping of CSS Classes to Theme Properties (Continued) HTML Property Theme Property (in UI) Theme Property (in Code)
Inactive links, footnotes, subtle text, and other dimmed text epi-dim, wsui-dim, portlet-font-dim (Figure 71) Menu links (For links that behave like menu items and do not have a unique visited color. Place class in the HREF tag.) epi-menu, wsui-menu (Figure 72) A.epi-menu, A.wsui-menu color color textdecoration A.epi-menu:hover, color A.wsui-menu:hover, A.wsui-menu-current:hover textdecoration epi-menuOn, wsui-menu-current (Figure 72) A.epi-menuOn, A.wsui-menu-current color font-weight color font-weight epi-menuOn.hover, wsui-menu-current. hover color textdecoration Other Links: Normal, Visited Other Links: Normal, Visited Underline menu and pagination links Other Links: Active, Hover None. Hardcoded (underline). Other Links: Normal, Visited None. Hardcoded (bold). Other Links: Normal, Visited None. Hardcoded (bold). Other Links: Active, Hover None. Hardcoded (underline). fontColor.menu fontColor.menu textDecoration.linkMenu fontColor.menuActive N/A fontColor.menuActive N/A fontColor.menu N/A fontColor.menuActive N/A color De-emphasized/Dimmed Text fontColor.dim
Appendices
453
Table 30:
Mapping of CSS Classes to Theme Properties (Continued) HTML Property Theme Property (in UI) Theme Property (in Code)
(No unique visited color. Place class in the HREF tag. Inactive pagination links use .epi-dim.) epi-nextPrev (Figure 71) color textdecoration epi-nextPrev:hover color textdecoration Button links (For links that behave like buttons and that do no have a distinct visited color) epi-buttonLink (Figure 73) color textdecoration epi-buttonLink:hover color textdecoration HTML buttons (for Submit, Reset, Cancel, Update, and other HTML buttons) epi-button, portlet-form-button (Figure 74) font-family font-size color Body Font Normal Size Button Text font.body.face font.body.normal fontColor.button bgColor.button Other Links: all values Underline links that behave like buttons (none/underline) Other Links: Active, Hover None. Hardcoded (underline). fontColor.menu textDecoration.linkButton Other Links: Normal, Visited Underline links that behave like buttons (none/underline) Other Links: Active, Hover None. Hardcoded (underline). fontColor.menu text-decoration.linkMenu
fontColor.menuActive N/A
fontColor.menuActive N/A
454
Table 30:
Mapping of CSS Classes to Theme Properties (Continued) HTML Property Theme Property (in UI) Theme Property (in Code)
(for input fields, text areas, pull-down menus) epi-input, portlet-form-input-field (Figure 74) font-family font-size color Body Font Normal Size Input Field Text font.body.face font.body.normal fontColor.formField bgColor.formField
background- Input Field Background color Form elements (for tables used in form layouts, and for labels that identify form fields) epi-formTable padding-top paddingbottom epi-formTable Table epi-spacerCell TD epi-formLabel, wsui-form-label, portlet-form-field-label, portlet-icon-label, portlet-dlg-icon-label (Figure 74) font-size Height font-weight text-align paddingright None. Hardcoded (.25em). None. Hardcoded (.25em). None. Hardcoded (0px). None. Hardcoded (1em). None. Hardcoded (bold). None. Hardcoded (left). None. Hardcoded (5px).
Table rows that behave like horizontal rules (i.e. using spacer GIFs). Note that horizontal rules are covered by type selectors. epi-lineBreak background- Line Breaks, Horizontal color Rules (<hr>) color.hr
Appendices
455
Table 30:
Mapping of CSS Classes to Theme Properties (Continued) HTML Property Theme Property (in UI) Theme Property (in Code)
(used only for tables that display data in tabular form, not for layout tables) epi-dataTable, wsui-table, portlet-table-body (Figure 75) borderbottom border-left Data Tables Border (Border style and width hardcoded to "solid, 1px") Data Tables Border (Border style and width hardcoded to "solid, 1px") Data Tables Border (Border style and width hardcoded to "solid, 0px") Column Header Text bgColor.dataTable
bgColor.dataTable
border-right
bgColor.dataTable
color
background- Column Header color Background border-top Data Tables Border (Border style and width hardcoded to "solid, 1px") Data Tables Border (Border style and width hardcoded to "solid, 1px") None. Hardcoded (5px). Column Header Text None. Hardcoded (none). Sorted Column Header Text
border-right
bgColor.dataTable
padding epi-dateTable TH A, wsui-table TH A, portlet-table-header A epi-dataTable TH.epi-rowHeadSorted, epi-dataTable TH.epi-rowHeadSorted A color textdecoration color
background- Sorted Column Header color Background textdecoration Underline menu and pagination links (none/underline).
456
Table 30:
Mapping of CSS Classes to Theme Properties (Continued) HTML Property border-top Theme Property (in UI) Data Tables Border (Border style and width hardcoded to "solid, 1px") Data Tables Border (Border style and width hardcoded to "solid, 1px") None. Hardcoded (3px). None. Hardcoded (3px). None. Hardcoded (5px). None. Hardcoded (0px). None. Hardcoded (22px). None. Hardcoded (0px). None. Hardcoded (0px). Theme Property (in Code) bgColor.dataTable
border-right
bgColor.dataTable
padding-top paddingbottom padding-left paddingright epi-dataTable epi-padRight epi-dataTable epi-embeddedTable TD Data table "lite" settings paddingright border padding
(For tables that display data in tabular form, not for layout tables. Rarely used.) epi-dataTableLite borderbottom border-left Data Tables Border (Border style and width hardcoded to "solid, 1px") Data Tables Border (Border style and width hardcoded to "solid, 1px") Data Tables Border (Border style and width hardcoded to "solid, 0px") bgColor.dataTable
bgColor.dataTable
border-right
bgColor.dataTable
Appendices
457
Table 30:
Mapping of CSS Classes to Theme Properties (Continued) HTML Property color Theme Property (in UI) Column Header Text Theme Property (in Code) fontColor.rowHead bgColor.dataTable bgColor.dataTable
background- Column Header color Background border-top Data Tables Border (Border style and width hardcoded to "solid, 1px") Data Tables Border (Border style and width hardcoded to "solid, 1px") None. Hardcoded (5px). Column Header Text None. Hardcoded (none). Data Tables Border (Border style and width hardcoded to "solid, 1px") Data Tables Border (Border style and width hardcoded to "solid, 1px") None. Hardcoded (3px). None. Hardcoded (3px). None. Hardcoded (5px). None. Hardcoded (5px). None. Hardcoded (22px). None. Hardcoded (0px). None. Hardcoded (0px).
border-right
bgColor.dataTable
border-right
bgColor.dataTable
padding-top paddingbottom padding-left paddingright epi-dataTableLite epi-padRight epi-dataTableLite epi-embeddedTable TD paddingright border padding
458
Table 30:
Mapping of CSS Classes to Theme Properties (Continued) HTML Property Theme Property (in UI) Theme Property (in Code)
(For tables that display hierarchical data in tabular form, such as a list of nested folders. Do not use for layout tables.) epi-dataTree (Figure 76) border Data Tables Border (Border style and width hardcoded to "solid, 1px") Column Header Text bgColor.dataTable
epi-dataTree TH
color
background- Column Header color Background borderbottom padding-top paddingbottom epi-dataTree TH A color textdecoration epi-dataTree epi-padding padding-left paddingright epi-dataTree epi-padLeft epi-dataTree, epi-embeddedTable TD padding border padding Data Tables Border (Border style and width hardcoded to "solid, 1px") None. Hardcoded (3px). None. Hardcoded (3px). Column Header Text None. Hardcoded (none). None. Hardcoded (5px). None. Hardcoded (5px). None. Hardcoded (0px 0px 0px 3px). None. Hardcoded (0px). None. Hardcoded (0px).
Appendices
459
Table 30:
Mapping of CSS Classes to Theme Properties (Continued) HTML Property Theme Property (in UI) Theme Property (in Code)
(For simulating the effect of a data tables header row. Not necessary if using <th> within a data table or data tree.) epi-rowHead, wsui-table-row-header color font-weight Column Header Text None. Hardcoded (bold). fontColor.rowHead N/A bgColor.rowHead N/A N/A fontColor.rowHead N/A
background- Column Header color Background padding-top paddingbottom epi-rowHead A, wsui-table-row-header A color textdecoration Data table and data tree "special" row colors None. Hardcoded (3px). None. Hardcoded (3px). Column Header Text None. Hardcoded (none).
(For creating alternating row color effect in tables used to present tabular data. Place in the <tr> tag.) epi-rowSpecial1, color Special Row Text wsui-table-row-sectionhead background- Special Row 1 Text er, portlet-table-subheader color Background (Figure 77) epi-rowFooter, .portlet-table-footer (Figure 77) epi-rowEven, wsui-table-row-even, portlet-table-alternate (Figure 77) epi-rowOdd, wsui-table-row-odd, portlet-table-body (Figure 77) color Footer Row Text fontColor.rowSpecial1 bgColor.rowSpecial1 fontColor.rowFooter bgColor.rowSpecial2 bgColor.rowEven
background- Footer Row Background color background- Even Row Background color
bgColor.rowOdd
460
Table 30:
Mapping of CSS Classes to Theme Properties (Continued) HTML Property color Theme Property (in UI) Highlighted Row Text Theme Property (in Code) fontColor.rowHighlight bgColor.rowHighlight
CSS Class epi-rowHighlight, epi-rowHighlight TD, epi-rowHighlight TD A, portlet-table-selected, portlet-table-selected A epi-dataTableBorder Content blocks
background- Highlighted Row color Background background- Data Tables Border color
bgColor.dataTable
(used to set off large areas of content that require a separate color) epi-block (Figure 78) background- Content Block Background color border wsui-block-bgcolor epi-blockBorder Content Block Border bgColor.contentBlock color.contentBlock bgColor.contentBlock bgColor.contentBlock
background- Content Block Background color background- Content Block Background color
Portlet chrome, page, and alignment classes epi-chromeHeader font-family font-size color Body Font NormalSize Chrome Header Text font.title.face font.body.normal fontColor.chromeHeader bgColor.chromeHeader bgColor.chrome bgColor.chromeBorder
background- Chrome Header color Background epi-chromeBG epi-chromeBorder Generic colors (For custom styles and custom secondary pages) epi-BG1 background- Background 1 color background- Chrome Body Background color background- Chrome Border color
bgColor.bg1
Appendices
461
Table 30:
Mapping of CSS Classes to Theme Properties (Continued) HTML Property Theme Property (in UI) Theme Property (in Code) bgColor.bg2 bgColor.bg3 bgColor.bg4 font.font1.face font.font1.size fontColor.font1 font.font2.face font.font2.size fontColor.font2 font.font3.face font.font3.size fontColor.font3 font.font4.face font.font4.size fontColor.font4 fontColor.link1Link N/A fontColor.link1Active N/A
background- Background 2 color background- Background 3 color background- Background 4 color font-family font-size color Font 1 Font 1 Size Font 1 Color Font 2 Font 2 Size Font 2 Color Font 3 Font 3 Size Font 3 Color Font 4 Font 4 Size Font 4 Color Link 1 Color: normal, visited None. Hardcoded (underline). Link 1 Color: active, hover None. Hardcoded (underline).
epi-font2
epi-font3
epi-font4
A.epi-link1:link, A.epi-link1:visited
color textdecoration
A.epi-link1:active, A.epi-link1:hover
color textdecoration
462
Table 30:
Mapping of CSS Classes to Theme Properties (Continued) HTML Property color textdecoration Theme Property (in UI) Link 2 Color: normal, visited None. Hardcoded (underline). Link 2 Color: active, hover None. Hardcoded (underline). Link 3 Color: normal, visited None. Hardcoded (underline). Link 3 Color: active, hover None. Hardcoded (underline). Link 4 Color: normal, visited None. Hardcoded (underline). Link 4 Color: active, hover None. Hardcoded (underline). Theme Property (in Code) fontColor.link2Link N/A fontColor.link2Active N/A fontColor.link3Link N/A fontColor.link3Active N/A fontColor.link4Link N/A fontColor.link4Active N/A
A.epi-link2:active, A.epi-link2:hover
color textdecoration
A.epi-link3:link, A.epi-link3:visited
color textdecoration
A.epi-link3:active, A.epi-link3:hover
color textdecoration
A.epi-link4:link, A.epi-link4:visited
color textdecoration
A.epi-link4:active, A.epi-link4:hover
color textdecoration
Appendices
463
{font-family: n}
General fonts and all classes except: epi-trail, wsui-trail, epi-trailOn, wsui-trail-current, epi-pageTitle, wsui-page-title, portlet-section-header epi-sectionTitle, wsui-section-title, portlet-section-subheader, portlet-form-label All classes except: epi-trail, wsui-trail, epi-trailOn, wsui-trail-current, epi-pageTitle, wsui-page-title, portlet-section-header epi-sectionTitle, wsui-section-title, portlet-section-subheader, portlet-form-label epi-fontSm, wsui-font-small epi-fontLg, wsui-font-large
Normal Size
{font-size: n}
{font-size: n} {font-size: n}
464
Table 31:
Mapping of Theme Settings to CSS Values (Continued) CSS Value {font-family: n} Affected CSS Classes epi-trail, wsui-trail, epi-trailOn, wsui-trail-current, epi-pageTitle, wsui-page-title, portlet-section-header epi-sectionTitle, wsui-section-title, portlet-section-subheader, portlet-form-label, epi-chromeHeader epi-pageTitle, wsui-page-title, portlet-section-header epi-sectionTitle, wsui-section-title, portlet-section-subheader, portlet-form-label epi-trail, wsui-trail, epi-trailOn, wsui-trail-current
{font-size: n}
{font-size: n}
Trail Size
{font-size: n}
General Font Colors Body Text {color: n} General fonts, epi-font, epi-fontSm, wsui-font-small, epi-fontLg, wsui-font-large, epi-formLabel, epi-rowOdd, epi-rowEven epi-pageTitle, wsui-page-title, portlet-section-header epi-sectionTitle, wsui-section-title, portlet-section-subheader, portlet-form-label
{color: n}
Appendices
465
Table 31:
Mapping of Theme Settings to CSS Values (Continued) CSS Value {color: n} {color: n} {color: n} Affected CSS Classes epi-trail, wsui-trail epi-trailOn, wsui-trail-current epi-ok, wsui-ok, portlet-msg-success epi-error, wsui-error, portlet-msg-error, portlet-msg-alert epi-dim, wsui-dim, portlet-font-dim
Theme Setting Navigation Trail: Normal Navigation Trail: Active Confirmation Messages
{color: n}
Deemphasized/Dimmed Text
{color: n}
Link Colors and Options Normal Links: Normal Normal Links: Visited Normal Links: Active, Hover Other Links: Normal, Visited {color: n} {color: n} {color: n} {color: n} General links General links General links epi-menu, wsui-menu , epi-menuOn, wsui-menu-current, epi-nextPrev, epi-buttonLink epi-menu, wsui-menu , epi-menuOn, wsui-menu-current, epi-nextPrev, epi-buttonLink epi-headline
{color: n}
Underline links
{text-decoration: underline}
466
Table 31:
Mapping of Theme Settings to CSS Values (Continued) CSS Value Affected CSS Classes epi-menu, wsui-menu , epi-menuOn, wsui-menu-current, epi-nextPrev epi-buttonLink
Theme Setting
Underline links that behave like buttons Portlet Chrome Colors Chrome Header Text Chrome Header Background Chrome Body Background Chrome Border Other Colors Page Background Content Block Background Content Block Border Line Breaks, Horizontal Rules (<hr>) Form Field Colors Button Text Button Background Input Field Text Input Field Background
{text-decoration: none/underline}
Appendices
467
Table 31:
Mapping of Theme Settings to CSS Values (Continued) CSS Value Affected CSS Classes
{background-color: n}
epi-dataTable, wsui-table, portlet-table-body epi-rowHead, wsui-table-row-header epi-rowHead wsui-table-row-header epi-rowHeadSorted epi-rowHeadSorted epi-rowSpecial1, wsui-table-row-sectionheader, portlet-table-subheader epi-rowSpecial1, wsui-table-row-sectionheader, portlet-table-subheader epi-rowHighlight, portlet-table-selected epi-rowHighlight, portlet-table-selected epi-rowFooter, portlet-table-footer epi-rowFooter, portlet-table-footer epi-rowOdd, wsui-table-row-odd, portlet-table-body epi-rowEven, wsui-table-row-even, portlet-table-alternate
Column Header Text Column Header Background Sorted Column Header Text Sorted Column Headers Background Special Row Text
{background-color: n}
Highlighted Row Text Highlighted Row Background Footer Row Text Footer Row Background Odd Row Background
{background-color: n}
468
Table 31:
Mapping of Theme Settings to CSS Values (Continued) CSS Value {font-size: n} {font-family: n} {font-size: n} {font-family: n} {font-size: n} {font-family: n} {font-size: n} Affected CSS Classes epi-font1 epi-font2 epi-font2 epi-font3 epi-font3 epi-font4 epi-font4
Theme Setting Size (1) Font 2 Size (2) Font 3 Size (3) Font 4 Size (4) Generic Colors Font 1 Color Font 2 Color Font 3 Color Font 4 Color Link 1 Color: Link, Visited Link 1 Color: Active, Hover Link 2 Color: Link, Visited Link 2 Color: Active, Hover Link 3 Color: Link, Visited Link 3 Color: Active, Hover Link 4 Color: Link, Visited Link 4 Color: Active, Hover Background 1 Background 2 Background 3 Background 4
{color: n} {color: n} {color: n} {color: n} {color: n} {color: n} {color: n} {color: n} {color: n} {color: n} {color: n} {color: n} {background-color: n} {background-color: n} {background-color: n} {background-color: n}
epi-font1 epi-font2 epi-font3 epi-font4 epi-link1 epi-link1 epi-link2 epi-link2 epi-link3 epi-link3 epi-link4 epi-link4 epi-BG1 epi-BG2 epi-BG3 epi-BG4
Appendices
469
Figure 68:
The following code produces the HTML output shown in Figure 68.
<a href="document.txt" class="epi-headline">This is a text file</a>
470
The following code produces the HTML output shown in Figure 69.
<table width="100%" border="0" cellpadding="0" cellspacing="0"> <tr> <td> <h1 class="epi-trail">Portlet » <span class="epi-trailOn">Search Results</span> </h1> </td> </tr> <tr><td valign="top" height="18"><hr size="1" /></td></tr> </table>
Appendices
471
Figure 70: Sample Implementation for the epi-pageTitle, episectionTitle, and epi-sectionTitleBG CSS Classes
The following code produces the HTML output shown in Figure 70.
<table width="100%" border="0" cellpadding="0" cellspacing="0"> <tr><td><h1 class="epi-pageTitle">Options</h1></td></tr> <tr><td valign="top" height="18"><hr size="1" /></td></tr> </table> <table width="100%" border="0" cellpadding="0" cellspacing="0"> <tr class="epi-sectionTitleBG"> <td height="18" colspan="2"> <h2 class="epi-sectionTitle">Display Preferences</h2> </td> </tr> ... valid HTML here </table>
472
Figure 71: Sample Implementation for the epi-nextPrev and epi-dim CSS classes
The following code produces the HTML output shown in Figure 71.
<span class="epi-dim">« Prev</span> | 1-5 of 47 | <a href="#" class="epi-nextPrev">Next »</a>
Figure 72: Sample Implementation for the epi-menu and epi-menuOn CSS Classes
The following code produces the HTML output shown in Figure 72.
Appendices
473
<tr> <td> <a href="author_details.jsp" class="epi-menu"> Author Details</a> | <span class="epi-menuOn">File Details</span> | <a href="other_options.jsp" class="epi-menu"> Other Options</a> </td> <td align="right"> <a href="view.jsp" class="epi-menu">Main View</a> </td> </tr>
Figure 73:
The following code produces the data tree shown in Figure 73.
<a href="create_new_task.jsp" class="epi-buttonLink"> <img src="icon_add.gif" title="Create" valign="absmiddle" /> Create New Task </a>
474
Figure 74: Sample Implementation for the epi-button, epi-input, and epi-formLabel CSS Classes
The following code produces the HTML output shown in Figure 74.
<table class="epi-formTable"> <tr> <td nowrap class="epi-formLabel"> <label for="name">Name:</label></td> <td><input type="input" name="name" id="name" class="epi-input"></td> </tr> <tr> <td nowrap class="epi-formLabel"> <label for="gender">Gender:</label></td> <td><select name="gender" id="gender"> <option selected>Female</option> <option>Male</option> </select></td> </tr> <tr> <td colspan="2"><hr size="1" noshade="noshade" /></td> </tr> <tr> <td nowrap colspan="2"> <input type="submit" name="submit" value="OK" class="epi-button" /> <input type="reset" name="submit" value="Reset" class="epi-button" /> </td> </tr> </table>
Appendices
475
Figure 75: Sample Implementation for the epi-dataTable and epirowFooter CSS Classes
The following code produces the data table shown in Figure 75.
<table border="0" cellspacing="0" cellpadding="0" class="epi-dataTable"> <tr> <th scope="col"><a href="#">Type</a></th> <th scope="col" align="left" width="100%" class="epi-rowHeadSorted"> <a href="#">Document Title</a></th> <th scope="col" align="center">a href="#">Size</a></th> <th scope="col" align="center">Edit</th> <th scope="col" align="center">Select</th> </tr> <tr class="epi-rowOdd"> <td align="center"><img src="icon_text.gif" border="0" alt="" /></td> <td><a href="doc_1.html">About the Intranet</a></td> <td align="center">96KB</td> <td align="center"><a href="edit.jsp">Edit</a></td> <td align="center"><input type="checkbox" name="checkbox4" value="checkbox" /></td> </tr> <tr class="epi-rowEven"> <td align="center"> <img src="icon_text.gif" border="0" alt="" /> </td> <td><a href="doc_2.html">Final Thoughts </a></td> <td align="center">20KB</td> <td align="center"><a href="edit.jsp">Edit</a></td> <td align="center"><input type="checkbox" name="checkbox4" value="checkbox" /></td> </tr>
476
<tr class="epi-rowOdd"> <td align="center"> <img src="icon_text.gif" border="0" alt="" /> </td> <td><a href="doc_3.html">Using the Intranet: A Step-byStep Guide</a></td> <td align="center">10KB</td> <td align="center"><a href="edit.jsp">Edit</a></td> <td align="center"><input type="checkbox" name="checkbox4" value="checkbox" /></td> </tr> <tr class="epi-rowEven"> <td align="center"><img src="icon_html.gif" border="0" alt="" /></td> <td><a href="doc_4.html">Where to Go from Here</a></td> <td align="center">36KB</td> <td align="center"><a href="edit.jsp">Edit</a></td> <td align="center"><input type="checkbox" name="checkbox4" value="checkbox" /></td> </tr> <tr class="epi-rowFooter"> <td align="right" colspan="4" style="font-weight: bold">Select All:</td> <td align="center"><input type="checkbox" name="checkbox5" value="checkbox" /></td> </tr> </table>
Descendant selectors or subclasses of the epi-dataTable CSS class should be used as shown in Table 32.
Table 32: CSS Class epi-dataTable TH, wsui-Table TH epi-dataTable TH a, wsui-Table TH a epi-dataTable TH.epi-rowHeadSorted Usage of Subclasses of the epi-dataTable CSS Class Usage Need not be explicitly specified in code. Automatically affects any <th> tag found within an epi-dataTable table. Need not be explicitly specified in code. Automatically affects any link within any <th> tag found within an epi-dataTable table. Apply epi-rowHeadSorted or wsui-rowHeadSorted to the <th> cell of the column against which the table is currently sorted.
epi-dataTable TH.epi-rowHeadSorted a Need not be explicitly specified in code. Automatically affects any link within any <th class="epi-rowHeadSorted"> tag found within an epi-dataTable table.
Appendices
477
Usage of Subclasses of the epi-dataTable CSS Class (Continued) Usage Need not be explicitly specified in code. Automatically affects any <td> tag found within an epi-dataTable table. Apply epi-padRight to any table cell (<td>) that requires additional padding to the right of its contents. Default padding is 0.5em; epi-padRight padding is 2em. Apply epi-embeddedTable with any tag that is contained within an epi-dataTable table . These tables are used only for layout. Applying this class will set the border and padding of the cells within the embedded table to zero.
epi-dataTable.epi-embeddedTable TD
Figure 76:
The following code produces the data tree shown in Figure 76.
<table border="0" cellpadding="0" cellspacing="0" class="epi-dataTree" width="100%"> <tr> <th style="padding-left: .2em"><img src="icon_folder.gif" alt="Folder" /></th> <th nowrap colspan="4" align="left" style="padding-left: .2em">Folder</th> <th nowrap align="right">Size</th> <th nowrap align="center">Last Modified</th> <th nowrap align="center" class="epi-padding">Select</th> </tr>
478
<tr class="epi-rowSpecial1"> <td style="padding-left: .2em"><img src="icon_folder.gif" alt="Folder" /></td> <td colspan="6" style="padding-left: .2em"> <a href="#">root</a></td> <td align="center" class="epi-padding"> <input type="radio" name="select" id="select1" value="select1" checked /></td> </tr> <tr class="epi-rowOdd"> <td style="padding-left: .2em"><a href="#"> <img src="tplus.gif" alt="expand" /></a></td> <td><img src="icon_folder.gif" alt="Folder" /></td> <td nowrap colspan="5" style="padding-left: .2em"> <a href="#">folder 1</a></td> <td align="center" class="epi-padding"><input type="radio" name="select" id="select2" value="select2" /></td> </tr> <tr class="epi-rowEven"> <td style="padding-left: .2em"><a href="#"> <img src="tminus.gif" alt="collapse" /></a></td> <td><img src="icon_folder.gif" alt="Folder" /></td> <td nowrap colspan="5" style="padding-left: .2em"> <a href="#">folder 2</a></td> <td align="center" class="epi-padding"><input type="radio" name="select" id="select3" value="select3" /></td> </tr> <tr class="epi-rowOdd"> <td style="padding-left: .2em"><img src="i.gif" alt="" /></td> <td><a href="#"><img src="tminus.gif" alt="collapse folder" /></a> </td> <td><img src="icon_folder.gif" alt="Folder" /></td> <td nowrap colspan="4" style="padding-left: .2em"> <a href="#">folder 2.1</a></td> <td align="center" class="epi-padding"><input type="radio" name="select" id="select4" value="select4" /></td> </tr> <tr class="epi-rowEven"> <td style="padding-left: .2em"><img src="i.gif" alt="" /></td> <td><img src="i.gif" alt="" /></td> <td><img src="tplus.gif" alt="Expand"></td> <td><img src="icon_folder.gif" alt="Folder" /></td> <td nowrap colspan="3" style="padding-left: .2em"> <a href="#">folder 2.1.1</a></td> <td align="center" class="epi-padding"><input type="radio" name="select" id="select5" value="select5" /></td> </tr>
Appendices
479
<tr class="epi-rowOdd"> <td style="padding-left: .2em"><img src="i.gif" alt="" /></td> <td><img src="i.gif" alt="" /></td> <td><img src="t.gif" alt="" /></td> <td><img src="icon_text.gif" border="0" alt="text file" /></td> <td nowrap width="100%" style="padding-left: .2em"> document_1.txt </td> <td nowrap align="right" class="epi-padding">5 KB</td> <td nowrap align="center" class="epi-padding"> 04/13/01 03:17 PM </td> <td align="center" class="epi-padding"></td> </tr> <tr class="epi-rowEven"> <td style="padding-left: .2em"><img src="i.gif" alt="" /></td> <td><img src="i.gif" alt="" /></td> <td><img src="t.gif" alt="" /></td> <td><img src="icon_text.gif" border="0" alt="text file" /></td> <td nowrap width="100%" style="padding-left: .2em"> document_2.txt</td> <td nowrap align="right" class="epi-padding">43.7 KB</td> <td nowrap align="center" class="epi-padding"> 04/13/01 03:17 PM </td> <td align="center" class="epi-padding"> </td> </tr> <tr class="epi-rowOdd"> <td style="padding-left: .2em"><a href="#"> <img src="lplus.gif" alt="Expand" /></a></td> <td><img src="icon_folder.gif" alt="Folder" /></td> <td nowrap colspan="5" style="padding-left: .2em"> <a href="#">folder 3</a></td> <td align="center" class="epi-padding"><input type="radio" name="select" id="select6" value="select6" /></td> </tr> </table>
Descendant selectors or subclasses of the epi-dataTableLite CSS class should be used as shown in Table 33.
480
Usage of Subclasses of the epi-dataTree CSS Class Usage Need not be explicitly specified in code. Automatically affects any <th> tag found within an epi-dataTree table. Need not be explicitly specified in code. Automatically affects any link within any <th> tag found within an epi-dataTree table. Apply epi-padRight to any table cell (<td>) that requires additional padding to the right of its contents. Default padding is 0.5em; epi-padRight padding is 2em. Apply epi-embeddedTable with any tag that is contained within an epi-dataTable table. These tables are used only for layout. Applying this class will set the border and padding of the cells within the embedded table to zero.
epi-dataTree.epi-embeddedTable TD
Figure 77: Sample Implementation for the epi-rowSpecial1, epirowFooter, epi-rowOdd, and epi-rowEven CSS Classes
Appendices
481
For code examples for the epi-rowSpecial1, epi-rowFooter, epirowOdd, and epi-rowEven CSS classes, see the code examples for the epidataTable and epi-dataTree CSS classes.
Figure 78:
Class(es): Usage:
epi-block Use to designate a special area of the user interface by offsetting some portion of the content with a slightly different background color.
Sample:
The following code produces the HTML output shown in Figure 78.
<table border="0" cellspacing="0" cellpadding="3" width="100%" class="epi-block"> <tr height="36"> <td class="epi-formLabel"> <label for="string">Search for:</label></td> <td input type="text" name="string" id=" string " class="epi-input" /></td> <td><input type="submit" name="search" value="Search" class="epi-button" /></td> </tr> </table>
482
Deprecated Classes
Deprecated Classes
The following tables list classes that have been deprecated in Portal 7.0 and 4.x.
Table 34: MyPages Deprecated CSS Classes epi-button-current,epi-buttoncurrent tablerollover epi-button-current-rollover a epi-button-line epi-button-normal a epi-button-rollover epi-button-rollover table.rollover
Table 35:
Other Deprecated CSS Classes epi-blockBGColor epi-buttonLinkSm:hover epi-chromeHeaderBG epi-dimColor, epi-dimSm, wsui-dim-small epi-form,epi-formSm epi-rowSpecial2
epi-align epi-buttonLinkSm epi-buttonSm,wsui-button-small epi-chromeHeaderFont epi-errorColor, epi-errorSm, wsui-error-small epi-okColor, epi-okSm, wsui-ok-small epi-rowSubHead
Appendices
483
Deprecated Classes
484
E
Summary: Audience: Topics: Note:
URLs (below) Secondary Pages on page 486 JSP Programming Constructs on page 488 System Properties on page 489 CSS on page 489 I18N on page 489 Changes Affecting PortalBeans on page 490
Previous names of the product in the 7.x and 4.x timeframes were Vignette Application Portal and Epicentric Foundation Server.
URLs
Portal 7.x URLs look different than 4.x URLs. Whereas version 4.x required developers to create URLs themselves by concatenating all of the pieces, version 7.x generates and parses URLs at a lower level. Portal 7.x understands 4.x URLs. Bookmarks and other hard-coded links will continue to work. Portal 7.x uses a legacy adapter to intercept old URLs, translate them into new ones, then either display a view or dispatch to the correct secondary page processor. This legacy adapter performs 4.x URL resolution if the following property and value are present in the Portal configuration file (PortalInstallDir/config/properties.txt):
portal.controller.version_support=4.x
The default value of this property is 7.x. You must change this value to 4.x under any of the following circumstances:
Appendices
485
Secondary Pages
If you want to use 4.x bookmarks, MWS portlets, or Collaboration portlets If you want to use the 7.x Page Display secondary page with 4.x chrome
styles
If you use the PortalBean API to invoke PortalBeans directly If you use the getFullViewURL(String viewID, Hashtable getParams, String nonPreferredPageURL) method on GenericPortalBean If you have custom code that hard-codes links
Secondary Pages
In version 4.x, JSPs contained processing logic for secondary pages. Portal 7.x uses Java classes that implement actions. When a secondary page JSP contains processing logic, Portal 7.x invokes that JSP logic instead of the action-based logic defined by its secondary page type. Portal 7.x uses the portal.controller.version_support property discussed above to determine how to handle secondary page processing logic.
Upgrade Notes
Version 4.x secondary pages will continue to work in a Version 7.x installation, with the following known exceptions:
If your 4.x installation uses a customized logout secondary page but default
account control style, after upgrade Portal 7.x will use this same combination. However, the account control style will generate a logout
486
Secondary Pages
URL similar to
/portal/system/template.LOGOUT/action.process/. This URL
will invoke the primary file of your custom logout secondary page, which will not remove the user session and hence cannot log out the user. To solve this problem, use the Portal server console to switch to the default logout secondary page. You can customize the default secondary page by duplicating it and then modifying and deploying the duplicate.
If your 4.x installation uses a customized site picker secondary page, after
upgrade the page will list all sites allowed for the user as well as any site that allows self-registration. However, users will not be permitted to go to a site that allows self-registration but is not one of their allowed sites. To solve this problem, use the Portal server console to switch to the default site picker secondary page. You can customize the default site picker secondary page by duplicating it and then modifying and deploying the duplicate.
In Portal 7.x, the My Pages - Manage secondary page provides the ability to
add, delete, and rename existing My Pages; in version 4.x, My Pages Manage provided only the ability to delete My Pages. As a result, if you configure Portal 7.x to use a version 4.x My Pages - Manage secondary page, the ability to add a new My Page will be lost. If you want to continue to use the version 4.x My Pages secondary pages, duplicate the following 4.x components (which are all obsolete in Portal 7.x):
My Pages grid My Pages navigation style My Pages control style
Then import these components into Portal 7.x and set the 4.x My Pages secondary pages to use the 4.x My Pages grids. (To prevent the My Pages controls from appearing twiceonce in the version 4.x My Pages navigation style and once in the Portal 7.x navigationalso set the navigation.mypages.show property to false in the Portal configuration file, properties.txt. For details about this file, see Vignette Portal Configuration Guide.) Vignette recommends that you refactor any 4.x custom secondary pages when upgrading to 7.x, to minimize the potential issues with using a hybrid system. Specifically, you should replace display and process JSPs with display and process action classes.
Appendices
487
Chapter 4, Controlling Functionality with Secondary Pages, for documentation of process actions.)
The prefix used for the main Portal custom JSP taglib has been changed from "epi_html" to "vgn-portal" although 4.x tags can use either prefix. (The PortalBean taglib prefix continues to be "mod".) The following tags are deprecated, though they will continue to work:
<epi_html:controllerURL/> can be replaced by <%= portalContext.getCurrentBasePortalURI() %>. <epi_html:portalHttpRoot/> can be replaced by <%= portalContext.getPortalHttpRoot() %>. <epi_html:guestAccessControl/> is replaced by the allowguest-access attribute in the component.xml file for secondary
header is now set by the framework. Any occurrence of this directive will be ignored.
The contentType directive [ contentType="text/html; charset=UTF-8" ] can be removed, as this header is now set by the
framework (and optionally overridden within a pre-display action, as documented in Chapter 4, Controlling Functionality with Secondary Pages). Any occurrence of this directive will be ignored.
See also:
Appendix A, Vignette Portal Custom JSP Tag Reference, for details about all Portal 7.x JSP tags Chapter 7, Using the Site Development APIs, for a discussion of the portalContext implicit variable
488
System Properties
System Properties
Prior to Portal 7.2, the com.epicentric.common.Props class was used to load Portal properties into the java.lang.System properties. The Props class is now deprecated. Use com.vignette.portal.config.PortalConfigUtils now instead of the System properties.
CSS
A number of CSS classes have been deprecated for Portal 7.x. These classes have been replaced by new ones that provide more granular control over page display. Although the deprecated classes will continue to work for Portal 7.x, you should replace them with the current classes.
See also: Appendix D, Vignette Portal CSS Reference, for a list of Portal CSS classes that have been deprecated
I18N
The following changes related to internationalization occurred in Portal 7.2:
The I18NUtils.getValue() methods no longer convert "\n" or "\r\n" to "<br />". This change is consistent with the best practice of separating translations from layout; it also makes the getValue()
Appendices
489
URLs and retrieving request parameters are used, this change will be transparent to the portlet and no changes will be necessary. However, PortalBeans that do not follow Portal best practices can encounter problems. Specifically, these two non-standard practices will cause problems:
URLs are not generated using getFullViewURL() on GenericPortalBean: This method takes care of namespacing parameters appropriately. If it is bypassedfor example, by generating a base URL and manually appending additional parameters (e. g.,
GenericPortalBean.getFullViewURL("my_view") + "&my_parameter=my_value"), the parameters will not be
namespaced and therefore the portlet will not be able to retrieve them later.
Request parameters are not retrieved using one of the request methods on GenericBeanView: Analogous to URL generation, the GenericBeanView method request() and related methods such as requestInt() and requestNames() take care of namespacing transparently. If the PortalBean instead uses methods such as
490
parameters.
The MINIMIZABLE permission and PortalBean descriptor (PBD) attribute has been deprecated; MINIMIZED is one of the Java standard portlet
window states. To prevent a particular portlet from being minimized, use the Portal administration consoles (Pages >> Page Name >> Portlet Placement) to lock the panel that contains the portlet. To prevent any portlet from being minimized, remove the logic for the minimize button from the component that renders the portlet (such as the chrome style, documented in Chapter 2, Controlling Navigation and Appearance with Styles; for discussion of other portlet-rendering techniques, see Chapter 7, Using the Site Development APIs).
The portal.controller.version_support property in properties.txt must be set to 4.x if you use the getFullViewURL(String viewID, Hashtable getParams, String nonPreferredPageURL) method on GenericPortalBean or
if you are using MWS portlets or Collaboration portlets. (Note that MWS portlets have been deprecated in favor of WSRP portlets.)
"Administrative" PortalBeans are no longer supported. Portal 7.x ignores
them.
Version 4.x included properties supporting the mapping of PortalBean view
IDs to URLs. These mapping properties (which were in properties.txt) have been removed.
See also:
Latest update to version 4.5 of the Vignette Application Portal Module Developers Guide for details about the legacy PortalBean portlet APIs Chapter 12, PortalBean Portlets, for documentation of post4.5 enhancements to the PortalBean APIs and for additional discussion of Portal changes affecting PortalBeans
Appendices
491
492
Index
A
<A> HTML tag, in Vignette Portal CSS
151, 449
ABOUT Java standard portlet mode 226 AbstractControllable class 373, 375 AbstractServiceController class
372, 373, 375 Access API, Content Access Management 335341 access control See authentication; authorization accessibility 161 account controls style type 50 account maintenance link, including in style 45, 50 accounts, authentication 261, 267 accounts, user 254, 261 action attribute, HTML <form> tag secondary pages and 113 action_based attribute value, component.xml 138, 139 actions, secondary page AJAX and 180182 defining on instances 100 display 38 example of 110 executing 103 forwarding from 106 groups of 139, 143, 414, 419 handling errors using 105 in component.xml 102, 139141, 143146, 412, 417 introduction 3840, 98 Java inheritance and 100 pre-display 98, 103, 108, 180182 process 39, 98, 109, 110, 180
redirecting from 104, 106, 172, 180181 returning null from 107, 109 reusing 99, 100 Admin user group 254 administration console component deployment and 196 component titles, descriptions, and 200, 377 component versions and 205 component visibility and 202 CSS and 149150, 447 federated search and 309, 322328, 331 friendly IDs and 188, 189 grids and 3233, 80, 83, 84 internationalization of 157 introduction 15, 29 Java standard portlets and 220 localization features of 157, 158, 159 menu item visibility and 64 portlets and 20, 30, 225226 secondary pages and 30, 95, 97, 147 services and 372, 372373, 375 styles and 42, 43, 47 themes and 29, 42, 48, 150, 447 adminURL variable 44, 46 AJAX errors and 179, 184, 217, 241 forward calls and 180 introduction 18, 19, 178 Java standard portlets and 212217, 226, 231 navigation styles and 5455 Portal library functions 179, 435436 PortalBean portlets and 234, 237241 redirection and 180181 styles, secondary pages, and 180185 alias, document 336 allLevels variable 57, 59
493
allow-guest-access attribute, component.xml 202, 260, 416 alt text, and internationalization 161
Apache Ant task for Java standard portlet packaging 220, 221224 for PortalBean deployment 242 Apache Struts 121 Apache validator classes 133, 134 appendToHandler JavaScript function 437 application restart deployment system and 196 for federated search connectors 331 for portlet applications 221 for secondary pages 142 for services 387 for Story Publisher renderers 369 application templates, Vignette Builder 20, 277 apply-template-header attribute,
component.xml
B
BaseAction class 103, 187 baseURL variable 45, 46 beginString attribute, I18N tag 160
grids and 87 reference 203, 411, 417 styles and 73 warning about 44, 48 architecture, Vignette Portal 1621, 2540, 43, 193194 Artesia integrations 20 attribute keys, WebConnector 301, 302 authentication, Vignette Portal introduction 21, 253, 260 portlet applications and 224 third-party software and 261 to remote servers 302 user accounts and 261 XML file 265 authorization, Vignette Portal federated searches and 310, 313 introduction 253 Java standard portlets and 210, 224
binary content Content Access Management and 336 Java standard portlets and 227229, 232 Oracle LOB data type and 294 BINARY portlet window state 176, 227229 birth date attribute, Java standard portlets 212 <BODY> tag, HTML excluding from style files 47 in Vignette Portal CSS 151, 449 including in grid 84, 90, 91 Java standard portlets and 229, 231 branding CSS and 154 function of 40 navigation styles and 61 themes and 189 branding variable 45 BrandingUtils class 61, 189 broadcasting cache strategy 270, 271, 274 browser object JavaScript function 437 build process, and portlet applications 222 See also deployment Builder, Vignette 19, 20, 277 build-version attribute,
component.xml
for services 377 for web components 200, 407 byte validation rule 129
494
Index
C
cache-control JSP directive, change since version 4.x 488 caching clustered environment and 269, 271 CSS 155 Vignette Portal system 269276 callback functions, AJAX 179, 183, 216, 240 CAM 307, 333369 cam-properties.sample file 344
canUserAccessSiteConsole()
386
classname attribute, validation
method 268
canUserAccessSystemConsole()
method 268 CAR files federated search connector 328330 function of 195 grid 86, 87 I18N property files and 159 secondary page instance 102, 141143 secondary page type 102, 143 service 386 Story Publisher 366, 368 structure of 198 style and style type 75 card, Content Access Management 336 cascading style sheets See CSS catalogs, search engine 349 Categorization Manager 348 character encoding 170 chrome styles custom portlet properties in 71 developing 6571 Java standard portlets and 225, 226 portlet content rendering in 69, 175 primary file 67 template header files 66 chromeless portlets 70, 119, 175, 176
framework 128 client browser object JavaScript function 437 clipping content 298, 299 clustered environment 269, 271 cm_bwcheck JavaScript function 437 cm_makeObj JavaScript function 437 cm_page JavaScript function 440 cm_scrolldown JavaScript function 441 cm_scrollleft JavaScript function 441 cm_scrollright JavaScript function 441 cm_scrollup JavaScript function 441 code examples, warning about 22 Code Exchange, Vignette 278, 298, 299 collections, Content Access Management 347350, 352 collections, federated search 308, 312, 326, 332 Column JavaScript function 441 component.xml files creating via export 197 for federated search connectors 318328 for grids 86, 87 for menu item images 407, 410 for secondary page instances 102, 137 for secondary page types 102, 143 for services 376386, 420434 for Story Publisher 367 for style types 43, 73 for styles 43, 72 friendly IDs and 189 function of 193, 195, 196 guest access and 260 I18N property filenames and 158 location for deploying 198
495
for services 377, 380 for Story Publisher renderers 367 for web components 200 I18N property filenames and 158 literal value for grids 87 reference 407, 409 uniqueness and 204 components, Vignette Portal architecture of 2540, 193 deployment of 193205 introduction 15, 18, 25, 26 uniqueness of 204 versioning 200, 204, 377 component-type attribute,
component.xml
for grids 87 for secondary page instances 138 for secondary page types 143 for services 377 for Story Publisher renderers 367 for style types 74 for styles 73 function of 200 reference 407, 409 uniqueness and 204 CONFIG Java standard portlet mode 226 configuration file, Vignette Portal See properties.txt file ConfigurationValidator interface 375
<configuration-validator-classname> element 380, 426
connection pools use with metrics system 279 Vignette Portal API 21, 289295 connectors
Content Access Management 307, 335, 341355 Content Delivery 334 federated search 306, 307, 309332 search engine 347355 ConnectorSearchContext class 314 <constant> element, validation framework 126, 127 constants, Vignette Portal 191 Contemporary theme control styles 50, 82 grid 81, 82 header style 49 illustration 83 navigation styles 48, 53, 56 <content> custom JSP tags 358, 359, 365 Content Access Management 307, 333369 Content Delivery Connector, Vignette 334 Content Management Middleware 335 content repositories 308, 333, 335, 341 See also MetaStore content types AJAX and 183, 216, 240 setting 108 content view, Story Publisher 357, 365, 366 contentType directive, change since version 4.x 488 context root, portlet applications 220, 222, 224 ContextAwareConnector interface 342 control styles 5051, 82, 83 Controllable interface 373 controllerURL variable 45 cookies 46, 55, 170 createController() method, services 373 createDisplayURI() method 182 createPageURI() method 173
496
Index
D
data source connectors, Content Access Management 341355 data, APIs for remote 297303 database connection pooling and 289295 Content Access Management and 333, 341 metrics and 277, 278 Oracle LOB handling 294 Portal schema 278 date of birth attribute, Java standard portlets 212 date validation rule 130 dates, internationalizing 163 day_phone user property, Vignette Portal 212 debug logging level 185 decoding and encoding 170 <default-value> element 381, 429 defineObjects custom JSP tag 85, 89, 191, 392 depends attribute, validation framework 126, 128 deployment component versioning and 204 of federated search connectors 318330 of grids 8688, 203 of Java standard portlets 219224 of secondary page instances 137143, 203 of secondary page types 143, 201 of services 376387 of style types 7375, 201 of styles 7275, 203 overview 193197 See also CAR files; component.xml files
method 113
createTemplateProcessURIAsPorta lURI() method 181 creditcard validation rule 130
CSS administration console and 447 branding and 154 caching system, Vignette Portal 155 classes, Vignette Portal 151, 450463, 483, 489 custom 153155 deploying 198 deprecated Vignette Portal classes 483, 489 epi-dataTable usage 477 epi-dataTree usage 481 examples, Vignette Portal 470482 grids and 81, 85, 153 HTML elements in Vignette Portals 151, 449450 Java standard portlets and 150, 229 modifying 47, 83, 95 navigation styles and 56, 61 overriding Vignette Portals 153 themes and 447469 type selectors, Vignette Portal 449 WSRP and 150 CSSTokenMutator class 303 custom properties Content Access Management 337 menu item node 63 MetaStore and 250 portlet 71 custom renderer, Story Publisher portlet 355369 CustomMBeanFactory class 284 CustomMonitor class 283
497
grids 83, 84 secondary pages 95, 102, 120 styles 4748, 49, 50, 54
E
EAR file, Java standard portlets 220 EDIT Java standard portlet mode 226 EDIT_DEFAULTS Java standard portlet
mode 226
editContentURL variable 45 email validation rule 130
for services 377 for web components 200 reference 408 epi-dataTable CSS class usage 477 epi-dataTree CSS class usage 481 <epideploy:component> element for services 377 for web components 200 reference 406 <epideploy:detail> element for services 378, 381 for web components 201, 203 reference 410, 431
<epideploy:required-component/>
element for grids 87 for secondary page instances 138 for secondary page types 146 for services 431
498
Index
for style types 74 function of 201, 377 reference 408 epi-tags taglib 44 epi-version attribute, component.xml for services 377 for web components 200 reference 408 error handling CSS classes for 452 Java standard portlets and 217 logging API and 185 Portal AJAX library and 179 PortalBean portlets and 241 secondary pages and 184, 186 styles and 186 error logging level 185 ErrorMessage class 110, 171, 172 Everyone user group 254 examples, warning about code 22 execute() method, of actions 103 executeAdvancedSearch() method 315 executeBasicSearch() method 313, 315 exporting See deployment
F
fatal logging level 185
322, 325
Field class (Apache) 133, 134 <field> element, validation framework
126
fields, template header files See variables filters, for portlet applications 223, 224 float validation rule 129 Floating Page Controls style type 50, 82 floatrange validation rule 128 folders Content Access Management 336 MetaStore 250 fonts and colors customizing for components 149, 150152 in Java standard portlets 229 in navigation styles 60 retrieving 190 See also CSS; branding; themes footer styles 71 <form> element, validation framework 126 formattable classes, Vignette Portal 164165 FormattingContext class 165 FormBean class 98, 122123, 133, 135 forms, HTML CSS and 151, 454455 in secondary pages 111114, 121136 internationalizing 161 Portal AJAX library and 179, 182184, 215217, 239241 See also validation framework; control styles <formset> element, validation framework 126, 127 forward calls 106, 109, 180 framesets, and Java standard portlets 231 friendly IDs administration console and 189 function of 40, 188 in component.xml 202, 411, 416 of Portal pages 173
499
friendly URI, of menu items 35, 60 FRONT_VIEW, Story Publisher 357 full view, Story Publisher 357, 359, 362, 366
G
GenericAuthenticator class 261 GenericBeanView class, PortalBeans
302
<global> element, validation framework
490
GenericPortalBean class 486, 490 getConfiguredTitle() method 68 getContextAttribute() method 302 getContextAttributeKeys() method
302
getCurrentPageURI() method 110 getCurrentUser() method 256 getFormattable() method 167 getFormName() method 122 getFriendlyURIFromMenuItemID()
method 60
getFullViewURL() method, PortalBeans
486, 490
getHref() method 60 getMenuItemIDFromFriendlyURI()
method 60
getNamespace() methods 68, 231 _getPageOffsetLeft JavaScript
function 437
_getPageOffsetTop JavaScript function
127 grids administration console and 3233 branding and 189 deploying 8688, 203 developing new 18, 84 example of 88 introduction 15, 27, 33, 79 linking to CSS 153 modifying the look and feel 83 secondary page types and 32 support files for 83 system (shipped with Vignette Portal) 80 Vignette Contemporary 81, 83 groups action 139, 143, 414, 419 user 254, 258 guests, portal access and 202, 260, 416 language preference 158, 254
440
getParameter() method 170 getParameterValues() method 170 getPortalRequest() method 170 getPortletProperty() method 71 getPortletSetTitle() method 68 getPortletUID() method 68 getPotentialErrors() method 122,
H
hard size-based caching 270 <HEAD> tag, HTML excluding from style files 47 including in grid 89 Vignette Portal CSS and 153 header styles 29, 49
123
500
Index
header-filename attribute, component.xml 74, 202, 417 HELP Java standard portlet mode 225 HiddenCollectionAwareEngine
images deploying 63, 198, 407, 410 internationalization and 161 menu item nodes and 61, 407
<implementation-class-name>
interface 349
homeURL variable 45
horizontal navigation styles 52 hot deployment, portlet applications 221 <HR> tag, in Vignette Portal CSS 151, 450 HTML CSS and 151 modifying 47, 83, 95 namespacing in chrome styles 67 See also individual tags <HTML> tag excluding from style files 47 including in grid 84, 89, 91 Java standard portlets and 229, 231 HTML forms See forms, HTML HTMLTokenMutator class 303 HTTP See request; response; session HTTPS features 35, 105, 181, 212 HttpSession wrappers 171
433 importing See deployment include (.inc) JSP files 120, 121 includeNavigation custom JSP tag 58, 85, 91, 396 includePageContent custom JSP tag reference 397 using 79, 82, 85, 91 includeStyle custom JSP tag 85, 90, 188, 397
<indexed-property-setdefinition> element 381, 430
I
I18N custom JSP tags 160164, 392396 See also internationalization I18N methods 68, 164168 See also internationalization I18nHelper class 167 i18nID variable 45, 160, 188 I18nUtils class 166 id attribute, component.xml literal value for grids 87 reference 411, 416, 424, 432 IframeIO 183, 216, 239 imageRoot variable 45
indexing Content Access Management and 307308, 334, 342, 350353 federated search and 306, 307308 info logging level 185 init() method federated search connectors 312 search engine connectors 354 services 373 inSegment custom JSP tag 255, 257, 398 insertPortletContent custom JSP tag 69, 174, 398, 401 installation path, Vignette Portal 190 integer validation rule 129 integrations technology comparisons 19 using Content Access Management 333355 using portlets 1921 using remote services 297303
501
using Vignette Builder 20 using Vignette Business Integration Studio 20 <interface-class-name> element 378, 380, 422 internationalization deployment and 159 format API for 164165 introduction 157 JSP tags for 160164, 392396 of federated search connectors 311, 317 of messages 186 of numbers and dates 163 of Story Publisher renderers 368 property files 157, 158 utility classes 166168 See also property files, I18N intrange validation rule 128 invalidate() method, cache API 273 invokingStyleSupportsDrag variable 66 isAdminUser() method 268 isAuthorizedUser() method 268 ISearchConnector interface 306, 310, 311 isEditModeAllowed() method 268 isEnabled() method 268 isHelpModeAllowed() method 268 isMaximizedStateAllowed() method 268 isMinimizedStateAllowed() method 268 isNormalStateAllowed() method 268 isPartialPageRequest() method 54, 180 isSecondary attribute, navigation JSP tag 58, 85, 91 isSelected() method 60, 61 isSelfRegAllowed variable 45
268
isUserAuthorized() method 268 isUserInRole() method 210 isValidCollection() method,
J
J2EE and Vignette Portal 16 JAR files Content Access Management 341 deploying 196, 199, 386 federated search 310, 329, 331 Java standard portlet 210 secondary page 142 service 386, 387 jar Java utility 75, 88, 142 Java classes, deploying 141, 142, 199, 386 Java Portlet Specification 209, 225 Java standard portlets See portlets, Java standard JavaBeans 103, 104 JavaScript in grids 81 Java standard portlets and 212, 229, 231 modifying 47, 83, 95 namespacing in chrome styles 67 navigation styles and 55 PortalBean portlets and 237 Vignette functions 435445 See also AJAX JavaScriptTokenMutator class 303 JD Edwards integrations 20
502
Index
JDBC See database JNDI 21, 253, 260 JSON objects, and AJAX navigation styles 55 JSP files deployment location 75, 198 template header file warning 48, 55, 56 See also primary JSP files;support files JSP include (.inc) files 120, 121 JSP include pages 30, 202, 416 JSP tags, Vignette Portal custom deprecations since version 4.x 488 for grids 85 for I18N and L10N 160164, 392396 for implicit variables 85, 89, 191, 392 for navigation 58, 85, 91, 396 for portlets 69, 174, 175, 398399, 400401 for Story Publisher 358 overview 40 JSPBean class, PortalBeans 243 <jsp:useBean/> tag secondary pages and 112, 135 styles and 67 JSPView class, PortalBeans 243 JSR-168 portlets See portlets, Java standard JSTL performance issues 18
L
Layer object constructor, JavaScript 437 layout, page 115121 See also grids; styles LDAP 253, 260 <LI> tag, in Vignette Portal CSS 151, 450 Linear theme control styles 50 grids 81
navigation styles 48, 54, 5455, 59 links in control styles 50 in navigation styles 60 in PortalBeans 490 in secondary pages 104109 Vignette Portal CSS classes for 453 LOB data type 294 <locale-key> element reference 421, 423, 433 using 378, 379, 382 localization API calls 164168 controlling precedence of 162 introduction 157 JSP tags 160164 Vignette Portal precedence algorithm 158 See also internationalization locking, Content Access Management 337, 343 LOG implicit variable function of 40, 185, 191 in grids 85 in secondary pages 109, 113 in style template header files 44 log table, metrics 277 log, Vignette Portal 185 log4j.properties file 185 login and logout buttons 45, 50 login functionality 33, 36, 181, 267 LogWrapper class 185 long validation rule 129 look and feel, customizing 1517, 149, 154 See also branding; CSS Lotus integrations 20
M
main view, Java standard portlets 225
503
for services 377, 380 for web components 200, 204 reference 407, 409 mask validation rule 130 maximized portlets 175, 176, 226, 268 maxlength validation rule 129 MBeans 280 MENU_NAVIGATION_SPLIT site setting 58 menuing system See navigation Menuitem File Assets component type 407, 410 MenuItemNode class 5963 MenuItemNodeImage class 61 MenuItemParams class 55 MenuItemUtils class 55, 59, 60, 64 MessageFormat patterns 163, 164, 166 messages, user 185, 453 metadata, and content search 306, 347351 MetaStore general usage guidelines 250251 use with Content Access Management 335 use with services 372, 429 method attribute, validation framework 128 methodParams attribute, validation framework 128, 133 metrics, Vignette Portal 277288 metrics_map.xml file 283 Microsoft Office integrations 20 MIME types AJAX and 183, 216, 240 setting 108 MINIMIZABLE attribute, PortalBeans 491 minimized portlets 176, 268, 491 minlength validation rule 129
for services 377, 380 for web components 200, 204 reference 407, 409 mobile devices 108 mobile_phone user property, Vignette Portal 212 <mod:i18nAlias> tag 242 <mod:i18nValue/> tag, PortalBeans 242 modes, Java standard portlet 225 moduleBackgroundColor variable 66 moduleBannerColor variable 66 <module-config> element 320, 367 moduleFrameColor variable 66 modules See portlets, PortalBean moduleTitleColor variable 66 ModuleTypes component type 320, 324, 367 monitoring cache strategy 270, 271 moveContentURL variable 45 mpList variable 45 multi-device support 108 multipart form, AJAX support 183, 216, 239 multithreading, PortalBean 177 MWS portlets 491 My Account link, including in style 45, 50 My Pages feature changes since version 4.x 487 checking for enablement 268 chrome style and 65 including link in style 50 variables for 45 myAccountURL variable 45 myColorsURL variable 45 myPagesID variable 45 myPagesURL variable 45
504
Index
N
name attribute, validation framework 127
namespacing changes affecting PortalBeans 490 chrome styles 67 custom metrics 284 Java standard portlets 212, 231 PortalBean portlets 237 request parameters 490 navigation items 52, 59, 151 navigation splits 53, 58 navigation styles AJAX and 5455 custom properties and 63 developing 5165 DHTML 55 fonts and colors 60 friendly URIs of 60 grids and 85 horizontal 52 images in 61, 407 introduction 31 links in 60 node visibility and 64 primary and secondary 58 site branding and 61 static 56 system (shipped with Vignette Portal) 53 template header file warning 55, 56 vertical 52 Vignette Contemporary 48, 53, 56 navigation tree 31, 52 navSplit variable 58 .NET 19, 20 night_phone user property, Vignette Portal 212 nodes, menu item 5965 nodesInHorizontalOrder variable 57 nodesInVerticalOrder variable 57
O
obsolete PortalBeans 243 onRenderFailure custom JSP tag 69, 174, 175, 399, 401 onRenderSuccess custom JSP tag reference 398, 399, 401 using 69, 174 <option> element 380, 428 <option-list> element 380, 428 Oracle database LOB handling 294
P
<P> HTML tag, in Vignette Portal CSS
151, 449 page controls style type 50, 82 Page Display secondary page type 31, 115121, 486 Page object constructor, JavaScript 440 pageBackgroundColor variable 46 pageContentTitle custom JSP tag 85, 90, 399 pages, Vignette Portal HTML 26, 33 invoking by friendly ID 173 JSP include 30, 202, 416 portlet 30, 3334, 50, 173 See also secondary pages; Page Display secondary page type parallel rendering of PortalBeans 177 of WSRP portlets 177 ParameterConstants class 191 parsable indexing engine 351 partial (AJAX) updates
505
Java standard portlets and 214215 navigation styles and 54 Portal AJAX library and 179 PortalBean portlets and 239 styles, secondary pages, and 181183 passivation, and caching system 269, 271, 274 _pathToImages variable 46 pathToStyle variable 46 pattern attribute, I18N tag 163 PBD file, for PortalBean portlets 243 PeopleSoft integrations 20 permissions checking 253, 267 content 348 federated search 310, 313 Java standard portlet 210, 224 pop-up windows, for Java standard portlets 229, 231 Portal Metrics Viewer application template 277
portal.controller.version_suppo rt property 485
PortalBean Manager 317, 320, 368 PortalBean portlets See portlets, PortalBean
PortalBeanRequestResponseContex t interface 302 PortalBeanView interface 243, 302 PortalConfigUtils class 190, 489 portalContext implicit variable
function of 40, 191 in grids 85 in secondary pages 113 in style template header files 44 PortalContext interface page invocation and 173 redirection and 104, 105
requests, responses, and 169 secondary pages and 135 user access and 255 PortalEnvironment class 190 portalHttpRoot variable 46 PortalInitialContext class 190 PortalRequest interface 169, 188 PortalResponse interface 169 PortalURI interface secondary pages and 105109 URI generation and 172, 173, 181 Portlet Packaging Tool, Vignette Portal 220, 221224 portlet windows 6571, 176 PortletRequest object 211 PortletResponse object 231 portlets AJAX and 19 building-block type 20 chrome styles and 6571 chromeless 70, 119, 175, 176 Content Access Management 333, 335, 338 control styles and 50 CSS and 153 custom properties 71 displaying on page 174178 friendly ID attribute 176178 introduction 15, 19 Java standard 209217 MWS 491 .NET and 20 page concepts 30, 3334 page layout 115121 prebuilt (shipped with Vignette Portal) 20 rendering content 69, 173, 174178 sample 21 search 306, 332, 348 Story Publisher 355369 title bar, displaying 68
506
Index
WebConnector 20, 299303 portlets, Java standard AJAX and 212217, 226, 231 comparison to PortalBeans 19, 233 deploying 219224 disabling Vignette Portal security filter for 224 framesets and 231 modes 225 packaging for Vignette Portal 221224 pop-up implementation 229, 231 rendering 175 request attributes and 107 roles and permissions 210 secure URLs and 212 tag library location 210 user attribute mapping 211 Vignette Portal and 209 WebConnector and 302 window states 175, 176, 226232 portlets, PortalBean AJAX and 234, 237241 calling one from another 235 comparison to Java standard portlets 19, 233 descriptors 243 multithreading 177 retiring 243244 troubleshooting 490 Vignette Portal changes affecting 490 WebConnector and 302 portlets.xml file 210 PortletURL object 212, 230 portletWindow scripting variable 66, 6771 PortletWindowBean interface 67, 69, 267 <PRE> tag, in Vignette Portal CSS 151, 449 PRE_DISPLAY attribute value, component.xml 139
pre-display actions, secondary page 98, 103, 108, 180182 preferences, Java standard portlet 226 prepared SQL statements 292, 294 primary attribute, I18N tag 162 primary JSP files deployment location 75, 198 for chrome styles 67, 69 for grids 83, 87 for secondary pages 95, 111, 113, 141 for styles 47 introduction 47 template header file warning 48, 55, 56 validating forms in 135 primary navigation 58 primary-filename attribute, component.xml 203, 411 printDocumentContent custom JSP tag 358, 365 printDocumentImageURL custom JSP tag 358, 359 printDocumentURL custom JSP tag 358, 359 process actions, secondary page 39, 98, 110, 180 PROCESS attribute value, component.xml 139 process requests, secondary page compared to display requests 36 function of 97 generating 113, 173 processing order 3940 processing-type attribute, component.xml 138, 139, 204, 412 processRequest() method 300 processResponse() method 300, 301 profiles, user 254 properties
507
Content Access Management 336, 339, 342, 344 menu item node custom 63 MetaStore and 250 Portal 190, 489 portlet custom 71 user 257 properties.txt file changes since version 4.x 485, 491 character encoding 170 connection pools and 290 Content Access Management and 307, 353355 metrics system and 279 My Pages and 487 Story Publisher renderers and 369 Vignette Portal logging and 185 <property> element, services 382, 434 property attribute, validation framework 126 property files, I18N deploying 199 for federated search connectors 317, 321, 325 for secondary pages 142 for services 386, 421, 424, 433 for styles 75 introduction 157, 158 See also resource bundles <property-set> element 382, 433 <property-set-definition> element 380, 381, 382, 426 proxied content 298
R
RAW portlet window state 175, 176, 214,
231
RAW view, PortalBean portlets 238
realms, authentication 256, 262, 266 realmSelector custom JSP tag 260, 400 redeployment, portlet application 221 redirection during an AJAX request 180181 to a URL 105 to an error page 105 using the Portal framework 104, 172 using the response 106 within a process action 109 regions, Vignette Portal page See grids registered users 254 registerURL variable 46 registration, portlet application 223 remote data APIs 297303 Remote Session Management API 297298, 299 renderer, customizing Story Publisher 355369 renderPortlet custom JSP tag reference 399, 400, 401 role in rendering content 69, 175, 176 specifying portlet to include 120, 176178 repositories, content 308, 333, 335, 341 repository, Vignette Portal 333, 335 See also MetaStore request, HTTP AJAX and 179183, 215217, 239241 APIs 169 blocking, in portlet applications 223, 224 PortalBeans and 490 remote 297, 300 sharing information using 107 request, HTTPS 35, 105, 181, 212 RequestResponseContext interface 301, 302
508
Index
RequestResponseInterpolator
interface 300, 301 requests, secondary page display 3639, 97, 172 requests, secondary page process compared to display requests 36 function of 97 generating 113, 173 processing order 3940 required validation rule 129 requiredif validation rule 129 resource bundles API calls 160, 164168, 188, 396 introduction 157, 158 secondary pages and 105, 110, 112 styles and 45, 68, 69 See also internationalization; property files response, HTTP AJAX and 179, 183, 216, 240 APIs 169 remote 297, 300 secondary pages and 108 restart() method, services 373 reuse, code 99, 100, 146 roles, portlet 210 Row JavaScript function 443 RSM API 297298, 299
S
SafeMessageFormat class 166
sample code, warning about 22 SAP gateway 20 schema, metrics 278 search, Content Access Management and 334, 337, 342, 349353 search, federated architecture 306309 CAR files 328330
collections 308, 312, 326, 332 component.xml files 318328 connectors 306, 307, 309332 introduction 305 portlet 306, 332, 348 terms 309, 316 SearchConnectorConfig class 312 SearchCriteria class 315 SearchException class 314 SearchResult class 314 SearchResults class 314 secondary files deploying 198 for secondary pages 95, 141 for styles 43, 47, 49 secondary navigation 58 secondary page instances AJAX and 180185 changes since version 4.x 486 creating the primary JSP file 111 CSS and 150, 153 customizing for page display 115121 deploying 137143, 203 developing new 101114 displaying localized values 160 grids and 85 I18N property files and 158, 159 introduction 16, 30, 96 JavaBeans and 103, 112 modifying the look and feel 95 rendering 97 retrieving the current 112 serving over HTTPS 35, 105, 181, 212 support files for 95 See also actions; display requests; process requests secondary page types changes since version 4.x 486 chrome styles and 65 deploying 143, 201 developing new 115
509
grids and 28, 32, 33 introduction 30, 96 sharing code between 146 warning about replacing 115 secondary pages introduction 16, 18, 30, 93 types vs. instances 96 Section 508 guidelines 161 secure requests 35, 105, 181, 212 security filter, for portlet applications 223, 224 Segmentation and Transformation API 298299, 302 segments, user 257 selectedDocument custom JSP tag 358, 365 self-registration link, including in style 50 sendForm AJAX function Java standard portlets and 215, 217 PortalBean portlets and 241 reference 435 styles, secondary pages, and 182, 184 sendMultiPartForm AJAX function Java standard portlets and 216 PortalBean portlets and 240 reference 436 styles, secondary pages, and 183 sendURL AJAX function Java standard portlets and 215 PortalBean portlets and 239 reference 436 styles, secondary pages, and 182 Service Manager configurable services and 372, 372373 federated search and 309, 317, 322328, 331 import feature 387 limitations 373, 375 ServiceController interface 372, 373
element 381, 429 services configuring 372, 372373, 376386 deploying 376387, 420434 federated search 309, 322328, 330, 331 implementations of 375, 378381, 383385 instances of 376, 381382, 385386 introduction 21, 247251 types of 374, 378, 382383 Vignette Portal API 251, 371376 <service-type> element 381, 430 <service-type-definition> element 378, 420 ServletContextListener, and portlet applications 223 ServletRequest object 211 session, HTTP AJAX and 179, 184 remote 297 Vignette Portal classes 170172 SessionInfo class 170, 171, 267 sessionInfo variable 46 SessionUtils class 110, 171 setContentType() method 108 setForward() method 107 setPartialPageURI() method 181, 182, 185 sharing code 99, 100, 146 short validation rule 129 <short-type-id> element 378, 421 Siebel integrations 20 single sign-on 21, 46, 261 SingleValueSearchTerm class 315 sink collections 347, 348
510
Index
site controls style type 50 site variable 46 siteConsoleURL variable 46 sites, Vignette Portal 15, 25 size-based caching strategies 270 soft size-based caching 270 SOLO portlet window state 175, 176, 229 sort order, federated searches 311, 314 source collections 347 spacer GIF, in navigation styles 60 <SPAN> HTML tags 161 SQL statements, and connection pools 291, 294 SSL features 35, 105, 181, 212 SSO 21, 46, 261 standard control styles 5051 Standard user groups 254 start() method, services 373 startLevel variable 57, 59 stop() method, services 373 Story Publisher portlet, customizing 355369 strategies, caching 270271, 272, 274 StringUtils class 110 Struts 121 Style objects 43, 106, 112, 194 style types architecture 43 deploying 7375, 201 developing new 49 including in grids 79, 81 introduction 28, 41 See also template header files style variable 46 styleBlock custom JSP tag 85, 153, 401 <style-info> element 144, 203, 204, 410 styles AJAX and 178, 180185
architecture 43 chrome 6571 code examples 7678 control 5051, 82, 83 CSS and 150, 153 deploying 7275, 203 developing new 18, 4971 displaying localized values 160 footer 71 grids and 85 header 29, 49 introduction 16, 18, 28, 41 modifying the look and feel 47 navigation 31, 5165 support files for 43, 47, 48 template header file warning 44, 48, 55, 56 See also template header files StyleUtils class 155 support files deploying 198 for grids 83 for secondary pages 95, 141 for styles 43, 47, 48 See also primary JSP files
supportsReinitialization()
method 373
supportsStop() method 373
system (out-of-the-box) components for grids 80 for navigation styles 53 for portlets 20
T
t0005style attribute value, component.xml 87
tables, HTML 152, 455461 See also CSS tables, relational database See database
511
tag libraries Java standard portlet 210 JSTL performance issues 18 PortalBean 488 Story Publisher portlet 358 Vignette Portal 44, 89, 160, 488 See also JSP tags, Vignette Portal taxonomy capabilities 348 <TD> HTML tag 151, 449 See also tables, HTML telephone number attributes, Java standard portlets 212 template header files deploying 75, 198, 417 for chrome styles 66 for static navigation styles 57 introduction 43 warning about applying 48, 55, 56 warning about reusing 44 Template objects 43, 188, 194 template0005 attribute value, component.xml 87 template-default attribute, component.xml 203, 411 <template-info> element for secondary page types 143, 144, 201, 202 for style types 74, 201 reference 415 templates, Vignette Builder 20, 277 template-uid attribute, component.xml 203, 411 TemplateUtils class 188 text content types, AJAX and 183, 216, 240 text/css content type 155 text/html content type 108 text/wml content type 108 TextProcessor interface 298 <TH> tag, in Vignette Portal CSS 151, 449
See also tables, HTML themes associating to styles 48 branding and 189 CSS and 150152, 154, 447469 introduction 29, 34, 42 navigation styles and 54 See also Contemporary theme; Linear theme _thisStyleID variable 46 _thisStyleObject variable 46 _thisTitle variable 46 threading, PortalBean 177 throwables, logging 185 time-based caching strategies 270, 272 titles, component defining in component.xml 200, 377, 408 formatting with CSS 151, 452 including in grid 85 tokens, and remote content 298, 303 TOTAL_NUMBER_OF_LEVELS variable 57 <TR> tag, in Vignette Portal CSS 151, 449 See also tables, HTML transformations, remote data 298299, 303 translation See localization ttl 272 type attribute, component.xml 74, 202, 416 type selectors, CSS 449 <type-id> element 382, 432 <type-version/> element 379, 424
U
UI design using CSS 149155 using grids 8391 using styles 4771
512
Index
Ultraseek indexing engine 351 unique identifiers description 200, 377 retrieving 112, 160, 187 unparsable indexing engine 351, 354 uploading See deployment URLs AJAX 180, 181184, 214215, 239 changes since version 4.x 485 generating 104109, 172174 PortalBean 490 returning in action classes 104 Vignette Portal, elements of 34, 35 User class 255, 267 user data, accessing 170, 255 user groups 254, 258 user management, Vignette Portal 21, 211, 253259 user registration 50, 254 See also authentication user segments 257 user variable 46 UserGroupManager class 258 UserManager class 255, 256 utility APIs, Vignette Portal 191
rules 125, 128, 132, 136 validation.xml file creating 125133, 197 deploying 142, 196, 199 function of 122 ValidationTestSuite class 132 <validator/> element 126, 127128, 132, 133 Validator class (Apache) 133 Validator class (Vignette Portal) 135 ValidatorAction class (Apache) 133 value attribute, I18N tag 163
<value-property-definition>
element 380, 427 vapajaxlibrary.js file 179, 214, 238 <var> element, validation framework 126 variables, template header file for all styles 44 for chrome styles 66 for static navigation styles 57 version support property, Vignette Portal 485 versioning, Vignette Portal component 200, 204, 377, 379 vertical navigation styles 52
vgn-jsr-container-taglib.jar
location 210
vgn-portal-core.jar file 237 <vgn-portal:defineObjects/> tag
V
validation framework action class development 135 field variables 134 FormBean and 122, 135 introduction 121 method example 132 parameter restrictions 134 primary JSP file coding 135 resources 133, 134
393
<vgn-portal: i18nFormattableValue/> tag
164, 393
<vgn-portal:i18nParam/> tag 162,
164, 394
513
164, 395
<vgn-portal:i18nValue/> tag
257, 398
<vgn-portal: insertPortletContent/> tag
260, 400
<vgn-portal:renderPortlet> tag
reference 399, 400, 401 role in rendering content 69, 175, 176 specifying portlet to include 120, 176178 <vgn-portal:styleBlock/> tag 85, 153, 401 vgn-tags taglib See JSP tags, Vignette Portal VIEW mode, Java standard portlets 225, 230, 231 view.jsp file, Story Publisher 357, 359, 366
358, 359 Vignette Builder 19, 20, 277 Vignette Business Integration Studio 20 Vignette Contemporary components control styles 50, 82 grid 81, 82 header style 49 navigation styles 48, 53, 56 Vignette Content 334 Vignette Content Delivery Connector 334 Vignette Global Marketplace 21 Vignette IDM 20 Vignette Linear components control styles 50 grids 81 navigation styles 48, 54, 5455, 59 Vignette Portal architecture overview 1621, 2540, 43, 193194 compatibility with version 4.x 485491 development overview 1722, 40 feature overview 15, 247251 portlet packaging tool 220 Vignette Records and Documents 20 visibility component 202 menu item node 64 visible attribute, component.xml 147, 202, 412, 416 visitors, portal See guests, portal vocabulary, search 309, 316
W
WAR files Java standard portlets 220, 222 Vignette Portal 17, 196
514
Index
X
XML files See component.xml files;
validation.xml file XMLHttpRequest object 180 xmlns:epideploy attribute, component.xml 201, 377, 408
web application restart deployment system and 196 for federated search connectors 331 for portlet applications 221 for secondary pages 142 for services 387 for Story Publisher renderers 369 web services 19, 20, 150, 234 web sites vs. Vignette Portal sites 15 web.xml file, Java standard portlets 219, 222, 223, 224 WebConnector portlet 20, 299303 <web-deployment-path> element 321, 368 WEB-INF directory <web-deployment-path> element and 321 CAR file structure and 198, 199 Content Access Management and 341 custom search connectors and 329 for custom search connectors 329, 330 for secondary pages 141, 142 for services 386, 387 for Story Publisher renderers 367 for styles 75 I18N property files and 159, 421, 424, 433 portlet tag library and 210 Vignette Portal WAR file and 196 welcome message, including in style 50 Wireless Markup Language 108 workflow, Content Access Management 337, 338, 344, 346 writable connectors, Content Access Management 337, 343, 345 WSRP 19, 150, 175
515
516
Index