You are on page 1of 516

Vignette Portal

Developers Guide

Version 7.4; LD1

Version
Vignette Portal Developers Guide, version 7.4 LiveDocs Update 1 (October, 2008)

Copyright and Trademarks


Copyright 1996-2008 Vignette Corporation. All rights reserved. Vignette and the V Logo are trademarks or registered trademarks of Vignette Corporation in the United States and other countries. All other company, product, and service names or brands are the trademarks or registered trademarks of their respective owners.

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.

Send Us Your Comments


If you have comments or suggestions about this manual, please send them to this address:

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

Section I: Portal Site Development


1 Vignette Portal Web Site Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
The Site Presentation Framework . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Overview of a Vignette Portal HTML Page . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Grids . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Style Types, Styles, and Themes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Secondary Pages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Vignette Portal Page Composition: Putting the Pieces Together . . . . . . . . . . . Vignette Portal and Request Handling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . URLs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Display Requests vs. Process Requests . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Design Points for Vignette Portal Site Development . . . . . . . . . . . . . . . . . . . . . .
25 26 27 28 30 33 34 34 36 40

2 Controlling Navigation and Appearance with Styles . . . . . . . . . . . . . 41


Introduction to Style Types and Styles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Style Type and Style Architecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Template Header Files for Style Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Support Files for Styles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Modifying the Look and Feel of Existing Styles. . . . . . . . . . . . . . . . . . . . . . . . . . Developing Styles and Style Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Header Style Type and Styles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
41 43 43 47 47 49 49

Portal Developers Guide

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

3 Controlling Page Structure with Grids . . . . . . . . . . . . . . . . . . . . . . . . . . . 79


Introduction to Grids . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Grids Shipped with Portal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Modifying the Look and Feel of Existing Grids . . . . . . . . . . . . . . . . . . . . . . . . . . Developing Grids . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Custom JSP Tags Used in Grids . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Deploying a Grid. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Component Descriptor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . CAR File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Uploading the CAR File into Portal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Grid Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
79 80 83 84 85 86 86 87 88 88

4 Controlling Functionality with Secondary Pages . . . . . . . . . . . . . . . . 93


Introduction to Secondary Pages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93 Modifying the Look and Feel of an Existing Secondary Page . . . . . . . . . . . . . . . 95 Secondary Page Types and Secondary Page Instances . . . . . . . . . . . . . . . . . . . . . 96 Secondary Page Rendering . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97 Display Requests and Process Requests . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97 Actions: Where Secondary Pages Do Processing . . . . . . . . . . . . . . . . . . . . . . . . . 98 Action Reuse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99 Actions on Secondary Page Instances . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100 Developing a Secondary Page Instance. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101 Step 1: Plan Your Work . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102 Step 2: Create Any Pre-Display Actions . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103 Step 3: Create Any Process Actions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109 Step 4: Create the Primary JSP File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111

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

5 Using Cascading Style Sheets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149


Customizing the Look and Feel of Your Portal. . . . . . . . . . . . . . . . . . . . . . . . . . Vignette Portal CSS, Themes, and End-User Settings . . . . . . . . . . . . . . . . . . CSS, the Java Portlet Standard, and WSRP . . . . . . . . . . . . . . . . . . . . . . . . . . Working with the Vignette Portal CSS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . HTML Elements Requiring No CSS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Using Portal CSS Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . How CSS Values Map to Portal Themes and End-User Settings. . . . . . . . . . Customizing the CSS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Overriding the Portal Style Sheet. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Style Sheets That Respond to Administrator and End-User Settings . . . . . . . Caching Custom Style Sheets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
149 150 150 151 151 151 152 153 153 154 155

6 Internationalizing and Localizing Site Components . . . . . . . . . . . . . 157


Vignette Portal, I18N, and L10N . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Portal Users and Language Preference . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Precedence Algorithm for Locale Selection. . . . . . . . . . . . . . . . . . . . . . . . . . Creating I18N Property Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Accessing Localized Values in Component Code. . . . . . . . . . . . . . . . . . . . . . . . Custom JSP Tags . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . I18N Format Java Package . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Java Utility Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
157 158 158 158 159 160 164 166

Portal Developers Guide

7 Using the Site Development APIs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169


Working with the Request and Response . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Working with the Session . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . SessionInfo Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . SessionUtils Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Generating URIs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Creating Display URIs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Creating Process URIs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Invoking a Specific Page by Creating a Page URI . . . . . . . . . . . . . . . . . . . . . Adding Parameters to a URI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Displaying Portlets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Out-of-the-Box Components that Render Portlets . . . . . . . . . . . . . . . . . . . . . Specifying the Portlet to be Rendered . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . AJAX-Enabling Portal Components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Portal and Third-Party AJAX Toolkits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Vignette Portal AJAX Library . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Writing to the Vignette Portal Log . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Handling Errors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Using UIDs and Friendly IDs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Working with Portal Branding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Retrieving System Properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Retrieving the Portal Installation Location . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Vignette Portal Utility Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Vignette Portal Constants and JSP Variables . . . . . . . . . . . . . . . . . . . . . . . . . . .
169 170 170 171 172 172 173 173 174 174 175 176 178 178 179 185 186 187 189 190 190 191 191

8 Deploying Site Components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193


Vignette Portal Component Architecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Deployment Process Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Uploading Components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Downloading Components. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Component Archive File Structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Component Descriptor File Structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Component Details for Style Types and Secondary Page Types . . . . . . . . . . Component Details for Styles, Grids, and Secondary Pages . . . . . . . . . . . . . Component Uniqueness and Versioning . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
193 195 196 197 198 199 201 203 204

Contents

Section II: Portlet Development


9 Java Standard Portlets and Vignette Portal . . . . . . . . . . . . . . . . . . . . . 209
Overview of Vignette Portal and Java Standard Portlets . . . . . . . . . . . . . . . . . . Java Standard Portlet Tag Library . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Roles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . User Attribute Mapping . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Handling URL Security Exceptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . AJAX-Enabling Portlets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . JSR 168 Specification and AJAX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . JSR 286 Specification and AJAX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Using the Portal AJAX Library . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
209 210 210 211 212 212 213 214 214

10 Deploying a Java Standard Portlet into a Portal Instance . . . . . . 219


Deployment Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Using the Vignette Portal Portlet Packaging Tool . . . . . . . . . . . . . . . . . . . . . . . Using the Vignette Portal Script . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Creating an Ant Build File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Changes Applied by the Tool . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Enabling Direct Requests to a Portlet Application . . . . . . . . . . . . . . . . . . . . . . .
219 221 222 222 223 224

11 Using Portlet Modes and Window States . . . . . . . . . . . . . . . . . . . . . . 225


Portlet Modes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Portlet Window States . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . BINARY Window State . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . SOLO Window State . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . RAW Window State . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
225 226 227 229 231

12 PortalBean Portlets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233


Java Standard Portlets vs. PortalBean Portlets . . . . . . . . . . . . . . . . . . . . . . . . . . Vignette Portal and the PortalBean Framework . . . . . . . . . . . . . . . . . . . . . . . . . Support for Standards-Based Portlets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Creating a URI to Another PortalBean . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Minimizing Portlets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Remote Content APIs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Deprecation of Administrator PortalBeans . . . . . . . . . . . . . . . . . . . . . . . . . .
233 234 234 235 235 236 236

Portal Developers Guide

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

Section III: Portal Services


13 Portal Services Overview. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 247
Available Portal Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 247 Storing Data in the MetaStore . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 250 Services API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 251

14 Users and Access Control . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 253


Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . User Management . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . User Access APIs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . User Group Access APIs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Authentication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Controlling Guest Access to Components . . . . . . . . . . . . . . . . . . . . . . . . . . . Creating a Custom Authenticator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Authorization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
253 253 255 258 260 260 261 267

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 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

272 274 274 275

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

17 Connection Pooling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 289


The Vignette Portal Connection Pooling System . . . . . . . . . . . . . . . . . . . . . . . . Connection Pooling Code Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Initializing a Connection Pool . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Using the Connection Pool . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Support for Oracle LOBs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
289 290 290 291 294

18 Remote Content Retrieval and Manipulation . . . . . . . . . . . . . . . . . . . 297


Retrieving Content from Remote Sources. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Inspecting and Altering Proxied Content . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Customizing the WebConnector 3.0 Portlet . . . . . . . . . . . . . . . . . . . . . . . . . . . . Accessing the Remote Request and Response . . . . . . . . . . . . . . . . . . . . . . . . Using a Custom Authenticator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
297 298 299 300 302

Portal Developers Guide

Performing Custom Segmentations and Transformations . . . . . . . . . . . . . . . 302

19 Customizing Federated Search . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 305


Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Federated Search Architecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Search Connectors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Repositories and Collections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Search Terms and the Common Vocabulary . . . . . . . . . . . . . . . . . . . . . . . . . Creating a Custom Search Connector . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Step 1: Plan the Implementation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Step 2: Implement the ISearchConnector Interface . . . . . . . . . . . . . . . . . . . . Step 3: Define the Connectors Search Field Names . . . . . . . . . . . . . . . . . . . Step 4: Create the I18N Property Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Step 5: Create Component Descriptors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Step 6: Package the Connector for Deployment . . . . . . . . . . . . . . . . . . . . . . Step 7: Test the Connector . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
305 306 307 308 309 309 310 311 316 317 318 328 331

20 Using the Content Access Management and Indexing APIs . . . 333


Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . CAM Architecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Folders and Documents . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Capabilities . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Using the Access API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Content Item Interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Workflow Support . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ContentManager Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Utilities and Exceptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Developing Data Source Connectors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Base Interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Capability Interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Connector Configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Developing Search Engine Connectors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Search Interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Indexing Interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
333 335 336 336 337 337 338 338 339 339 341 342 342 344 345 347 349 350

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 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

352 353 355 357 366 369 369

21 Developing and Deploying Custom Services . . . . . . . . . . . . . . . . . . 371


Services and Vignette Portal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Developing a Configurable Service . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ServiceController Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Controllable Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Service Components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Service Type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Service Implementation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Service Instance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Deploying Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Creating the Component Descriptor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Creating the CAR File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Uploading the CAR File into Portal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
371 372 372 373 374 374 375 376 376 376 386 387

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

Portal Developers Guide

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

B Deployment Reference . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 405


Component Descriptor Structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . <epideploy:component> Element . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . <epideploy:required-component/> Element. . . . . . . . . . . . . . . . . . . . . . . . . . <epideploy:detail> Element . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Detail Elements for Styles, Grids, and Secondary Pages . . . . . . . . . . . . . . . . . . <style-info> Element . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . <actions> Element . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . <action> Element . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . <class> Element . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . <group-reference> Element . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Detail Elements for Style Types and Secondary Page Types . . . . . . . . . . . . . . . <template-info> Element . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . <actions> Element . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . <action> Element . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . <class> Element . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . <group> Element . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Detail Elements for Service Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . <service-type-definition> Element . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . <short-type-id> Element . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
406 406 408 410 410 410 412 413 414 414 415 415 417 418 419 419 420 420 421

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

C Vignette Portal JavaScript Functions. . . . . . . . . . . . . . . . . . . . . . . . . . . 435


AJAX Library . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . sendForm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . sendMultiPartForm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . sendURL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Generic Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . appendToHandler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . cm_bwcheck . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . cm_makeObj . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . cm_page . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
435 435 436 436 437 437 437 437 440

Portal Developers Guide

13

_getPageOffsetLeft . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . _getPageOffsetTop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Drag-and-Drop Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . cm_scrolldown . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . cm_scrollleft . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . cm_scrollright . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . cm_scrollup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Column . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Row . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

440 440 441 441 441 441 441 441 443

D Vignette Portal CSS Reference . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 447


Font and Color Settings in the Administration Consoles . . . . . . . . . . . . . . . . . . Vignette Portal Type Selectors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Vignette Portal CSS Classes (Class Selectors) . . . . . . . . . . . . . . . . . . . . . . . . . . Mapping of Theme Settings to CSS Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . Deprecated Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
447 449 450 464 483

E Compatibility with Version 4.x . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 485


URLs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Secondary Pages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Page Display Secondary Page . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Upgrade Notes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . JSP Programming Constructs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . System Properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . CSS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . I18N . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Changes Affecting PortalBeans . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
485 486 486 486 488 489 489 489 490

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

Vignette Portal Features and Concepts


Vignette Portal enables customers to rapidly build, customize, and manage multiple web initiatives across the extended enterprise. Portal ships with all of the capabilities required to begin creating and managing a portal immediately. In addition, web designers and Java developers can customize many of the out-of-the-box Portal features: the look and feel of Portal pages, the functionality available to end users, and the underlying Portal services (such as authentication, metrics, and caching).

Vignette Portal Sites


Generally speaking, a web site refers to all of the HTTP- or HTTPS-accessible URLs (or pages) under a given domain, such as www.company.com. The pages of a web site are typically unified by a common purpose, look and feel (such as fonts, colors, and logos), and navigational elements. A Vignette Portal site is a collection of administrable components that provide look and feel, content, functionality, and navigation structure. Sites are created and administered via the Portal administration consoles. Administrators can share components between sites, thereby reusing functionality, look and feel, and applications. The principal components of sites are portlets (providing pluggable applications), grids (controlling the

Portal Developers Guide

15

Vignette Portal Features and Concepts

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

Vignette Portal J2EE Architecture


Vignette Portal runs within a J2EE application server environment. As Figure 2 shows, multiple J2EE web applications are involved. In addition to the Portal web application, each individual Java standard portlet (JSR 286 application) is deployed as an individual web application.

16

Introduction

Points of Customization

Figure 2:

J2EE Web Applications


J2EE Application Server Vignette Portal (a WAR)

end user

Java Standard Portlet Applications (WARs)

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

Portal Developers Guide

17

Points of Customization
intranet site

Figure 3:

Portal High-Level Architecture


Site Presentation Framework

Portal

Site Components grids styles secondary pages

extranet site
multiple initiatives

Portal Services authentication user management search content management etc.

Portlets

corporate site

Customizing End-user Components


The Portal framework has a component architecture that allows individual pieces of an end-user web site to be customized as needed. Two types of components control the look and feel of the site: grids and styles. Grid and style development requires only JSP scripting skills. No Java skills are needed. Vignette provides custom JSP tags that simplify JSPs by encapsulating portions of the assembly and UI generation logic. A type of component called a secondary page controls the functionality of the site, such as how users log in, how users manage their Portal accounts, and how users select what portlets to view on any given page. Secondary page development often requires only JSP skills, although Java developers can perform deep customizations. End-user components support use of interactive technologies such as AJAX and DHTML. These technologies apply primarily to styles and secondary pages. In addition to supporting third-party and home-grown AJAX wizard toolkits, Vignette Portal provides its own AJAX library. Section I of this guide explains how to customize end-user components.

18

Introduction

Points of Customization

Integrating Content and Applications


Vignette Portal can integrate with portlets, Vignette Builder, .NET technology, and standards-based technologies to provide access to applications and content. Table 1 summarizes how Vignette Portal integrates with various technologies.
Table 1: Vignette Portal and Integration Technologies Access to Vignette Portal APIs Limited Java Standard Portlets Full PortalBean Portlets Vignette Builder WSRP Web Service Standards .NET Limited Limited None Limited but extensible Business analyst Variable XML, SOAP, WSDL Visual Studio .NET, VisualBasic Java, JSP, XML Where Application Logic Resides Locally (same VM, different web application) Locally (same VM and web application) Remotely Remotely Remotely Remotely

Technology

Developer Skill Set Java, JSP, XML

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.)

Portal Developers Guide

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.

Using and Customizing Vignette Portal Services


The Portal framework includes services that perform common portal and web tasks such as authentication, user management, and database connectivity. System administrators can customize a number of services by configuring Vignette Portal, and Java developers can perform deeper customizations by creating their own implementations of certain services. For example, Vignette Portal provides a default SQL user manager, a default SQL authentication implementation, and a default connection pool shared by all Portal data. System administrators can configure Portal to use one of the other shipping user managers (various JNDI implementations) or authenticators (JNDI, NT, and SSO), to change the default connection pool properties, or to configure multiple connection pools. Developers can customize these out-of-the-box services in a number of ways, such as adding fields to the Portal user table and to the Portal page that collects user data, implementing a custom authenticator, and dynamically creating and managing connection pools. Other examples of services are metrics and caching, both of which can be useful in developing portlets and Portal pages. Section III of this guide describes how to use and customize Vignette Portal services. Appendix B, Deployment Reference, provides information about packaging and deploying a custom service for use with Vignette Portal.

Portal Developers Guide

21

Using This Guide

Using This Guide


This guide explains how those with web development and Java skills can customize Vignette Portal. Table 2 maps the various development roles to the chapters of this guide that are associated with each.
Table 2: Development Roles and Contents of This Guide See

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

use Java, XML, and related technologies to customize your portal

All chapters and appendices of this guide

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

Section I: Portal Site Development

1
Summary: Audience: Topics:

Vignette Portal Web Site Overview


Describes the main components of a Vignette Portal site and explains how they interact Web page developers

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

The Site Presentation Framework


The site presentation framework of Vignette Portal is responsible for assembling pages for the end user. The framework itself is a set of J2EE filters, servlets, and Java classes that handle such overall tasks as system initialization, authentication, and authorization. Once those tasks are completed, the framework selects the appropriate Portal componentssecondary pages, grids, and stylesto service requests (see Figure 4).

Section I: Portal Site Development

25

Overview of a Vignette Portal HTML Page

Figure 4:

Overview of the Site Presentation Framework

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.

Overview of a Vignette Portal HTML Page


An HTML page within a Vignette Portal site is composed of regions, such as headers and footers. The regions included on a particular page depend upon its purpose and look-and-feel settings. For example, the login page might have a header, a footer, and a region where the login form is displayed, whereas many pages of a site also have a navigation region (see Figure 5).

26

Vignette Portal Web Site Overview

Overview of a Vignette Portal HTML Page

Figure 5:

Examples of Regions within Portal HTML Pages


Header Page Content

Footer

page with 3 regions


Header Navigation Page Content

Footer

page with 4 regions

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>

Grid with Three Regions


Grid Header Page Content

Footer

Section I: Portal Site Development

27

Overview of a Vignette Portal HTML Page

Grids can define two types of regions (see Figure 7):


Regions containing decorative and navigational elements (like headers,

footers, and menus). These elements are called styles.


A single region for the primary content/functionality of the page (like login,

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

Grid with Two Styles and the Mandatory Secondary Page

style of type "header"

secondary page

Footer

style of type "footer"

See also:

Chapter 3, Controlling Page Structure with Grids, for details about grid development

Style Types, Styles, and Themes


Each type of style corresponds to a Portal component called a style type. A style type can have many different implementations. Each implementation is a Portal component that is simply called a style. Each style provides a different look and feel for a style type. Figure 8 shows three styles of the "header" style type.

28

Vignette Portal Web Site Overview

Overview of a Vignette Portal HTML Page

Figure 8:

Three Implementations of the "Header" Style Type

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

Grid Style type: header Page Content

style
"basic" "basic" "basic" "basic"

Page Content

"basic" footer Style type: footer

See also:

Chapter 2, Controlling Navigation and Appearance with Styles, for details about style and style type development

Section I: Portal Site Development

29

Overview of a Vignette Portal HTML Page

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

Portlet Pages and JSP Include Pages

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

Vignette Portal Web Site Overview

Overview of a Vignette Portal HTML Page

the sites menus (see Figure 10). The end-user site displays the navigation via navigation styles (see Figure 11).
Figure 10:
navigation tree

Navigation Tree with Three Menu Items

Home

Portlet Page X Portlet Page Y Portlet Page Z

Products

Services

Figure 11:

Navigation Tree Rendered by a Navigation Style

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).

Section I: Portal Site Development

31

Overview of a Vignette Portal HTML Page

Figure 12:

Page Display Secondary Page

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

Vignette Portal Web Site Overview

Overview of a Vignette Portal HTML Page

Figure 13:
login

Grids for Two Different Secondary Page Types


main view of portal site style of type "navigation"

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"

main view with horizontal navigation

Vignette Portal Page Composition: Putting the Pieces Together


Heres the composition process for the login HTML page of a Vignette Portal site:
1 2 3 4

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.

Section I: Portal Site Development

33

Vignette Portal and Request Handling

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

3. Execute grid, applying theme

end user

asks for login page


Style type: footer

Vignette Portal and Request Handling


This section explains how Vignette Portal uses site components to handle requests. It steps through the life of a request and identifies the major touchpoints.

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

Vignette Portal Web Site Overview

Vignette Portal and Request Handling

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

Section I: Portal Site Development

35

Vignette Portal and Request Handling

Display Requests vs. Process Requests


A request to Vignette Portal can be one of two types:
Display requestA request to display something. A display request

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

page being returned, with a login form rendered within it.


Clicking the submit button on the login form results in a process request to

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

Vignette Portal Web Site Overview

Vignette Portal and Request Handling

Figure 17:

Login Display and Process Requests


Portal Asks for login screen (a DISPLAY request) Site Presentation Framework Grid Styles Secondary Page Renders login using a grid, styles, and a login secondary page.

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

Asks for main view (a DISPLAY request)

Portal Site Presentation Framework Grid Styles Secondary Page Renders main view using grid, styles, and page display secondary page.

Display Requests

The processing order in a display request is as follows:

Section I: Portal Site Development

37

Vignette Portal and Request Handling

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

Figure 18 shows this control flow.


Figure 18: Display Request Control Flow
Portal Site Presentation Framework DISPLAY request 1 Secondary Page Process Actions Display Actions JSP Grid 2 JSP Styles JSP 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

Vignette Portal Web Site Overview

Vignette Portal and Request Handling

Figure 19:

Display Request Alternative Control Flow


Portal Site Presentation Framework DISPLAY request 1 redirect Display Actions JSP Grid JSP Styles JSP Secondary Page Process Actions

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.

Section I: Portal Site Development

39

Design Points for Vignette Portal Site Development

Figure 20:

Process Request Control Flow


Portal Site Presentation Framework PROCESS request Display Actions Secondary Page 1 Process Actions

end user

JSP

Design Points for Vignette Portal Site Development


All Vignette Portal site components have access to some commonly used objects and JSP features, including these:
A Portal context, which provides access to

The request and response objects Portal-related context about the current request, like the current user Encapsulation of the URL creation logic

A branding object, which provides access to look-and-feel information

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

inclusion, portlet inclusion, and secondary page inclusion


User-defined friendly IDs that Portal maps internally to unique identifiers
See also:

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

Vignette Portal Web Site Overview

2
Summary: Audience: Topics: See also:

Controlling Navigation and Appearance with Styles


Describes the various style types and styles within Vignette Portal and explains how to customize them JSP or Java developers responsible for customizing the Vignette Portal end-user site

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

Introduction to Style Types and Styles


A style type is an abstraction that corresponds to a particular region of a web page, such as the header, the navigation, or the chrome (border, title bar, or other elements displayed with a portlet). A Portal page can have several style types, as shown in Figure 21.

Section I: Portal Site Development

41

Introduction to Style Types and Styles

Figure 21:

Style Types on a Portal Page


Site Controls Account Controls Horizontal Navigation Page Controls Chrome Chrome

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

component has not been explicitly associated with a specific style.


Themes can be defined that contain collections of styles designed to be

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

Controlling Navigation and Appearance with Styles

Style Type and Style Architecture

Style Type and Style Architecture


Style types (as well as secondary page types and the overall collection of grids) are represented by com.epicentric.template.Template objects. Styles (as well as secondary pages and grids) are represented by com.epicentric.template.Style objects. Each Style object is a specific instance of a Template. The Vignette Portal framework handles much of the management of Template and Style objects, including their creation and persistence. You therefore should not need to use many of the methods on these objects directly. Use the Portal administration consoles to add, duplicate, export, import, and delete styles and style types. A style type can include the following files:
An optional template header file (template_header.inc), providing

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

secondary files (such as images) that the primary file requires


Component descriptor (component.xml file), required to upload the style

using the deployment system


See also: Chapter 8, Deploying Site Components, for a discussion of component.xml files and the deployment system

Template Header Files for Style Types


Each style type can have a template header file, which contains common logic for some (or all) of the styles of its type. The Vignette Portal convention is to name this file template_header.inc. Template header files prevent code duplication by declaring variables and (in some cases) performing specific functions that primary JSP files can then use. When working with template header files, keep the following caveats in mind:
If a variable is declared in the template header file of a style type, do not

declare the same variable in the primary JSP or other support files for styles of that type.

Section I: Portal Site Development

43

Style Type and Style Architecture

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

Variable Name adminURL

Description String defining the site administration console link for the current site

44

Controlling Navigation and Appearance with Styles

Style Type and Style Architecture

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

Section I: Portal Site Development

45

Style Type and Style Architecture

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

site siteConsoleURL SSO SSO_attr

style _thisStyleID _thisStyleObject _thisTitle user

46

Controlling Navigation and Appearance with Styles

Modifying the Look and Feel of Existing Styles

Support Files for Styles


Every style has a primary file, which is a JSP file containing the code needed to execute the style. Any logic that isnt shared with other styles of the same style type goes in the primary file. Such logic includes displaying buttons or links the style is responsible for as well as checking which display elements should be rendered for the current request. When the primary file of a style is first uploaded, the Portal framework checks whether it uses its style types template header file. If so, the framework includes the contents of the header file into the primary file (using the JSP include directive). The resulting file is compiled and executed when the style is called. IMPORTANT: Primary files do not have opening and closing <html>, <head>, or <body> tags. These tags are included by the grid, which in turn includes the style. Styles can also have any number of secondary files. Most commonly, secondary files are image files, but they can also be any other type of file that the primary file requires: CSS, JavaScript, include files, etc. The list of support files for any style can be viewed from the administration consoles (Components >> Style List >> Style Name >> Support Files). You can also use the Support Files page to download and upload custom styles that youve created as well as duplicates of styles that ship with Portal.

Modifying the Look and Feel of Existing Styles


You can customize the physical appearance of an out-of-the-box style simply by editing its primary JSP file. This process does not require Java coding, component deployment, or a Portal application restart.
To modify the look and feel of an existing style: 1 2 3

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.

Section I: Portal Site Development

47

Modifying the Look and Feel of Existing Styles

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

Controlling Navigation and Appearance with Styles

Developing Styles and Style Types

Developing Styles and Style Types


If you want to customize the appearance of Portal pages, you can create your own implementations of the Portal style types. You can also add functionality that is not provided by any of the Vignette styles by creating custom styles. For example, you might want to incorporate a login field, a search feature, a portlet, or the ability to choose a language within a style. You develop a custom style by creating its primary file and creating any secondary files that it needs. You can use an existing style as the starting point for a new one by duplicating the existing style, exporting it, and modifying the duplicate. In most cases, you do not need to create custom style types; Portal ships with style types for many different regions of a Portal page. Should you need to develop a new style type, simply create a template header file for common variable declarations and other code that styles of the new style type can use. (Of course, youd also need to create styles of your new style type.) The following sections describe the style types and styles that ship with Portal. The end of the chapter explains how to use the deployment system to import custom styles and style types into Portal.
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

Header Style Type and Styles


The Header style type defines the area at the top of a Portal page. Styles of this style type usually display the principal branding of the site, such as the site title or an image. Header styles can also include links or buttons for URLs. Most out-of-the-box Header styles simply display the site title, as a localizable string, within the region specified by the grid (see Figure 22). The Vignette Contemporary Header style displays an image that links to the sites "home" URL.

Section I: Portal Site Development

49

Developing Styles and Style Types

Figure 22:
Header

Sample Header Style

Style Types and Styles for Standard Controls


Three different style types handle the inclusion of controls that link to basic functions that a portal needs, such as logging in, logging out, personalizing colors, and returning to the main view of a site. These control style types are as follows:
Site Controls Links and buttons for using built-in site features, such as

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

Controlling Navigation and Appearance with Styles

Developing Styles and Style Types

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

Variable Name allNodes

Description List of all menu items for the current request

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.)

Navigation Style Types and Styles


Whereas the control style types support general navigation of a portal (logging out and in, returning to the current sites home page, etc.), the navigation style types define the look and feel of menus and submenus that provide access to the pages of a particular site. The Portal administration consoles enable menus and submenus to be created for sites and to be shared between sites.

Section I: Portal Site Development

51

Developing Styles and Style Types

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

Controlling Navigation and Appearance with Styles

Developing Styles and Style Types

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

Horizontal, Vertical, and Split Navigation Examples


Vertical

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

Navigation Styles Shipped with Vignette Portal

The following navigation styles are the current out-of-the-box implementations:


Vignette Linear Nav Vert Interactive Vignette Contemporary DHTML Horizontal Navigation Vignette Contemporary DHTML Vertical Navigation

Section I: Portal Site Development

53

Developing Styles and Style Types

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

AJAX-Enabled Navigation Styles

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

Controlling Navigation and Appearance with Styles

Developing Styles and Style Types

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

DHTML Navigation Styles

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):

Section I: Portal Site Development

55

Developing Styles and Style Types

They display only the first level of the navigation tree (unless the site is

using a navigation split).


They use calculated gradations of color to distinguish the currently selected

navigation item and the path to that item.


On mouse-over, they highlight each navigation item that is part of the path

to the one over which the mouse is positioned.


Figure 25: DHTML Navigation Example

At the code level, the Vignette DHTML navigation styles share additional characteristics:
They use functions from the Vignette Portal JavaScript library as well as

their own custom JavaScript functions.


They include non-DHTML code for use with browsers that do not have

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

Controlling Navigation and Appearance with Styles

Developing Styles and Style Types

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

Variable Name allLevels endLevel nodesInHorizontalOrder nodesInVerticalOrder startLevel TOTAL_NUMBER_OF_LEVELS

In addition, the static navigation style types declare the following standard variables in their template header file:

i18nID pageBackgroundColor _pathToImages portalHttpRoot _thisStyleID _thisStyleObject


See also: Template Header Files for Style Types on page 43 for a description of each of the standard variables

Section I: Portal Site Development

57

Developing Styles and Style Types

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

Controlling Navigation and Appearance with Styles

Developing Styles and Style Types

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

Working with Navigation Items

Each item in a navigation tree is an instance of the


com.epicentric.common.website.MenuItemNode class. Because the

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.

Section I: Portal Site Development

59

Developing Styles and Style Types

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 { %> &nbsp;<a href="<%= node.getHref() %>" <%=node.getTarget()%> class="epi-link3"> <%=node.getTitle()%></a>&nbsp; <% } %> 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:

getFriendlyURIFromMenuItemID(String menuItemID) getMenuItemIDFromFriendlyURI(String friendlyURI, Site site)

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

Controlling Navigation and Appearance with Styles

Developing Styles and Style Types

Figure 27:

isSelected() and wasSelected() Nodes

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.

IMAGE_NORMAL IMAGE_NORMAL_HOVER IMAGE_SELECTED IMAGE_SELECTED_HOVER

Here is an example of the code that enables display of a MenuItemNodeImage:

Section I: Portal Site Development

61

Developing Styles and Style Types

<% 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 %> &nbsp;<a href="<%= node.getHref() %>" <%=node.getTarget()%> class="epilink3"><%=node.getTitle()%></a>&nbsp; <% } %>

The following out-of-the-box styles have built-in support for images in navigation items:
Vignette Linear Nav Horz

62

Controlling Navigation and Appearance with Styles

Developing Styles and Style Types

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

Section I: Portal Site Development

63

Developing Styles and Style Types

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

Controlling Navigation and Appearance with Styles

Developing Styles and Style Types

hidden. Other methods on MenuItemUtils enable you to retrieve either visible menu items or all menu items.

Chrome Style Type and Styles


Styles of the Chrome style type display portlet views within a Portal page. Chrome styles render the portlet content as well as define the appearance of the portlet window, which can include a border, title bar, and buttons for users to interact with individual portlets. Figure 28 shows an example of a chrome style. Portal includes a variety of out-of-the-box Chrome styles.
Figure 28: Sample Chrome Style

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

Section I: Portal Site Development

65

Developing Styles and Style Types

Template Header Variables for Chrome Styles

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

Variable Name dragElementID

invokingStyleSupportsDrag

moduleBackgroundColor moduleBannerColor moduleFrameColor moduleTitleColor portletWindow

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

Controlling Navigation and Appearance with Styles

Developing Styles and Style Types

minimizeURL required view


See also: Vignette Portal Configuration Guide for discussion of Portal properties and the Portal configuration file

Primary JSP Files for Chrome Styles

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" />

A chrome styles primary JSP file must perform three functions:


Setting up the portlet window layout Displaying the portlet window title bar Rendering the portlet content

A description of each of these functions follows.


Setting Up the Portlet Window Layout. The chrome styles that ship with Portal use HTML tables to provide the style structure. Typically, the title and buttons are cells within one table row, and the content itself is a separate row. Fonts and colors can be controlled by CSS classes or hard-coded values. (See Chapter 5, Using Cascading Style Sheets, for information about Portals CSS classes.)

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.

Section I: Portal Site Development

67

Developing Styles and Style Types

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:

<vgn-portal:i18nValue stringID="<%= portletWindow.getPortletUID() %>" key="title" defaultValue="<%= portletWindow.getConfiguredTitle() %>"

(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

Controlling Navigation and Appearance with Styles

Developing Styles and Style Types

} %>

Note that portletWindow.getEditModeURL() links to the portlets edit window.


Rendering the Portlet Content. In its content-rendering section, a chrome primary JSP file uses four custom JSP tags whose purpose is specific to rendering a portlets content. These tags are listed and described in Table 7. Table 7: Portal Custom JSP Tags for Portlet Content Description Calls getContent() on the PortletWindowBean. This tag encloses the content-rendering logic. Executes when the getContent() method successfully returns the portlet content. This tag must be nested within a <vgnportal:renderPortlet> tag. Indicates where the portlet content is inserted within the page. This tag must be nested within a <vgn-portal:onRenderSuccess> tag. Executes when the getContent() method throws a PortletRenderException. This tag must be nested within a <vgnportal:renderPortlet> tag. In the body of this tag, the PortletRenderException thrown is made available through the scripting variable portletRenderException. The name and error parameters provided by the exception can be used to look up an appropriate error message in the current styles resource bundle.

Tag Name <vgn-portal:renderPortlet>

<vgn-portal:onRenderSuccess>

<vgn-portal:insertPortletContent/>

<vgn-portal:onRenderFailure>

These four tags are used together as follows:


<vgn-portal:renderPortlet> <vgn-portal:onRenderSuccess> ... Optional HTML/JSP ... <vgn-portal:insertPortletContent /> ... Optional HTML/JSP ... </vgn-portal:onRenderSuccess> <vgn-portal:onRenderFailure> ... Optional HTML/JSP ... <vgn-portal:i18nValue stringID="<%= i18nID %>" key="<%= portletRenderException.getName() %>"

Section I: Portal Site Development

69

Developing Styles and Style Types

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

Controlling Navigation and Appearance with Styles

Developing Styles and Style Types

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

Displaying Custom Properties in a Chrome Style

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.

Footer Style Types and Styles


Portal ships with two Footer style types: one for a horizontal navigation style and the other for a vertical or split navigation style. The Footer style types define the area at the bottom of a Portal page, where the company logo, other branding, a copyright statement, or a legal disclaimer is typically displayed. Footers can also be used to include links or buttons for URLs. Figure 30 shows an example of a Vignette Footer style.
Figure 30: Sample Horizontal Footer Style

Section I: Portal Site Development

71

Deploying Styles and Style Types

Deploying Styles and Style Types


Once youve created a new style or style type, it can be deployed into one or more Vignette 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 archive and component descriptor for styles and style types. 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 style or style type.
See also: Chapter 8, Deploying Site Components, for more about the deployment system

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

Controlling Navigation and Appearance with Styles

Deploying Styles and Style Types

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"

Section I: Portal Site Development

73

Deploying Styles and Style Types

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

Controlling Navigation and Appearance with Styles

Deploying Styles and Style Types

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

CAR File Directory root

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

CAR File Directory root

component.xml (required) template header file (if applicable)

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

Uploading the CAR File into Portal


The CAR file for your style or style type 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.

Section I: Portal Site Development

75

Style Example: Adding Login Functionality to a Style

Style Example: Adding Login Functionality to a Style


Portal includes login controls in the login secondary page type. Suppose that you want to add login controls to a style so that a user can log in to a site without going to the Login secondary page. For example, Figure 31 shows user name, password, and login controls added to an account controls style.
Figure 31: Login Controls Added to an Account Controls Style

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

Import the following classes:


com.epicentric.authentication.Realm com.epicentric.common.website.RealmUtils

Get the realms that the user can be authenticated against. For example:

76

Controlling Navigation and Appearance with Styles

Style Example: Adding Login Functionality to a Style

Realm rlm = (Realm)RealmUtils.getLoginRealms().get(0); c

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

Section I: Portal Site Development

77

Style Example: Adding Login Functionality to a Style

"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

Controlling Navigation and Appearance with Styles

3
Summary: Audience: Topics: See also:

Controlling Page Structure with Grids


Describes the grids that ship with Vignette Portal and explains how to modify existing grids and create new ones JSP or Java developers responsible for customizing the end-user site

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

Section I: Portal Site Development

79

Grids Shipped with Portal

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

Two Examples of Grids


Header Site Controls Account Controls Horizontal Navigation

<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

Grids Shipped with Portal


Portal ships with a number of predefined grids. Table 10 describes each outof-the-box grid, including its title within the administration consoles and the

80

Controlling Page Structure with Grids

Grids Shipped with Portal

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)

Horizontal Vertical and Vertical

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

Vignette Linear Popup Page Vignette Linear System Page X X X

Horizontal Imports JavaScript functions for form handling

Section I: Portal Site Development

81

Grids Shipped with Portal

Table 10:

Summary of Vignette Grids (Continued) Site Account NavigaHeader Controls Controls tion

Grid Title Vignette Popup Page

Footer

Notes Like Vignette Linear Popup Page except also includes style for page background color

Vignette System Page Vignette User Setting Page

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

Controlling Page Structure with Grids

Modifying the Look and Feel of Existing Grids

Figure 33:

Contemporary Grid and Styles


Page Controls

See also:

Chapter 4, Controlling Functionality with Secondary Pages, for a discussion of secondary page types

Modifying the Look and Feel of Existing Grids


You can customize the physical appearance of an out-of-the-box grid simply by editing its primary JSP file. This process does not require Java coding, component deployment, or a Portal application restart.
To modify the look and feel of an existing grid: 1 2 3

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.

Section I: Portal Site Development

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

Controlling Page Structure with Grids

Custom JSP Tags Used in Grids

Custom JSP Tags Used in Grids


Several Vignette Portal custom JSP tags are specific to grids. All grids get the secondary page output by using the <vgnportal:includePageContent/> tag. Most grids also include the <vgnportal:includeStyle/>,<vgn-portal:styleBlock/>, and <vgnportal:pageContentTitle/> tags; the exceptions are the content-only and popup grids. Any grid that has one or more navigation regions includes a <vgn-portal:includeNavigation/> tag for each region. Table 11 lists and describes the custom tags required or commonly used in grids.
Table 11: Tag <vgn-portal:defineObjects/> Custom JSP Tags for Grids Description Defines the LOG and portalContext implicit objects; included in JSP files for all Portal components. (See Chapter 7, Using the Site Development APIs, for a discussion of the JSP implicit objects used by Portal.) Includes the current style for the specified navigation style type. For a split navigation, isSecondary specifies whether this style type is the primary or the secondary navigation. Example: <vgn-portal:includeNavigation friendlyID="navigation-vertical" isSecondary=<%= true %>/> <vgn-portal:includePageContent/> <vgn-portal:includeStyle/> Includes the secondary page in the page content area. Includes the current style for the specified style type. Example: <vgn-portal:includeStyle friendlyID="account_controls"/> <vgn-portal:pageContentTitle/> Displays the title of the secondary page or menu item node, wrapping it within opening and closing HTML <title> tags. Includes CSS styles that are aware of the current theme, fonts, and colors.

<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

Section I: Portal Site Development

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

Controlling Page Structure with Grids

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

Section I: Portal Site Development

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

Uploading the CAR File into Portal


The CAR file for your grid can be uploaded using either of these methods:
Import the CAR file from the Portal server console (Tools >> Import

Components).
Place the CAR file in the PortalInstallDir/deployment/upload

directory, then restart the Portal web application.

Grid Example
This example is for a grid that includes the following style types:

header site controls horizontal navigation vertical navigation footer

The structure of this example is shown in Figure 34.

88

Controlling Page Structure with Grids

Grid Example

Figure 34:
Header

Grid Structure for the Example

Site Controls Horizontal Navigation

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

Section I: Portal Site Development

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

Controlling Page Structure with Grids

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>

Section I: Portal Site Development

91

Grid Example

92

Controlling Page Structure with Grids

4
Summary: Audience: Topics: See also:

Controlling Functionality with Secondary Pages


Describes the role of secondary pages within Vignette Portal and explains how to customize them JSP or Java developers responsible for customizing the Portal end-user site

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

Introduction to Secondary Pages


A secondary page defines the functionality of each Portal page. Every request is for exactly one secondary page, and that secondary page corresponds to the functionality of the request, such as login, user account management, or portlet display. Figure 35 and Figure 36 show examples of two different secondary pages. Figure 35 is a portlet page (a page displaying portlets), and Figure 36 is a page for rearranging portlets. These two figures are exactly the same except for the

Section I: Portal Site Development

93

Introduction to Secondary Pages

content/functionality portion. That portionthe region surrounded by dotted lines in the figuresis rendered by secondary pages.
Figure 35: Portlet Page Example

Secondary page displaying aggregated portlets

Figure 36:

Arrange Portlets Page Example

Secondary page for arranging portlets

94

Controlling Functionality with Secondary Pages

Modifying the Look and Feel of an Existing Secondary Page

Modifying the Look and Feel of an Existing Secondary Page


You can customize the physical appearance of an out-of-the-box secondary page simply by editing its primary JSP file. This process does not require Java coding, component deployment, or a Portal application restart.
To modify the look and feel of an existing secondary page: 1 2 3

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).

Section I: Portal Site Development

95

Secondary Page Types and Secondary Page Instances

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

Secondary Page Types and Secondary Page Instances


A secondary page type is an abstract component that defines a specific kind of functionality, such as user login. A secondary page (also known as a secondary page instance) is a component that fully implements the functionality of its given type, in the same way that a style implements its style type. For example, the following two figures show different secondary pages (instances) of the Login secondary page type. Figure 37 is the out-of-the box login page. Figure 38 is a custom login page that has a "Corporate PIN" field.
Figure 37: Standard Login Page

Default login secondary page instance

96

Controlling Functionality with Secondary Pages

Secondary Page Types and Secondary Page Instances

Figure 38:

Custom Login Page

Username: Password: Corporate PIN:

Custom login secondary page instance

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.

Secondary Page Rendering


Secondary page instances contain a JSP, called the primary JSP, which handles the rendering of the secondary page. The primary JSP can include other JSPs contained within the secondary page. Secondary page types do not contain JSPs.

Display Requests and Process Requests


The Portal framework handles two categories of requests:
Display requests, which render a page of markup (HTML) Process requests, which execute processing logic contained in secondary

pages and typically redirect to a display request


See also: Chapter 1, Vignette Portal Web Site Overview, for a discussion of display and process requests

Section I: Portal Site Development

97

Actions: Where Secondary Pages Do Processing

Actions: Where Secondary Pages Do Processing


Both secondary page types and secondary page instances can contain Java classes called actions, which perform processing. There are two types of actions:
Pre-Display Actions are invoked on a display request. These actions do

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

Controlling Functionality with Secondary Pages

Actions: Where Secondary Pages Do Processing

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.

Section I: Portal Site Development

99

Actions: Where Secondary Pages Do Processing

Actions on Secondary Page Instances


A secondary page instance can define its own list of pre-display and process actions, instead of using the list defined on its secondary page type. Usually, an instance can use most (if not all) of the processing logic of its secondary page type. Two different mechanisms enable a secondary page instance to modify only a bit of processing while leaving the rest of the logic in the secondary page type: direct reuse of actions and Java inheritance.
Direct Reuse of Actions

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

My Login Secondary Page Pre-Display Actions CustomLoginFormAction Reference Primary JSP

This Action lives in secondary page type

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

Controlling Functionality with Secondary Pages

Developing a Secondary Page Instance

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

My Login Secondary Page Pre-Display Actions MySetUpLoginFormAction Primary JSP

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.

Developing a Secondary Page Instance


If you need to add your own processing to a particular secondary page type, you can create a new instance of that type. That instance will consist of a new primary JSP file and any number of custom actions that provide the processing logic your organization requires.

Section I: Portal Site Development

101

Developing a Secondary Page Instance

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

Step 1: Plan Your Work


Before you can create an instance of a secondary page type, you need to familiarize yourself with the existing functionality so that you can plan your customizations. To ascertain what actions are invoked and their invocation order, open the component descriptor (component.xml file) for the secondary page type or one of its existing instances. The component descriptor is one of the files in the component archive (CAR file), which you can obtain by using a Portal administration console to export the secondary page type or instance. If you export a secondary page instance, you can also study its primary JSP file. (Before you can export one of the components that ship with Portal, you first must duplicate it.)

102

Controlling Functionality with Secondary Pages

Developing a Secondary Page Instance

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

Step 2: Create Any Pre-Display Actions


A pre-display action is a subclass of com.vignette.portal .website.enduser.components.BaseAction. Every action must extend this class, which has one abstract method: execute(). The Portal framework sequentially calls execute() on each pre-display action in the list for the requested secondary page. When the last execute() method has completed processing, the framework calls the secondary pages primary JSP, unless an execute() method performed a redirect or forward. Typically, a pre-display action checks for various conditions and includes redirection or other logic for handling each condition. IMPORTANT: Do not extend any of the Vignette Portal actions. These actions are subject to change in future releases of the product.
Storing a JavaBean in the Request

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;

Section I: Portal Site Development

103

Developing a Secondary Page Instance

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);

Redirecting Using the Portal Framework

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

Controlling Functionality with Secondary Pages

Developing a Secondary Page Instance

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 returned object is of type


com.vignette.portal.website.enduser.PortalURI.
About the PortalURI Object.

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

Portal URL generation logic):


protocol://domain/portal/site/mysite/template.LOGIN

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.

secondary page and to pass a localized error message. For example:


Site site = portalContext.getCurrentSite(); if (site == null) {

Section I: Portal Site Development

105

Developing a Secondary Page Instance

// 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

Controlling Functionality with Secondary Pages

Developing a Secondary Page Instance

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);

Returning Null within a Pre-Display Action

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");

Section I: Portal Site Development

107

Developing a Secondary Page Instance

Overriding the Default Content Type

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

Controlling Functionality with Secondary Pages

Developing a Secondary Page Instance

// 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; } }

Step 3: Create Any Process Actions


Process actions associated with a specific secondary page are executed by the framework upon direct invocation through a process URL. Process actions should be used for core secondary page logic as well as for redirection. Like a pre-display action, a process action extends
com.vignette.portal.website.enduser.components .BaseAction; and its execute() method can redirect using either a PortalURI object or response.sendRedirect(), can use forward calls,

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

Section I: Portal Site Development

109

Developing a Secondary Page Instance

Passing Data from a Process Action to a Display

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

Controlling Functionality with Secondary Pages

Developing a Secondary Page Instance

// 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); } }

Step 4: Create the Primary JSP File


Every secondary page instance needs a file that is identified as the primary JSP file. This file performs the actual rendering of a secondary page. Typically, it includes an HTML form and other markup, as well as logic for using its JavaBean, retrieving its secondary page, and generating a process request.

Section I: Portal Site Development

111

Developing a Secondary Page Instance

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

Retrieving the Secondary Page Object

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); %>

(EndUserUtils and I18nUtils are utility classes within com.epicentric.common.website.)


See also: Chapter 6, Internationalizing and Localizing Site Components, for discussion of I18N APIs

112

Controlling Functionality with Secondary Pages

Developing a Secondary Page Instance

Generating a Process Request

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

in the friendly ID of a different secondary page type.


JSP File Example

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>

Section I: Portal Site Development

113

Developing a Secondary Page Instance

<%-- 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(); %> &nbsp;&nbsp;</td></tr> <%-- Display form field. --%> <tr><td> <input class="epi-input" type="password" size="13" style="width: 150px" value="" name="password" id="password" /> &nbsp;&nbsp;</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

Controlling Functionality with Secondary Pages

Developing a Secondary Page Type

Developing a Secondary Page Type


The secondary page types shipped with Portal support most of the categories of functionality that a portal requires: login, logout, user account maintenance, page display, layout of portlets on a page, error and other message display, etc. You therefore might not need to develop any new secondary page types. If, however, you do want to develop a secondary page type to support additional functionalityfor example, to display your privacy policy or provide access to legal statementsthe process is similar to that for developing a secondary page instance. Here are guidelines for developing secondary page types:
Define as many actions as possible on the type. In most cases, all pre-

display and process actions can be defined on the type.


Create a JavaBean for the type. Create one or more secondary page instances for your new type. Generally,

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.

Creating Custom Portlet Page Layouts


The Page Display secondary page type is responsible for the layout of portlets on an end-user page. Typically, such a page includes the main views of multiple portlets. An instance of the Page Display secondary page renders a particular portlet page for a particular end user according to the specifications that administrators supply through a graphical user interface. This UI consists of two administration console pages: Layout and Portlet Placement. The Layout page enables Portal administrators to define either a column or row orientation (see Figure 43). Each column or row contains one or more panels, and each panel contains one or more portlets. Administrators can specify the width of panels; in a column orientation, they can also specify the width of the columns.

Section I: Portal Site Development

115

Creating Custom Portlet Page Layouts

Figure 43:

Layout Page, Portal Administration Consoles

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

Controlling Functionality with Secondary Pages

Creating Custom Portlet Page Layouts

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.

Page Display Files


The Page Display secondary pages use a deep JSP inclusion model to isolate the various features that a portlet page can support: DHTML, column or row orientation, portlets with or without chrome, etc. One of the out-of-the-box Page Display secondary pages is for a DHTML-enabled browser, and the other is for a non-DHTML browser. Figure 45 illustrates the inclusion model for the DHTML Page Display secondary page; Table 12 describes each file.

Section I: Portal Site Development

117

Creating Custom Portlet Page Layouts

Figure 45:

DHTML Page Display JSP Inclusion Model

displaypage.jsp

DHTML?

Include displaypage_dhtml.inc

Include displaypage_dhtml_ module_layout.inc

N Include displaypage_static.inc

Column Y Orientation?

Include displaypage_static_ column_oriented.inc

N Include displaypage_static_ row_oriented.inc Include displaypage_static_ common.inc Include display_portlet.inc

Chromeless Portlet?

Include chromeless_portlet.inc

N Insert chrome style

118

Controlling Functionality with Secondary Pages

Creating Custom Portlet Page Layouts

Table 12: Filename

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

Section I: Portal Site Development

119

Creating Custom Portlet Page Layouts

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

Page Display APIs


Most of the logic for rendering portlets within a page is in the displaypage_dhtml_module_layout.inc file for DHTML Page Display, and in the following files for the non-DHTML secondary page:
displaypage_static_column_oriented.inc displaypage_static_row_oriented.inc displaypage_static_common.inc

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

Controlling Functionality with Secondary Pages

Automating the Validation and Population of HTML Forms

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

Automating the Validation and Population of HTML Forms


Secondary page developers can validate and populate HTML forms in a fashion similar to that provided by the Apache Struts validator framework.

Section I: Portal Site Development

121

Automating the Validation and Population of HTML Forms

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

Step 1: Develop a FormBean


An HTML form is represented by a JavaBean-like class called a FormBean, which contains logic for HTML form field population and validation. Each end-user HTML form using the Portal validation framework has its own subclass of com.vignette.portal.website.enduser .components.EndUserFormBean. This class superclass (com.vignette.portal.website.form.FormBean) has two abstract methods that must be overridden: getFormName() and getPotentialErrors().
getFormName() Method

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

Controlling Functionality with Secondary Pages

Automating the Validation and Population of HTML Forms

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; }

Section I: Portal Site Development

123

Automating the Validation and Population of HTML Forms

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

Controlling Functionality with Secondary Pages

Automating the Validation and Population of HTML Forms

"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; } }

Step 2: Set up the Validation Rules


The Portal validation framework gets all of the information it needs about each form from an XML file. This file identifies the validation rules to be run on each field of each form. The framework provides validation rules for the most common types of data. If your form has specialized validation requirements, you can create custom validation rules and specify their classnames and other identifying information in the XML file.
Creating the XML File

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>

Section I: Portal Site Development

125

Automating the Validation and Population of HTML Forms

<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

Controlling Functionality with Secondary Pages

Automating the Validation and Population of HTML Forms

<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

Section I: Portal Site Development

127

Automating the Validation and Population of HTML Forms

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

the implementation for this validation method.


methodRequired. Name of the Java method to execute to perform the

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

Controlling Functionality with Secondary Pages

Automating the Validation and Population of HTML Forms

Table 13: Rule

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.

maxlength minlength required requiredif

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

Section I: Portal Site Development

129

Automating the Validation and Population of HTML Forms

Table 13: Rule

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

Strict date pattern to which the date must conform

email mask

n/a mask

n/a Perl expression to which this field must conform

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

Controlling Functionality with Secondary Pages

Automating the Validation and Population of HTML Forms

<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>

Section I: Portal Site Development

131

Automating the Validation and Population of HTML Forms

Creating Custom Validation Rules

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; } }

As shown above, a validation method should call


ValidationTestSuite.putErrorInList() whenever a validation test

fails. The reference to this method within validation.xml might look like this:

132

Controlling Functionality with Secondary Pages

Automating the Validation and Population of HTML Forms

<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.

Note that the sample validation method and the

methodParams attribute of the sample<validator> element above include

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

Section I: Portal Site Development

133

Automating the Validation and Population of HTML Forms

java.util.Lista list of errors that have been encountered during

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

Controlling Functionality with Secondary Pages

Automating the Validation and Population of HTML Forms

(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.

Step 3: Add Validation Code to the Primary JSP


Instantiate the FormBean in a secondary pages primary JSP file, like this:
<jsp:useBean id="add_form" scope="session" type="com.companyname.portal.mycomponents.SampleFormBean" />

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>

Step 4: Develop the Action Processing


In your pre-display action, retrieve the FormBean:
SampleFormBean formBean = (SampleFormBean)session.getAt tribute(ProcessSampleAction.FORM_KEY); if (formBean == null) { formBean = new SampleFormBean(); session.setAttribute(ProcessSampleAction.FORM_KEY, formBean); }

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

Section I: Portal Site Development

135

Secondary Page Deployment

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.

Secondary Page Deployment


The deployment process is very similar for secondary page instances and secondary page types. This section first explains how to deploy a secondary

136

Controlling Functionality with Secondary Pages

Secondary Page Deployment

page instance and then describes how the deployment process is different for secondary page types.

Deploying a Secondary Page Instance


Once youve created a new secondary page instance, it can be deployed into one or more Vignette 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 archive and component descriptor for secondary page instances. NOTE: The export mechanism of the administration consoles creates the
component.xml, validation.xml (if any), and CAR files for an

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"

Section I: Portal Site Development

137

Secondary Page Deployment

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

Controlling Functionality with Secondary Pages

Secondary Page Deployment

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"

Section I: Portal Site Development

139

Secondary Page Deployment

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

Controlling Functionality with Secondary Pages

Secondary Page Deployment

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

CAR File Directory root

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)

Section I: Portal Site Development

141

Secondary Page Deployment

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.)

CAR File Directory /WEB-INF/i18n

/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

Uploading the CAR File into Portal

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

Controlling Functionality with Secondary Pages

Secondary Page Deployment

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

Deploying a Secondary Page Type


Except for a few details, deploying a new secondary page type is the same as deploying a new secondary page instance. The differences are as follows:
The CAR file for a secondary page type does not include any JSP files, any images, or a validation.xml file. The component.xml file for a secondary page type has a componenttype value of "Secondary Page Types" and contains a <templateinfo> element instead of a <style-info> element. The <actions>

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">

Section I: Portal Site Development

143

Secondary Page Deployment

<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

Controlling Functionality with Secondary Pages

Secondary Page Deployment

<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>

Section I: Portal Site Development

145

Secondary Page Deployment

<action id="3" type="PROCESS"> <class>com.vignette.portal.website.enduser.components .mypage.movecontent.ProcessMyPagesMoveAction </class> </action> </actions>

Sharing Code between Secondary Page Types

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

Controlling Functionality with Secondary Pages

Secondary Page Deployment

</template-info> </epideploy:detail> </epideploy:component>

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.

Section I: Portal Site Development

147

Secondary Page Deployment

148

Controlling Functionality with Secondary Pages

5
Summary: Audience: Topics:

Using Cascading Style Sheets


Explains when and how to use CSS to customize Vignette Portal end-user pages HTML, JSP, or Java developers responsible for the look and feel of Vignette Portal sites

Customizing the Look and Feel of Your Portal (below) Working with the Vignette Portal CSS on page 151 Customizing the CSS on page 153

Customizing the Look and Feel of Your Portal


You can customize the look and feel of your end-user Portal sites in several ways. Some do not require development; for example, administrators can use the administration consoles to change the theme for a site, or end users can add, remove, or move content on their pages. Other customizations require development; for example, developers can create new styles, style types, grids, and secondary pages. Cascading style sheets (CSS) provide yet another way to modify the look and feel for end users: with the Vignette Portal CSS system, you can dynamically change the look and feel of styles and secondary pages that use the CSS classes provided with Portal. You can also create your own CSS classes to further customize the end-user appearance. Portal generates a cascading style sheet that can control the look and feel of all HTML that Portal pages produce. This style sheet controls the appearance of body text, messages, titles, forms, buttons, menus, data tables, and more. It is dynamic: its fonts, colors, and other values change to reflect Portal administrator and end-user settings. HTML that uses the Vignette Portal CSS automatically changes look and feel based on actions by the administrator and end user.

Section I: Portal Site Development

149

Customizing the Look and Feel of Your Portal

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

and end users.


Enables components on a site to respond to that particular sites look and

feel.

Vignette Portal CSS, Themes, and End-User Settings


The Vignette Portal style sheet responds to themes and end-user settings. Its font and color values are determined by the following administrator and enduser settings:
Server level.

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.

CSS, the Java Portlet Standard, and WSRP


The Java Standard Portlet and Web Services for Remote Portlets (WSRP) specifications share a standard set of CSS classes. The Vignette Portal style sheet includes these classes. When the font and color values of the Portalspecific CSS change, the values of the standards-based classes change as well. When writing a standards-based portlet, you should make use of the standards-based CSS classes. However, the standards-based classes do not provide many of the features of the Portal-specific classes, such as control of hierarchical trees of data. When developing structures that the standardsbased CSS doesnt control, the best practice is to use Portal-specific classes.

150

Using Cascading Style Sheets

Working with the Vignette Portal CSS

Working with the Vignette Portal CSS


This section describes how an HTML developer should code using the Portal style sheet.

HTML Elements Requiring No CSS


The Portal style sheet applies default formatting to the following HTML tags:

<body> <p> <pre> <a> <hr> <li>

the table elements <th>, <tr>, and <td>

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>.

Using Portal CSS Classes


Vignette Portal provides a wide range of CSS classes that you can use to control the appearance of HTML pages. Here are some situations in which Portal CSS classes are specifically designed to be used:
Text:

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:

Section I: Portal Site Development

151

Working with the Vignette Portal CSS

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

Data trees: See also:

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.

How CSS Values Map to Portal Themes and End-User Settings


Vignette Portal themes are administrator-controlled components that have properties. For example, one theme property is font.body.face. From a Portal administration console, an administrator might set the value of that property for a particular theme to (for example) Helvetica. Each CSS property is controlled by a Portal theme property. For example, the CSS property font-family is associated with the Portal theme property font.body.face:
.epi-fontLg { font-family: //equal to Portal theme property font.body.face font-size: large; }

If font.body.face is set to Helvetica, the Portal style sheet would contain this:
.epi-fontLg { font-family: Helvetica font-size: large; }

Here is an example of HTML that uses the above CSS class:


<p class="epi-fontLg">Hello, world.</p>

This would render "Hello, world" in Helvetica (or whatever font was set in the administrator-controlled theme).

152

Using Cascading Style Sheets

Customizing the CSS

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.

Customizing the CSS


You might want to develop custom CSS styles to accomplish any of these objectives:
Create CSS classes that are specific to a single HTML page. Often, pages

with DHTML require such page-specific CSS.


Make all Portal CSS values come from an external system, such as a

corporate style repository.


Override Portal CSS for just a portion of the HTML page, to make that

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.

Overriding the Portal Style Sheet


If you want to provide your own values for Portal CSS, you must override the Portal style sheet. You cannot modify the Portal style sheet itself; instead, include your custom style sheet in the HTML after the Portal style sheet. This has the effect of overriding any Portal CSS classes and selectors of the same name. Each Portal grid includes the Portal style sheet between the HTML <head> and </head> tags. Grids use a custom JSP tag called <vgn-portal:styleBlock/> to generate the CSS link. Any style sheet included after that point, whether a link or an inline style block, will override Portal style sheet elements. Any style sheet included by a portlet, style, or secondary page will override the Portal style sheet.

Section I: Portal Site Development

153

Customizing the CSS

Style Sheets That Respond to Administrator and End-User Settings


You can create a custom style sheet that responds, like the Portal style sheet, to the administrator-set theme and the end users color and font preferences. For example, when creating CSS classes that are specific to a single HTML page, you might want the page-specific CSS to take its values from the theme and end user. To accomplish this type of customization, use the com.epicentric.template.Branding class. This class provides lookand-feel information for the current request. It allows the retrieval of font and color values based on the current theme, merged with the current end users font and color preferences. Heres an example JSP that sets some of Portals menu-related CSS. (This example generates the same values as the Portal style sheet; its up to you to customize the logic.)
<%@ page import="com.epicentric.template.Branding, com.epicentric.template.BrandingUtils, com.epicentric.common.website.HtmlUtils" %> <%@ taglib uri="vgn-tags" prefix="vgn-portal" %> <vgn-portal:defineObjects /> <% // declare variables to deal with branding Branding branding = BrandingUtils.getUserBranding(portalContext); int clientBrowser = HtmlUtils.sniffBrowser(request); String fontSize = BrandingUtils.remapSize(branding.getFontValue( "font .body.normal"), clientBrowser); String fontFamily = branding.getFontValue("font.body.face"); %> <%-- set font and cursor attributes for menu --%> .epi-horzMenu-border-baseLevel, .epi-horzMenu-border-subLevel, .epi-horzMenu-baseLevel, .epi-horzMenu-baseLevel-over, .epi-horzMenu-baseLevel-select, .epi-horzMenu-baseLevel-select-over, .epi-horzMenu-subLevel, .epi-horzMenu-subLevel-over, .epi-horzMenu-subLevel-select, .epi-horzMenu-subLevel-select-over{ overflow:hidden; cursor:pointer; cursor:hand; font-size:<%=fontSize%>; font-family:<%=fontFamily%>;

154

Using Cascading Style Sheets

Customizing the CSS

} See also: Chapter 7, Using the Site Development APIs, for more about Portal branding

Caching Custom Style Sheets


To improve performance, the users browser can cache custom style sheets that make use of the Branding object. To take advantage of Portals CSS caching, use the StyleUtils.createCSSStyleSheetLink() method to create the link to the custom JSP style sheet. This will ensure the client browser caches the style sheet and retrieves it again only under one of these conditions:
The theme is modified. The end user changes font or color preferences.

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%>">

Section I: Portal Site Development

155

Customizing the CSS

156

Using Cascading Style Sheets

6
Summary: Audience: Topics:

Internationalizing and Localizing Site Components


Describes Vignette Portals internationalization and localization features and explains how to use the Portal I18N property files, custom JSP tags, and Java utilities JSP or Java developers responsible for customizing the Vignette Portal end-user site

Vignette Portal, I18N, and L10N (below) Creating I18N Property Files on page 158 Accessing Localized Values in Component Code on page 159

Vignette Portal, I18N, and L10N


The Vignette Portal end-user site and administration consoles are fully internationalized (capable of handling multiple languages). The Portal I18N framework supports localization (the process of adapting software to a specific language or region) through the administration consoles as well as through standard Java resource bundles and property files. All Portal components ship with default property files that define keys and U. S. English values. The Portal I18N framework is patterned after Java resource bundles but also offers a number of enhancements. The framework supports per-request language selection, addition of new localizable objects, dynamic addition of new localizations, and key/value comments to aid translators. You can internationalize components that you develop for Vignette Portal by using custom JSP tags and other APIs specifically designed for that purpose. Translators can localize components by providing locale-specific property files or by entering translations directly through the Portal administration consoles.

Section I: Portal Site Development

157

Creating I18N Property Files

Portal Users and Language Preference


End-user sites as well as the administration consoles are localizable. Users can select their preferred language. Administrators can provide multiple translations per site, specify a sites default locale, and specify the systemwide default locale. A registered users language preference is stored the users account (user profile). For sites that allow guest access, a guest users language preference is stored in a cookie. If the current user has not specified a language preference, the sites default locale is used.

Precedence Algorithm for Locale Selection


When multiple resource bundles are available for a given site or site component, Portal determines which resource bundle to use based on the following precedence algorithm:
User-specific language + country variant User-specific language Site default language + country variant Site default language Server default language + country variant Server default language Absolute default (from the default property file) Default value specified in the code
See also: Vignette Application Portal Module Developers Guide for I18N and L10N information specific to PortalBean portlets

Creating I18N Property Files


When you create a new Portal style (see Chapter 2) or secondary page (see Chapter 4), you should create, at minimum, a default property file containing key/value pairs for every piece of display data. The name of the default property file must be componentID.properties, where componentID matches the value of the component-id attribute in the component descriptor (component.xml file, explained in Chapter 8) for your new style

158

Internationalizing and Localizing Site Components

Accessing Localized Values in Component Code

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

Accessing Localized Values in Component Code


Portal includes a number of custom JSP tags and Java APIs that support internationalization. The rest of this chapter discusses these tags and APIs.

Section I: Portal Site Development

159

Accessing Localized Values in Component Code

Custom JSP Tags


Using custom JSP tags for component internationalization requires that you declare the Portal tag library in primary JSP files or in template header files for styles:
<%@ taglib uri="vgn-tags" prefix="vgn-portal" %>

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

Inserting a Localized Value

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

Internationalizing and Localizing Site Components

Accessing Localized Values in Component Code

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>

This tag is explained next.


Controlling Placement of <span> Tags within a Localized Value

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:

Section I: Portal Site Development

161

Accessing Localized Values in Component Code

<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>

generates HTML similar to this:


<span lang="locale1"><a href="/someURL.html" alt="String1"> <span lang="locale2">String2</span></a></span>

Inserting Parameters within a Localized Value

The <vgn-portal:i18nParam/> tag can be used within opening <vgnportal:i18nValue> and closing </vgn-portal:i18nValue> tags to

162

Internationalizing and Localizing Site Components

Accessing Localized Values in Component Code

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>

Internationalizing Numbers and Dates

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"/>

Localizing and Formatting Values When the Context is not Known

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.

Section I: Portal Site Development

163

Accessing Localized Values in Component Code

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 %>"/>

I18N Format Java Package


The com.epicentric.i18n.format package supports internationalization in cases such as these:
The user context is not known. You need to localize a combination of dynamic and static data. You need to send an error or other string to a file based on one locale and

display a message based on the locale of the current request.


Formattable is the base interface for this package. It specifies format() methods for formatting output. Formattable objects can be used for the

following purposes:
Specifying a string and its locale Defining output styles (for example, a "caution" style, which might be

different for a desktop browser compared to a mobile device)


Formatting output based on locale and output style Creating a group of string-locale combinations Getting and formatting a resource bundle

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

Internationalizing and Localizing Site Components

Accessing Localized Values in Component Code

Here is an example of using a FormattableBundle to provide a default message and locale:


FormattableBundle bundle = new FormattableBundle(uid, key); bundle.setDefaultPattern("The default message.", Locale.US);

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);

Section I: Portal Site Development

165

Accessing Localized Values in Component Code

Java Utility Classes


The Vignette Portal API includes a number of utilities for internationalization and localization.
I18nUtils

The primary I18N and L10N utility class is


com.epicentric.common.website.I18nUtils, which includes

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

Like java.text.MessageFormat, the


com.epicentric.website.SafeMessageFormat class enables you to

produce concatenated messages in a language-neutral way. In addition,


SafeMessageFormat provides graceful handling of error conditions. For

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

Internationalizing and Localizing Site Components

Accessing Localized Values in Component Code

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",

Section I: Portal Site Development

167

Accessing Localized Values in Component Code

"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

Internationalizing and Localizing Site Components

7
Summary: Audience: Topics: See also:

Using the Site Development APIs


Describes how to perform common Portal site development tasks JSP or Java developers responsible for customizing the Vignette Portal end-user site

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

Working with the Request and Response


The Vignette Portal framework includes two interfaces that represent requests and responses between the client and the portal: com.vignette.portal.website.enduser.PortalRequest and com.vignette.portal.website.enduser.PortalResponse, respectively. You can access PortalRequest and PortalResponse through another interface in the same package: com.vignette.portal.website.enduser.PortalContext. Every

Section I: Portal Site Development

169

Working with the Session

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 can then retrieve a specific request parameter as follows:


String myParam = portalRequest.getParameter(MY_PARAM_NAME);

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

Working with the Session


The Portal framework includes two classes for working with the HTTP session: SessionInfo and SessionUtils.

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

Using the Site Development APIs

Working with the Session

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:

Section I: Portal Site Development

171

Generating URIs

ErrorMessage em = new ErrorMessage(ErrorMessage.SYSTEM_ERROR, err); SessionUtils.setNamespacedAttribute(session, ParameterConstants.ERROR_MESSAGE, null, em);

(ErrorMessage is a class in the com.epicentric.common.website package.)

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

Creating Display URIs


The Vignette account controls style creates a PortalURI for the login button as follows:
String loginURL = portalContext.createDisplayURI(ParameterConstants. PAGE_LOGIN).toString();

172

Using the Site Development APIs

Generating URIs

This PortalURI uses a static field on


com.epicentric.common.website.ParameterConstants to point to the login page. The login button uses the PortalURI as follows:
<a href="<%=loginURL%>" class="epi-link1"><vgn-portal:i18nValue stringID="<%=i18nID%>" key="login" defaultValue="Login" /></a>

(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

Creating Process URIs


The Vignette account controls style uses a different PortalContext method and ParameterConstants field to create a PortalURI for the logout button:
String logoutURL = portalContext.createProcessURI(ParameterConstants. PAGE_LOGOUT).toString();

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

Invoking a Specific Page by Creating a Page URI


Typically, Portal invokes the page that is specified through the frameworks request processing. If instead you want to invoke a particular page, you can use the createPageURI(String templateFriendlyID, String pageID) method on PortalContext to force the specified page to render.

Section I: Portal Site Development

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");

The resulting URL will be of the following form:


/portal_app_context/site/site_name/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

Adding Parameters to a URI


You can use the addParameter(String name, String value) method on PortalURI to add parameters to that PortalURI object. For example:
PortalURI newsURL = portalContext.createPageURI(PAGE, "nationalnews"); newsURL.addParameter("newsid", "123");

The resulting URL would have the following form:


/portal_app_context/site/site_name/page.nationalnews /?newsid=123

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

Using the Site Development APIs

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

Out-of-the-Box Components that Render Portlets


As shipped, Portal includes the portlet-rendering tags in the following components:
Chrome styles, which define the appearance of the portlet window

(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

state (designed to display an HTML frameset)


The Default Solo secondary page, which renders a portlets SOLO window

state (designed for use in a pop-up window)

Section I: Portal Site Development

175

Displaying Portlets

The Single Portlet secondary page, which enables a portlet to be rendered

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.

Specifying the Portlet to be Rendered


You can use the <vgn-portal:renderPortlet> tag to embed a specific portlet into a style or secondary page. You do so by including the portletFriendlyID attribute of the tagfor example:
<vgn-portal:renderPortlet portletFriendlyID="bookmark"> <!-- success and failure tags go here --> </vgn-portal:renderPortlet>

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

Embedding Portlets in Styles

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

Using the Site Development APIs

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

Embedding Portlets in Secondary Pages

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

Section I: Portal Site Development

177

AJAX-Enabling Portal Components

Required Deployment Steps

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

with the component that includes the reference.


When a Portal administrator imports a component that refers to a portlet,

the portlet must be imported as a separate step.


When a Portal administrator shares a component that refers to a portlet, the

portlet must be shared as a separate step.


See also:

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

AJAX-Enabling Portal Components


Vignette Portal provides an open framework for AJAX-style interactions. This framework supports AJAX widget toolkits while also providing a Vignette Portal AJAX library for those situations where widgets are not ideal for meeting your functional requirements.

Portal and Third-Party AJAX Toolkits


Portal supports the use of third-party AJAX toolkit products or home-grown solutions. Portal ships with a navigation style developed using a customized tree widget from the Dojo toolkit. This is an example of a use case where custom widgets provided an appropriate solution. NOTE: If a toolkit requires modifying the Portal web.xml, such modifications must be reapplied upon Portal upgrade.
See also: Chapter 2, Controlling Navigation and Appearance with Styles, for more about Portals out-of-the-box AJAX-enabled navigation style

178

Using the Site Development APIs

AJAX-Enabling Portal Components

Vignette Portal AJAX Library


The Vignette Portal AJAX Library provides a consistent programming paradigm to perform AJAX-style updates throughout the Portal product, including styles, secondary pages, Java standard portlets, and PortalBean portlets. This library is a JavaScript API that communicates with Portal. The library can be made available to the Portal page and therefore to all components that execute within that page. It provides session management and handles error conditions on behalf of AJAX-enabled Portal components. It also provides request aggregation for forms, communicating with the Portal server and registering a callback in the browser. The library supports partial page updates in response to any JavaScript event. As a result, any keyboard or mouse action targeted to a browser can initiate an AJAX-style update. For example, an onMouseOver event over an employee name could present contact or other information about the employee; or an onKeyUp event within a search input textbox could display suggestions for alternative search terms. An AJAX-enabled component is executed without including the surrounding Portal page, so that the AJAX response is aggregated into the existing Portal page. If an HTTP session has been established, the AJAX Library enables its use; otherwise, it redirects the user to the login or guest page. The AJAX Library supports sending of URLs, standard FORMs, and multipart FORMs to the Portal server. You manipulate the HTML DOM to reflect changes in browser markup by coding callback functions. The library performs some basic error handling before invoking your callback. The Portal AJAX functions reside in PortalInstallDir/portal/jslib/vapajaxlibrary.js. To prevent conflicts with other libraries that your code might use, the library is namespaced using a dotted notation (VignettePortal.AJAXClient). The following sections discuss and illustrate the use of the Portal AJAX Library with styles and secondary pages.

Section I: Portal Site Development

179

AJAX-Enabling Portal Components

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

Using the Library with Styles and Secondary Pages

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

Using the Site Development APIs

AJAX-Enabling Portal Components

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

a secondary page that does require security


If a secondary page requires security, but it creates an AJAX link to another

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.

Section I: Portal Site Development

181

AJAX-Enabling Portal Components

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();

<%

%> <form name="main" id="main" action="<%=formProcessURIAsString%>" onSubmit="new VignettePortal.AJAXClient().sendForm(this,callback Function);return false"

182

Using the Site Development APIs

AJAX-Enabling Portal Components

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,

Section I: Portal Site Development

183

AJAX-Enabling Portal Components

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:

If an exception is thrown in an action class (whether pre-display or process)

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

Using the Site Development APIs

Writing to the Vignette Portal Log

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

Writing to the Vignette Portal Log


Portal includes a logging framework that enables you to log five message levels based on severity and purpose. The Portal log is configurable through the Portal configuration file (PortalInstallDir/config/properties.txt) and the log4j.properties file. The logging API has method names that correspond to the message levels: debug, info, warning, error, and fatal. (For details about the Portal configuration file, see Vignette Portal Configuration Guide.) JSPs have access to the Portal log through an implicit variable named LOG. You can create a log entry simply by using the appropriate method and passing it the messagefor example:
LOG.info("connecting to resource");

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:

Section I: Portal Site Development

185

Handling Errors

LogWrapper(Class originatingClass) LogWrapper(Class originatingClass, String subsystem)

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); }

(The log levels are fields on


com.vignette.portal.log.LogConfiguration.)

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

Using the Site Development APIs

Using UIDs and Friendly IDs

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

Using UIDs and Friendly IDs


Every component within the Vignette Portal web application must have a unique ID (UID), which is a 128-bit number in hexadecimal notation. Portal generates UIDs as components are installed or imported. The primary use of

Section I: Portal Site Development

187

Using UIDs and Friendly IDs

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(); }

Friendly IDs must be unique for a given


com.epicentric.template.Template object. Therefore, each style type and each secondary page type (which are both Template objects) must have

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

Using the Site Development APIs

Working with Portal Branding

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

Working with Portal Branding


Styles, themes (which are collections of styles providing a unified look and feel), and grids together define the branding of a portal. Depending upon the Vignette Portal configuration, branding can be controlled at the server, site, portlet page, and (in the case of fonts and colors) individual user levels. The com.epicentric.template.Branding object encapsulates this lookand-feel information for the current request. The BrandingUtils class (also in com.epicentric.template) enables you to retrieve the Branding object for the current request or for the current user:
Branding branding = BrandingUtils.getRequestBranding(portalContext); Branding branding = BrandingUtils.getUserBranding(portalContext);

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");

Section I: Portal Site Development

189

Retrieving System Properties

String rolloverBGColor = branding.getColorValue("bgColor.bg1"); String pageBGColor = branding.getColorValue("bgColor.page");

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

Retrieving System Properties


You can retrieve Vignette Portal properties using methods on the com.vignette.portal.config.PortalConfigUtils class. Here is a usage example (where HTMLUtils is a class in com.epicentric.common.website):
String imagesPath = PortalConfigUtils.getProperty(HtmlUtils.END_USER _IMAGE_PATH).trim();

NOTE: The com.epicentric.common.Props class has been deprecated. Use the pattern shown above instead of it to retrieve Portal properties.

Retrieving the Portal Installation Location


You can get the path to the Vignette Portal installation by using the getInstallDir() method on com.vignette.portal.config.PortalEnvironment. NOTE: The com.epicentric.common.Installation class, which was previously used to retrieve the installation path, has been deprecated.

190

Using the Site Development APIs

Vignette Portal Utility Classes

Vignette Portal Utility Classes


This chapter has introduced you to a number of utility classes, such as SessionUtils, EndUserUtils, and BrandingUtils. Most Portal utility classes are in the packages listed and described in Table 15.
Table 15: Package Vignette Portal Utility Packages Description Web, string, array, date, reflection, and other utilities Utilities for Portal end-user site development More utilities for Portal administrative and end-user sites A few web and Portalspecific utilities (most deprecated; replaced by

com.vignette.portal.util com.vignette.portal.website.enduser. utils


com.epicentric.common.website

com.epicentric.common

com.vignette.port al.util classes)

Vignette Portal Constants and JSP Variables


The com.epicentric.common.website.ParameterConstants class defines static fields that the Portal framework uses. Many of these fields are passed in the session and in query strings. For example, LOCALE stores the current locale, ERROR_MESSAGE stores any error strings for the current session, and PAGE_LOGIN identifies the login secondary page. The Portal framework also defines two variables for implicit JSP objects: LOG, representing the Portal log, and portalContext, representing the com.vignette.portal.website.enduser.PortalContext object. Both of these objects are request scoped and are made available to all JSP pages through the <vgn-portal:defineObjects/> custom tag.
See also:

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

Section I: Portal Site Development

191

Vignette Portal Constants and JSP Variables

192

Using the Site Development APIs

8
Summary: Audience: Topics:

Deploying Site Components


Describes the deployment process for styles, style types, secondary pages, secondary page types, and grids JSP or Java developers responsible for deploying Vignette Portal components

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

Vignette Portal Component Architecture


Vignette Portal consists of a number of different kinds of componentsfor example, styles, grids, secondary pages, and PortalBeans. Each component that is part of the Portal web application contains various resources. Depending upon the type of component, these resources can include Java classes, JSP files, XML files, images, .properties files for localization, CSS files, and more. In addition, every Portal component can be described in a component descriptor (component.xml file). This descriptor identifies the type of component and provides other information about it that is required by the Portal deployment system. Figure 46 shows the physical architecture for several kinds of components.

Section I: Portal Site Development

193

Vignette Portal Component Architecture

Figure 46:

Vignette Portal Component Architecture


J2EE Application Server Portal (a WAR) Site Presentation Framework PortalBean Classes & JSPs component.xml Grids & Styles JSP

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

Deploying Site Components

Deployment Process Overview

Deployment Process Overview


The Portal deployment system takes Portal components, bundled as compressed files, and puts their resources into the Portal web application. Using the Portal deployment system, componentsand even entire sites can be installed, upgraded, and migrated from one machine to another. The details of the deployment process vary according to the type of component being deployed; however, deployment of any component involves the following steps:
1

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.

Figure 47 depicts the deployment process.

Section I: Portal Site Development

195

Deployment Process Overview

Figure 47:

Deployment Overview

J2EE Application Server Vignette Portal (a WAR)


portal.war admin beans beanutils diag images jslib jsp META-INF templates WEB-INF

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

Deploying Site Components

Deployment Process Overview

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

Section I: Portal Site Development

197

Component Archive File Structure

Component Archive File Structure


While the structure of CAR files varies somewhat for the different Portal components, all CAR files have the following common characteristics:
They are JAR files in ZIP format. They have a .car file extension. The root of the CAR file contains the component.xml file. Multiple CAR files can be bundled into a single CAR file.

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

Deploying Site Components

Component Descriptor File Structure

Table 16:

CAR File Contents and Deployment Destination (Continued) Location After Deployment Comments

File Name or Type Java .class files

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.

*.properties JAR files

validation.xml

Loaded in the database; not copied to the file system

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

Component Descriptor File Structure


A component.xml file has the following basic structure (with required elements and attributes shown in bold):
<?xml version="1.0" encoding="UTF-8"?> <epideploy:component component-id="string" component-type="Styles"|"Secondary Pages"|"Grids"|"Style Types"|"Secondary Page Types" major-version="integer" minor-version="integer" build-version="string" epi-version="string"

Section I: Portal Site Development

199

Component Descriptor File Structure

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>

Every component.xml file must start with the following declaration:


<?xml version="1.0" encoding="UTF-8"?>

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

characters; displayed in the administration consoles and updatable by administrators.

200

Deploying Site Components

Component Descriptor File Structure

xmlns:epideploy A required attribute whose value is fixed as shown

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

Component Details for Style Types and Secondary Page Types


The structure of the <epideploy:detail> element for style types and secondary page types is as follows (with required elements and attributes in bold):
<epideploy:detail> <template-info id="string" friendly-id="string" title="string" description="string" type="templatetype_ui_element" | "templatetype_page_content_include" | "templatetype_standard_jsp_include" | "templatetype_ui_grid_element" is-system="true"|"false" visible="true"|"false" allow-guest-access="true"|"false" header-filename="string"> </template-info> </epideploy:detail>

Style types and secondary page types must include <template-info> as a child element of <epideploy:detail>. The id attribute must match the

Section I: Portal Site Development

201

Component Descriptor File Structure

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

Deploying Site Components

Component Descriptor File Structure

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

Component Details for Styles, Grids, and Secondary Pages


The structure of the <epideploy:detail> element for styles, grids, and secondary pages is as follows (with required elements and attributes in bold):
<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" processing-type="JSP_BASED"|"ACTION_BASED"> </style-info> </epideploy:detail>

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

default for its style type or secondary page type.


apply-template-headerBoolean specifying whether the deployment

system should apply the style types header file, if any (applies only to style components).

Section I: Portal Site Development

203

Component Uniqueness and Versioning

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

Component Uniqueness and Versioning


Only one version of a component may be installed at any point in time. The uniqueness of a component is determined by the values of four <epideploy:component> attributes:

component-id component-type major-version minor-version

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

Deploying Site Components

Component Uniqueness and Versioning

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.

Section I: Portal Site Development

205

Component Uniqueness and Versioning

206

Deploying Site Components

Section II: Portlet Development

9
Summary: Audience: Topics: See also:

Java Standard Portlets and Vignette Portal


Explains how Vignette Portal works with Java standard portlets Java standard portlet developers using Vignette Portal

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

Overview of Vignette Portal and Java Standard Portlets


Vignette has been an expert group member for Versions 1 and 2 of the Java Portlet Specification (JSR 168 and JSR 286) for defining interoperability among portals and portlets. Vignette Portal complies with the current (JSR 286) version of the specification and therefore can invoke JSR 286-compliant portlets, manage them from the Portal administration consoles, and display them within Portal pages. The information in this guide assumes familiarity with Java Portlet Specification concepts and terminology. Knowledge Base (KB) items 6745 and 7967 provide examples of portlet web applications that are ready for deployment to Portal. Chapter 10, Deploying a Java Standard Portlet into a Portal Instance, explains the Portal deployment process.

Section II: Portlet Development

209

Java Standard Portlet Tag Library

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.

Java Standard Portlet Tag Library


Vignette Portal installs an implementation of the Java standard portlet tag library under PortalInstallDir/lib/shared. Some application servers, however, require the tag library to be added to the portlet web application in the WEB-INF/lib directory in order for the tag library to be properly resolved. If necessary for your application server, manually copy the tag library, named vgn-jsr-container-taglib.jar, to the required location.

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

Java Standard Portlets and Vignette Portal

User Attribute Mapping

PortletRequest or ServletRequest to determine whether the current

user is in the specified role.

User Attribute Mapping


Portal provides out-of-the-box mappings between Portal user properties and the user attributes specified in the Java Portlet Specification. However, you can change any of these default mappings by editing <entity-propertyalias/> values within a Portal configuration file named PortalInstallDir/config/entity_management.xml. Table 17 shows the default mappings provided in entity_management.xml.
Table 17: Default User Attribute Mappings Java standard User Attribute user.business-info.online.email user.name.given user.name.middle user.name.family user.gender user.home-info.postal.street user.home-info.postal.city user.home-info.postal.stateprov user.home-info.postal.postalcode user.home-info.postal.country user.employer user.business-info.telecom.telephone.number user.home-info.telecom.telephone.number user.home-info.telecom.mobile.number user.home-info.telecom.fax.number

Portal User Property email firstname middlename lastname gender address1 city state zip country employer day_phone night_phone mobile_phone fax

Section II: Portlet Development

211

Handling URL Security Exceptions

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

Handling URL Security Exceptions


Portal can be configured to enable selective transmission of data using HTTPS. With such a configuration, Portal administrators can select the secondary pages that are to be served securely. If the PortletURL generated by a Java standard portlet is set to be secure but the secondary page associated with the window state of the URL is not set to be secure, Portal displays an error message. Any portlet that has secure URLs therefore must handle javax.portlet.PortletSecurityException.
See also: Chapter 1, Vignette Portal Web Site Overview, for a discussion of security configuration options

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

Java Standard Portlets and Vignette Portal

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

JSR 168 Specification and AJAX


The JSR 168 portlet specification does not address AJAX support, which leads to the following issues:
The JSR 168 specification states that an action request on a portlet must be

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

on portlet display pages.

Section II: Portlet Development

213

AJAX-Enabling Portlets

JSR 286 Specification and AJAX


The updated JSR 286 standard still does not provide a native AJAX support, but does provide a Resource Serving capability that can be used to retrieve resources such as images and markup fragments which would be the JSR standard alternative to RAW window state outlined in the previous section. For more information, consult JSR 286 Specification section PLT.14. With respect to the "changing navigational state" issue described in the previous section, the JSR 286 specification stresses that the portlet only addresses the scenario for an AJAX call that does not need to coordinate feature or shared state change, like portlet application sessiion scope data, or any navigational state (such as render parameter, portlet mode, or window state).

Using the Portal AJAX Library


Your portlet web application has access to the Portal AJAX Library, which is in PortalInstallDir/portal/jslib/vapajaxlibrary.js. The following sections provide examples of the use of this library with Java standard portlets.
See also: Chapter 7, Using the Site Development APIs, for a description of the Portal AJAX Library

Creating URIs for Partial Portlet Updates

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);

This URL may be either a render URL or an action URL.

214

Java Standard Portlets and Vignette Portal

AJAX-Enabling Portlets

Performing a Partial Portlet 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 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>

Performing a Partial Portlet Update from a Form Submission

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.

Section II: Portlet Development

215

AJAX-Enabling Portlets

Uploading a File from a Multipart Form

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

Java Standard Portlets and Vignette Portal

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.

Section II: Portlet Development

217

AJAX-Enabling Portlets

218

Java Standard Portlets and Vignette Portal

10
Summary: Audience: Topics:

Deploying a Java Standard Portlet into a Portal Instance


Explains how to prepare a Java standard portlet for deployment into Vignette Portal Java standard portlet developers using Vignette Portal

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 web application

Portlet web applications

portal user

Section II: Portlet Development

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.

Run portlet application through Portlet Packaging Tool.

Deploy portlet application via application server's deployment tools.

Application Server Portlet application (WAR or EAR) Portal-ready Portlet WAR or EAR

Portal-ready WAR or EAR

Portal web application

220

Deploying a Java Standard Portlet into a Portal Instance

Using the Vignette Portal Portlet Packaging Tool

Figure 50:

Deploying a Portlet from an Exploded War File

Create portlet in exploded WAR format.

Run portlet application through Portlet Packaging Tool.

Deploy portlet application via application server's deployment tools.

Modify portlet application on filesystem. JSP changes take effect immediately. Java class and web.xml configuration changes take effect on portlet application restart.

Application Server Portlet application exploded WAR Portal-ready exploded WAR

Application Server Modified exploded WAR

Portal-ready exploded WAR

Portal web application

Portal web application

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.

Using the Vignette Portal Portlet Packaging Tool


The Vignette Portal Portlet Packaging Tool works with portlet applications in any formatone or more WAR files, one or more EAR files, or loose files in exploded WAR format. If you do not run the packaging tool on a portlet application before deploying it for the first time, the application server will complete its deployment process but Portal wont find the application. However, you need to run the tool only once on any portlet application. Thereafter, you can redeploy the application as well as make changes to it without rerunning the tool (as long as the application continues to contain the modifications applied by the tool).

Section II: Portlet Development

221

Using the Vignette Portal Portlet Packaging Tool

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.

Using the Vignette Portal Script


Portal ships with a preconfigured build file containing an Ant task to prepare a single WAR file for deployment. You can run this build file by using a command-line executable script for convenience.
To prepare a portlet application for deployment using the Portal script: 1

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.

Creating an Ant Build File


The packaging tools Ant task supports a number of options that can be declared in an Ant build file to provide flexible support for portlet

222

Deploying a Java Standard Portlet into a Portal Instance

Using the Vignette Portal Portlet Packaging Tool

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

Changes Applied by the Tool


The Vignette Portal Portlet Packaging Tool adds static elements to a portlet applications web.xml file to provide the following Portal-specific definitions:
Servlet that receives requests from Portal and invokes portlets ServletContextListener that will register the portlet application with

Portal
Security filter that blocks unauthorized requests to the portlet application

Section II: Portlet Development

223

Enabling Direct Requests to a Portlet Application

A context parameter specifying the context root to which the application

will be deployed

Enabling Direct Requests to a Portlet Application


The Portal Portlet Packaging Tool adds a security filter to a portlet applications web.xml file. This filter allows direct requests to static files, such as images, but it blocks all requests to servlets and JSPs that are not proxied through Portal, thereby ensuring that the Portal authentication and authorization mechanisms protect all application resources. As a result, a Portal user is forbidden to access a portlet application directly (see Figure 51).
Figure 51: Default Blocking of Direct Access to a Portlet Application
Application Server

Portal web application portal user

Direct access of portlet web application not allowed by default.

Portlet web application

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

Deploying a Java Standard Portlet into a Portal Instance

11
Summary: Audience: Topics:

Using Portlet Modes and Window States


Describes how Vignette Portal uses Java standard portlet modes and window states. Also describes three custom window states provided by Portal. Java standard portlet developers using Vignette Portal

Portlet Modes (below) Portlet Window States on page 226

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

Displays portlet help

End User

From portlet chrome (a Portal UI element) or from a link provided in the portlet content (if portlet supports this mode)

Section II: Portlet Development

225

Portlet Window States

Table 18: Mode EDIT

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

Defaults tab of the server or site console

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

Portlet Window States


Vignette Portal supports the standard window states (NORMAL, MAXIMIZED, and MINIMIZED) in addition to three custom window states: BINARY for displaying binary content, SOLO for pop-up windows, and RAW for AJAXenabled displays and for framesets. A window state controls the appearance, and in some cases the functionality, of a portal itself. For example, NORMAL displays the portlet on a page that typically includes other portlets. When displaying a portlet in NORMAL or MAXIMIZED window state, Portal can include a border, title bar, and buttons enabling users to interact with the

226

Using Portlet Modes and Window States

Portlet Window States

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

BINARY Window State


The BINARY custom window state provided by Portal enables you to generate markup for binary files (images, Adobe PDF files, Microsoft Word documents, etc.). Any binary content types allowed by the portlet (as specified in the portlet.xml file) can be set. This binary markup can be of either a dynamic or static nature. When the end user clicks a link to a portlet URL that uses the BINARY window state, the Portal framework handles the rendering of the binary content. Both portal and portlet security are enforced. NOTE: Portal does not cache the output of the BINARY window state even if the portlet specifies caching parameters. Here is an example of using the portlet APIs within a JSP to create a link to binary content:
PortletURL url = renderResponse.createRenderURL(); WindowState w = new WindowState("binary"); url.setWindowState(w); writer.write("<A HREF=\""+url.toString()+"\">Summary</A>");

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];

Section II: Portlet Development

227

Portlet Window States

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() + "\">");

The image can be dynamically constructed as follows:


WindowState currentWindowState = renderRequest.getWindowState(); if( currentWindowState.toString().equals("binary") { renderResponse.setContentType("image/jpeg"); byte[] b = new byte[1024]; // read image bytes from a binary data column (e.g. BLOB) // access that column by executing a JDBC statement ... InputStream inputStream = resultSet.getBinaryStream("blob_column"); int i; OutputStream portletOutputStream = renderResponse.getPortletOutputStream(); do { i = inputStream.read(b); portletOutputStream.write(b); } while (i != -1); portletOutputStream.flush(); }

228

Using Portlet Modes and Window States

Portlet Window States

Figure 52:

Displaying a Dynamic Image within a Portlet Window

Page 1

Page 2

Page 3

Portlet A

Stocks Portlet
Ticker Symbol:

Content

Submit

Page 1

Page 2

Page 3

Portlet A

Stocks Portlet

Same Content as Above

SOLO Window State


With the SOLO custom window state, the portlet generates nearly all of the output. Portal does not add navigation, branding, or any other content; it does, however, include the <HTML> and <BODY> tags as well as the CSS enabling the content to be rendered with the fonts and colors used in a portal. Vignette recommends that you implement a pop-up window by using SOLO as the window state, in addition to JavaScript attached to a link, to specify that the window should be a pop-up. Figure 53 illustrates the following example: A search portlets main view includes a link to past searches. The link opens a pop-up window using JavaScript that looks like this:

Section II: Portlet Development

229

Portlet Window States

<a href="POPUP_URL" onClick="doPopup(this.url)">Past Searches</a>

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

Same Content as Above

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

Using Portlet Modes and Window States

Portlet Window States

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.

RAW Window State


Like SOLO, the RAW custom window state does not receive any content from Portal. However (unlike SOLO), RAW does not include the <HTML> and <BODY> tags. Use the RAW window state to AJAX-enable a portlet, as documented in Chapter 9, Java Standard Portlets and Vignette Portal. Vignette recommends that you also use RAW to implement displays that involve HTML framesets. Figure 54 provides an example of the use of RAW with SOLO and JavaScript for displaying a frameset within a pop-up window.
Figure 54: RAW Window State Example

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

Save Download Upload

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

Section II: Portlet Development

231

Portlet Window States

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

display binary content.


See also: Chapter 9, Java Standard Portlets and Vignette Portal, for more about the use of RAW to AJAX-enable a portlet

232

Using Portlet Modes and Window States

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

Java Standard Portlets vs. PortalBean Portlets


Since its inception, Vignette Portal has included the PortalBean framework, a proprietary mechanism supporting discrete, pluggable applications known as "portlets." PortalBean portlets are developed using Vignette APIs that predate the release of the Java Portlet Specification. Although Portal continues to support the PortalBean framework, new portlets should be developed using the standard specification rather than the Vignette APIs. Unlike PortalBean portlets, Java standard portlets provide hot deployment and redeployment as well as the ability to use third-party tools and open-source projects specifically designed for Java standard portlet development. NOTE: 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.

Section II: Portlet Development

233

Vignette Portal and the PortalBean Framework

See also:

Chapter 9, Java Standard Portlets and Vignette Portal, for a description of how Portal works with Java standard portlets

Vignette Portal and the PortalBean Framework


The PortalBean framework has not been enhanced since version 4.5 of Vignette Portal (then called Vignette Application Portal), with the following exceptions:
AJAX support Release of a deployment utility called the CAR tool Additional I18N support through a custom JSP tag named <mod:i18nAlias> Ability to retire a prototype (JSPBean) PortalBean

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

Support for Standards-Based Portlets


Vignette Portal now has built-in support for portlets that adhere to the JSR 286 and Web Services for Remote Portals (WSRP) specifications. In addition, Vignette is an expert group member of the JSR 286 portlet specification. Changes in the Portal user interface enable standards-based portlets to be managed and viewed along with PortalBean portlets. For example, the Portal administration consoles support deployment of Java standard portlet applications; registration with WSRP-compliant producers; consumption of

234

PortalBean Portlets

Vignette Portal and the PortalBean Framework

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.

Creating a URI to Another PortalBean


Portal 7.2 introduced a new method on
com.vignette.portal.website.enduser.PortalContext that

enables you to generate a URI from one PortalBean to another:


createPortletURI(). The following example creates the URI for a generic view of a portlet whose friendly ID is "portletB":
PortalBean thisBean = view.getBean(); Hashtable hash = new Hashtable(); hash.put("viewID", new String []{PortalBeanView.GENERIC_VIEW}); String portletBuri = portalContext.createPortletURI("portletB", "view", hash).toString();

(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

Section II: Portlet Development

235

Vignette Portal and the PortalBean Framework

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

Remote Content APIs


Two remote content APIs have been introduced since version 4.5:
The Remote Session Management API supports the retrieval of content

from external sources.


The Segmentation and Transformation API supports the inspection and

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.

Deprecation of Administrator PortalBeans


Portal no longer supports administrator-only "tool" and "plug-in" PortalBeans. As a result, ADMIN and ADMIN_MENU are no longer meaningful values for the CATEGORY attribute of the <PORTALBEAN> element in a PortalBean descriptor (PBD) file. Portal simply ignores any PBD files having one of these values.

Other API Changes


A number of Portal tags, variables, CSS classes, and Java APIs have been added since version 4.5, while others have been deprecated. These changes support enhancements to performance, scalability, URL generation,

236

PortalBean Portlets

AJAX-Enabling 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

AJAX-Enabling PortalBean Portlets


Vignette Portal provides AJAX support for Java standard portlets through the RAW PortalBean view. You can use a third-party AJAX widget toolkit, a homegrown toolkit, or the Portal AJAX Library to perform AJAX-style updates within this view. When using any AJAX library or toolkit, be sure to namespace JavaScript functions to ensure uniqueness. The PortalBeans name provides one namespacing mechanism:

Section II: Portlet Development

237

AJAX-Enabling PortalBean Portlets

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

Creating AJAX URLs


You enable a PortalBean view to partially update itself by creating an AJAX URLfor example:
<% String ajaxURL = view.getBean().getFullViewURL("formsubmit-response");

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

AJAX-Enabling PortalBean Portlets

Performing a Partial Portlet 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 PortalBean portlet from a link:
<a href="" onclick="new VignettePortal.AJAXClient().sendURL(<%=ajaxURL%> ,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 View Update from a Form Submission


The following example shows a form whose submission partially updates an AJAX view. It demonstrates the use of AJAX with an HTTP POST request.
<form name="<%=formName%>" action="<%ajaxURL%>" 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.

Uploading a File from a Multipart Form


The Portal AJAX Library provides multipart form support through its customization of the Dojo IframeIO. For a multipart form, set the encoding

Section II: Portlet Development

239

AJAX-Enabling PortalBean Portlets

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.

Section II: Portlet Development

241

<mod:i18nAlias> JSP Tag

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

<mod:i18nAlias> JSP Tag


This tag (added in version 7.0 of the Portal product) is used in conjunction with <mod:i18nValue/> to support alias attribute values other than type and instance. Suppose that you wanted to list PortalBeans, showing the localized title and description of each. You could use <mod:i18nValue/> to get the PortalBeans unique ID twice, as follows:
<% Iterator iter = view.getModuleIterator(); while (iter.hasNext()) { PortalBean bean = (PortalBean)iter.next(); %> Title: <mod:i18nValue stringID="<%= bean.getUID() %>" key="title" defaultValue="<%= bean.getTitle() %>"/> Description: <mod:i18nValue stringID="<%= bean.getUID() %>" key="description" defaultValue="<%= bean.getDescription() %>"/> <% } %>

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

Retiring a Prototype PortalBean

Description: <mod:i18nValue alias="bean" key="description" defaultValue="<%= bean.getDescription() %>"/> </mod:i18nAlias> <% } %>

Retiring a Prototype PortalBean


A prototype PortalBean consists only of one or more JSP files, a PortalBean descriptor (PBD file), and optional image files. Instead of requiring its own Java classes, a prototype PortalBean uses two of the classes in the com.epicentric.portalbeans.beans.jspbean package:
JSPBean as its PortalBean implementation JSPView as its PortalBeanView implementation

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()

Section II: Portlet Development

243

Retiring a Prototype PortalBean

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

Section III: Portal Services

13
Summary: Audience: Topics: Table 20: Service MetaStore

Portal Services Overview


Describes Vignette Portal services that you can customize or use JSP or Java developers responsible for customizing Vignette Portal

Available Portal Services (below) Storing Data in the MetaStore on page 250 Services API on page 251

Available Portal Services


Vignette Portal provides a number of services that Portal sites and components can use and, in some cases, customize. Table 20 summarizes the Portal services that are covered in this guide and provides cross-references to other documentation of them.
Summary of Portal Services What You Can Do See

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

Section III: Portal Services

247

Available Portal Services

Table 20: Service

Summary of Portal Services (Continued) What You Can Do See

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

Portal Services Overview

Available Portal Services

Table 20: Service Caching

Summary of Portal Services (Continued) What You Can Do See

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

Remote Session Management and Manipulation

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

Section III: Portal Services

249

Storing Data in the MetaStore

Table 20: Service

Summary of Portal Services (Continued) What You Can Do See

Content Access Management

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

Storing Data in the MetaStore


The Portal MetaStore is a central repository for any type of serializable data. Portal typically stores PortalBean user preferences, shared state, and systemwide state (that is, server configuration information) in the MetaStore. The MetaStore is hierarchical in nature: content is organized into folders (MetaStoreFolder objects), which can contain documents (MetaStoreDocument objects), properties, and other folders. Documents are the basic unit of storage within the MetaStore. Each document holds a single data item, such as a serialized Java object, byte array, image, text string, file, number, or DOM document. Properties are name-value pairs, such as "color" = "blue", that can be associated with both folders and documents. The MetaStore that ships with Portal makes persistent its folders, documents, and properties in a SQL database. It is therefore visible across all servers within a Portal cluster; however, it is therefore also expensive to access the data stored in it. If data does not need a complex management system or constant updating, storing that data in the MetaStore is a simple way to make it globally accessible. By convention, a company-specific folder (domain_name) containing the global data is placed in the vendor folder of the MetaStore:
/vendor/domain_name

250

Portal Services Overview

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

Section III: Portal Services

251

Services API

252

Portal Services Overview

14
Summary: Audience: Topics:

Users and Access Control


Explains how to programmatically access user data, customize authentication, and check a Vignette Portal users permissions JSP or Java developers responsible for customizing Vignette Portal

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

or single-sign-on product to determine whether a Portal visitor is a registered user


The Portal authorization system, which controls access to specific Portal

functionality based on a users access permissions

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.

Section III: Portal Services

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

create system groups. There are several types of system groups:

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

Users and Access Control

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

User Access APIs


A number of Portal interfaces and classes have methods that can be used to access users and user data. These interfaces and classes include the following:
com.vignette.portal.website.enduser.PortalContext com.epicentric.user.UserManager com.epicentric.user.User com.epicentric.entity.EntityType com.epicentric.entity.EntityProperty com.epicentric.uid.UIDRegistry com.epicentric.common.website.EntityUtils

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

Section III: Portal Services

255

User Management

Retrieving an Individual User

Retrieve the current user, from the PortalContext object, as follows:


User user = portalContext.getCurrentUser();

To retrieve a user by unique ID, use the UIDRegistry class:


UIDRegistry uidRegistry = UIDRegistry.getInstance(); try{ User userToGet = uidRegistry.getObjectFromUID(userUID); }catch (UIDException exception){ // Handle exception. }

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);

Retrieving Multiple Users

To retrieve a list of users, pass in a non-unique property valuefor example:


UserManager userManager = UserManager.getInstance(); try{ Iterator usersIterator = userManager.getUsers("lastname", "Smith"); while (usersIterator.hasNext()){ User nextUser = (User)usersIterator.next(); } }catch (EntityPersistenceException exception){ // Handle database error. }

256

Users and Access Control

User Management

Retrieving User Properties

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();

To check the value of a property attribute, query the EntityProperty, as follows:


EntityProperty firstNameProperty = userType.getProperty("firstname"); boolean canSearch = firstNameProperty.isSearchable();

Working with User Segments

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

Section III: Portal Services

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

User Group Access APIs


Portal has user group counterparts for many of the user access APIs. Because user groups, like users, are entities, user groups can have configurable properties.
Retrieving User Groups

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

Users and Access Control

User Management

Checking Group Membership

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. }

Section III: Portal Services

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

Controlling Guest Access to Components


Sometimes you want to ensure that unauthenticated users (guest users) cannot access a Portal feature or set of functionality. For example, a guest would never be allowed to access the user account management page. Guest access can be enabled or disabled for a specific secondary page type or style type by setting the allow-guest-access attribute of the components deployment descriptor (component.xml). Out-of-the box secondary page and style types have this value set as appropriate. For custom secondary page types and style types, this value defaults to true if you dont explicitly set it. (See Chapter 8, Deploying Site Components, for a discussion of the component.xml file.) When an unauthenticated user attempts to access a non-guest secondary page type, Portal redirects the user to the login page.

260

Users and Access Control

Authentication

Creating a Custom Authenticator


Creating a custom authenticator involves three steps:
Installing, configuring, or otherwise preparing the authentication data

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

authenticators have in common. To ensure compatibility as new

Section III: Portal Services

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

Users and Access Control

Authentication

The following code shows a subclass,


com.yourcompany.authentication.FileAuthenticator, that

supports this example:


package com.yourcompany.authentication; import com.epicentric.authentication.*; import java.util.*; import java.io.*; /** * Authenticator example that reads a flat file of one * username,password combination per line into a HashMap */ public class FileAuthenticator extends GenericAuthenticator { // The LogWrapper is used to make logging easier private static final com.vignette.portal.log.LogWrapper LOG = new com.vignette.portal.log.LogWrapper (FileAuthenticator.class, "com.epicentric.authentication"); // global variables /** * Realm object, which associates a users profile with * the users authentication account. The realm is set in * the authentication XML file but should also be provided * to the authenticator as a global variable in case it * needs to be used for any special purpose. */ Realm realm; Map users; /** * Looks up users in the HashMap. * @param logon Users logon * @param password Users password * @throws InvalidAccountException if the passed logon and * password combination does not match a record in the data * source. */ public void authenticate(String logon, String password) throws InvalidAccountException { if (!users.get(logon).equals(password)) { throw new InvalidAccountException("The username and password combination supplied is invalid."); } } /**

Section III: Portal Services

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

Users and Access Control

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); } } }

Writing the Authenticator XML

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"

Section III: Portal Services

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

Users and Access Control

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

identifies the path to the flat file.


ACCOUNT-TYPE-DESCRIPTOR is another child element of AUTHENTICATOR

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:

com.vignette.portal.portlet.website.PortletWindowBean com.epicentric.common.website.SessionInfo com.epicentric.common.website.EndUserUtils com.epicentric.user.User

Section III: Portal Services

267

Authorization

Table 21 lists the permissions-checking methods on these classes.


Table 21: Methods for Checking Permissions Methods

Permission Type Portlet

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

Users and Access Control

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

The Vignette Portal Caching System


Vignette Portal provides a flexible caching system that allows you to use the out-of-the-box caching defaults, to configure the default behavior, or to perform deeper customizations programmatically. Among the features that the Portal caching system supports are the following:
Caching by any key that correctly implements hashCode() and equals() Passivating data (removing inactive objects from cache memory and

placing them in persistent storage)


Configuring cache expiration and passivation times Configuring the maximum number of objects in a cache (expiring by oldest

usage or by oldest addition)


Caching in either a local environment (where caching is localized to a

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

Section III: Portal Services

269

The Vignette Portal Caching System

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

traditional expiration models.


Size-based strategies are driven by usage patterns. They limit the number of

items in the cache. There are two variations:

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.

Class TimeToLiveStrategy LiveUntilUnusedStrategy

Sizebased

FirstInFirstOutStrategy

LeastRecentlyUsedStrategy

270

Caching

The Vignette Portal Caching System

Table 22: Type Other

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.

Class BroadcastingStrategy MonitoringStrategy

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

Section III: Portal Services

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 . . . }

Now, use the object ID to cache an object into the Cache:

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.)

Section III: Portal Services

273

Caching Examples

Using Multiple Strategies


If you want to use more complex caching behavior, you simply add more strategiesfor example:
List strategies = new ArrayList(3); // Set time-to-live to 1 hour strategies.add(new TimeToLiveStrategy(60*60*1000)); // Passivate to file after 5 minutes of no use PassivationStorageHandler handler = new FileSerializingPassivationStorageHandler(); strategies.add(new TimeUntilUnusedStrategy(5*60*1000, new PassivatingCacheAction(handler))); // Set maximum cache size to 10,000 items strategies.add(new SoftLeastRecentlyUsedStrategy(10000));

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.

Using a Broadcasting Strategy


The BroadcastingStrategy is slightly different from the other strategies. Instead of being created via construction, the BroadcastingStrategy is created by calling a method on the CacheFactory instance:
BroadcastingStrategy strategy = cacheFactory.createBroadcastingStrategy();

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

Using a Custom Cache Data Source


Instead of using the put() method to populate the cache, you have the option of configuring the caching system to get the data directly from your own external source (for example, from a database table). To use this option, you must extend the CacheDataSource class. Its load() method must be implemented to retrieve the specified object from external storage. The caching system will load the object from the defined external source into the cache whenever the cache needs refreshing. Objects will be expired from memory based on the expiration time, but they are never expired from the external persistence mechanism. Suppose that you store Widget objects in a table named Widgets, and that you want the widget cache to use this table as its source. You would implement CacheDataSource as follows:
public class WidgetCacheDataSource extends CacheDataSource { public Object load(Object widgetID) throws CacheException { try { // Retrieve the specified widget // SQL select statements go here // Generate widgetObject from the returned data return widgetObject } catch (SQLexception e) { // Throw SQL errors as a CacheException throw new CacheException("Failed to load Widget " + widgetID, e); } } }

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);

Section III: Portal Services

275

Caching Examples

Retrievals from a custom cache data source occur as follows:


1 2

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

The Vignette Portal Metrics System


The com.epicentric.metrics package supports collecting and recording basic Vignette Portal metrics data, such as portlet page hits, unique user sessions, and other usage patterns per page, portlet, portlet view, and user. As shipped, Portal collects and archives concurrent usage, site, page, domain, and other metrics. In addition, you can use the metrics system to monitor, collect, and archive any custom data of interest to your organization. Portal collects metrics as raw data on the fly. For example, a metric that counts page views increments the counter whenever a user views that page. Aside from counters, you can also collect other integer data, strings, and dates. Portal persists metrics data into a log table at configurable intervals. Every 24 hours, the Portal-defined metrics data is archived, and the metrics log table is emptied. A Vignette Builder template, called the Portal Metrics Viewer, can be used to display metrics reports and charts. Additionally, Portal metrics tables can be queried through any external reporting mechanism. IMPORTANT: The metrics log is a denormalized table; the metrics archive tables are normalized. Do not attempt to retrieve data from the metrics log table.

Section III: Portal Services

277

First-Time Database and Connection Pool Setup

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

First-Time Database and Connection Pool Setup


Under the default Vignette Portal configuration, the Portal database includes the metrics log and archive tables. If you add custom metrics to a Portal installation, however, Vignette recommends that you place all tables for both the Portal and custom metrics in a separate, external database that has its own connection pool. This process involves two steps:
Creating the external database Setting properties in the Portal configuration file

This section explains these steps.

Creating an External Metrics Database


You can use any relational database to store metrics data. Portal ships with a table installer utility that uses an XML file to create tables in a database. The XML file for Portal tables is named tables.xml, which is in the PortalInstallDir/system/dbsetup directory. Use tables.xml as a template for creating a metrics XML file. This new XML file must contain the following lines from tables.xml:
the <xml>, <DOCTYPE>, and <schema> tags the elements for all of the Portal metrics log and archive tables the </schema> tag

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

First-Time Database and Connection Pool Setup

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

Setting Database and Connection Pool Properties


Configuring a separate database and connection pool for the log and archive metrics tables involves defining the database connection, defining the connection pool, and configuring the Portal metrics system to use the new connection pool.
To define the database connection:

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

Section III: Portal Services

279

Creating a Custom Metric

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

Creating a Custom Metric


Once youve set up an external metrics database and connection pool, you can start gathering custom metrics data. Creating a custom metric involves three steps:
1 2 3

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

Each of these steps is explained next.

Defining a Custom Metric in mbeans.xml


Each custom-developed metric (MBean) must be defined in a file named mbeans.xml. This file must be in PortalInstallDir/config. A sample metric is available in PortalInstallDir/config/examples/mbeanssample.xml. This section describes the elements and attributes of mbeans.xml.
<custom-mbeans> Element

Document root element; do not modify.

280

Metrics

Creating a Custom Metric

<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.

Section III: Portal Services

281

Creating a Custom Metric

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

Creating a Custom Metrics Archive Table


Each mbean defined in mbeans.xml needs its own table in the metrics database. The table must include a column named report_id of type integer. This column must be the first one in the table, should not allow null values, and should be an implicit key to the table (in addition to the key identified by the name-space attribute of the mbean element). The Portal table installer and metrics XML file (described in Creating an External Metrics Database on page 278) can be used to create a new custom metrics table. Custom metrics tables should be added to this file as follows:
<?xml version="1.0" ?> <!DOCTYPE schema PUBLIC "http://www.epicentric.com/dtd/sql-schema-1-1.dtd" "./sql-schema-1-1.dtd"> <!-- to install these tables run table_installer in your bin directory --> <schema version="4.0 SP4"> <tablegroup name="metrics log" java-package="com.epicentric.metrics.log"> <!-- Portal log tables go here --> </tablegroup>

282

Metrics

Creating a Custom Metric

<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).

Using Metrics API Calls


The CustomMonitor class has separate instance methods for recording the various types of data:
recordIncrementalNumberValue(String attribute) recordIncrementalNumberValue(String attribute, String key) recordIncrementalNumberValue(String attribute, String key, int increment) recordOverwrittenNumberValue(String attribute, int value) recordOverwrittenNumberValue(String attribute, String key, int value) recordStringValue(String attribute, String value) recordStringValue(String attribute, String key, String value) recordDateValue(String attribute, Date date)

Section III: Portal Services

283

Using Table Aliases

recordDateValue(String attribute, String key, Date date)

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.

Using Table Aliases


If you want to use table and/or column name aliases in mbeans.xml (for example, so that you can use its element name attributes as headings and labels in reports), you must modify another XML file, metrics_map.xml, to provide the mappings between the actual names and aliases. The metrics_map.xml file is in the config subdirectory of the Portal installation directory. This section describes the elements and attributes of mbeans.xml.

<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

contain spaces and use mixed case. Required attribute. Example:


Portlet Views
table

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

Using Table Aliases

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

key attribute value for the corresponding mbean in mbeans.xml. This

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:

Section III: Portal Services

285

Metrics Code Example

<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>

Metrics Code Example


Suppose that your company wants to collect the following information on each portlet view:
Total number of hits Total hits per user Time stamp of the latest hit per user

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.

Defining the Custom Metric in mbeans.xml


The following additions to mbeans.xml would support this scenario:
<mbean name="com.companyname.metrics.portlets" name-space="portletviews" key="userid">

286

Metrics

Metrics Code Example

<attribute-integer name="pagehits" method="Incremental"/> <attribute-date name="last_hit"/> </mbean>

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.

Creating the Custom Metric Table


For this scenario, you would add the following lines to the "custom metrics" tablegroup element in the metrics XML file and then run the table installer:
<table name="portletviews" java-class= "com.epicentric.metrics.data.MetricsReportElement" > <comment> This table stores metrics data for portlet views. </comment> <column name="report_id" type="integer" no-nulls="true" /> <column name="userid" type="varchar" size="64" no-nulls="true" /> <column name="pagehits" type="integer" /> <column name="last_hit" type="timestamp" /> <index name="portletviews_PK" columns="report_id,userid" primary-key="true" /> </table>

Adding JSP/Java Code


To collect the metrics data, you would add code to each portlet view that acquires a CustomMonitor and then uses it to record the data:
CustomMonitor monitor = CustomMBeanFactory.getCustomMonitor( "com.companyname.metrics.portlets"); monitor.recordIncrementalNumberValue("pagehits"); // code here gets the user ID as a string monitor.recordIncrementalNumberValue("pagehits", userid); monitor.recordDateValue("pagehits", userid, new Date());

NOTE: Not passing a key (userid) provides a counter of all page hits, as demonstrated in the call to recordIncrementalNumberValue("pagehits").

Section III: Portal Services

287

Metrics Code Example

A Java view would need to catch either a


com.epicentric.metrics.NoSuchMBeanException or a javax.management.AttributeNotFoundException.

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

The Vignette Portal Connection Pooling System


The com.epicentric.jdbc package provides a database connection pooling system. For frequently accessed data, a separate connection pool should be establishedone pool per database or table space. IMPORTANT: The Portal database should not be manipulated directly; it is used only as a persistence mechanism. Instead, objects and properties stored in the Portal database should be manipulated using the appropriate Portal APIs. When creating a database connection pool, keep the following additional guidelines in mind:
Close all statements. Remember that each statement object opens one

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.

Section III: Portal Services

289

Connection Pooling Code Examples

See also:

Vignette Portal Configuration Guide for details about configuring Portal connection pools and about data storage options

Connection Pooling Code Examples


The following example shows how to initialize and then use a custom database connection pool. This connection pool uses an Oracle JDBC driver, although any supported database driver and URL should also work.

Initializing a Connection Pool


Connection pools can be initialized in either of two ways: statically through the Portal properties file or dynamically through Java.
Static Configuration

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

Connection Pooling Code Examples

Dynamic Configuration

For dynamically configured connection pooling, use the


com.epicentric.jdbc.ConnectionPoolConfiguration class to

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.

Using the Connection Pool


The following example accesses a statically configured connection pool, uses a connection to execute a SQL statement, and then closes the statement and the connection in a finally block:
// Get a connection pool named "my_pool", defined in the // properties file. String poolName = "my_pool"; ConnectionPool pool = ConnectionPoolManager.getPool(poolName); // Initialize variables. Connection connection = null; Statement statement = null; ResultSet resultSet = null;

Section III: Portal Services

291

Connection Pooling Code Examples

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

Connection Pooling Code Examples

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();

Section III: Portal Services

293

Support for Oracle LOBs

// Catch general exception. } catch (Exception e){} } }

Support for Oracle LOBs


The Vignette Portal connection pool provides a built-in abstraction layer that reduces the complexity involved in using the Oracle LOB data type. This abstraction layer enables you to stream the data directly into LOBs using the setBinaryStream() method on the J2SE PreparedStatement object. The Portal connection pool supports the following insert/update statements on LOBs:
inserting values into all columns of a table:
INSERT INTO tableName (?, ?, ?, ...)

inserting values into any number of specified columns of a table:


INSERT INTO tableName (column1, column2, column3, ...) VALUES (?, ?, ?, ...)

updating a table using this form:

UPDATE tableName SET columnName=value[, columnName=value...] WHERE columnName=value[, columnName=value...]


UPDATE tableName SET

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

Support for Oracle LOBs

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

Section III: Portal Services

295

Support for Oracle LOBs

296

Connection Pooling

18
Summary: Audience: Topics:

Remote Content Retrieval and Manipulation


Explains how to use Vignette APIs for retrieving, inspecting, and altering remote content, as well as how to customize the WebConnector 3.0 portlet Java developers who want to expose remote content through Vignette Portal

Retrieving Content from Remote Sources (below) Inspecting and Altering Proxied Content on page 298 Customizing the WebConnector 3.0 Portlet on page 299

Retrieving Content from Remote Sources


Vignette provides a Remote Session Management (RSM) API that supports the retrieval of content from external sources. This API provides protocolagnostic transport layer services, using a session-request-response paradigm:
1 2 3 4

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.

Section III: Portal Services

297

Inspecting and Altering Proxied Content

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

Inspecting and Altering Proxied Content


Once youve retrieved remote content, you can manipulate its markup text using the Vignette Segmentation and Transformation API. This API supports the following capabilities:
Parse markup contentread characters from a reader and tokenize them

(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

process referred to as "clipping"). An implementation of the


com.vignette.portal.text.processor.TextProcessor interface is

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

Remote Content Retrieval and Manipulation

Customizing the WebConnector 3.0 Portlet

Figure 55:

Segmentation and Transformation Process

TextProcessor read input parse & tokenize inspect/alter produce output

Markup Text

HTMLToken CSSToken JavascriptToken

Segmenter TokenMutator

UltimateDestination

Segment Segment Segment pre body post

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

Customizing the WebConnector 3.0 Portlet


The WebConnector 3.0 portlet enables rapid integration of external applications, web pages, or "clipped" content into Vignette Portal. The portlet uses the RSM API for its transport layer and the Segmentation and Transformation API to keep proxied content within the portal by altering URLs. Because WebConnector is used to integrate many diverse web sites and applications into Portal, it must remain very flexible. However, you can

Section III: Portal Services

299

Customizing the WebConnector 3.0 Portlet

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

Accessing the Remote Request and Response


You can inspect and modify the request that WebConnector sends, and you can inspect the response that WebConnector receives, by implementing the
com.vignette.portlet.buildingblock.webconnector .interpolator.RequestResponseInterpolator interface. This interface requires implementation of two methods: processRequest() and processResponse(). WebConnector calls these two methods before and

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

Remote Content Retrieval and Manipulation

Customizing the WebConnector 3.0 Portlet

context is an implementation of the com.vignette.portlet .buildingblock.webconnector.interpolator.RequestRespons eContext interface, which WebConnector creates and populates with

context information from the portlet


remote_session is an implementation of the com.vignette.portal.rsm.RemoteSession interface, which models

the session on the remote entity


remote_request is an implementation of the com.vignette.portal.rsm.RemoteRequest interface, which

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.

The context data includes the following:


WebConnector proxy URL, available from the ATTRIBUTE_KEY_PROXY_URL named constant. This key is a string

version of the URL that WebConnector is about to proxy. This information

Section III: Portal Services

301

Customizing the WebConnector 3.0 Portlet

is also available in java.net.URL form, from the RemoteRequest object.


Interpolator metadata, available from the ATTRIBUTE_KEY_INTERPOLATOR_META_DATA named constant. This key

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.

You can access context data through two methods on RequestResponseContext:


getContextAttributeKeys(), which returns an enumeration of the key

names of all context attributes


getContextAttribute(String key), which returns, as an object, the context attribute specified by key, or null if the object does not exist.
See also: Vignette Application Portal Module Developers Guide for information about the legacy PortalBean APIs

Using a Custom Authenticator


The RSM API provides an Authenticator interface for handling authentication to remote servers. You can write your own implementation of this interface to add custom authentication support to WebConnector 3.0 portlet instances. The Portal administrator configures a portlet instance to use your authenticator implementation.

Performing Custom Segmentations and Transformations


You can use the Segmentation and Transformation API to write classes that inspect and alter the content proxied by a WebConnector 3.0 portlet instance.

302

Remote Content Retrieval and Manipulation

Customizing the WebConnector 3.0 Portlet

Custom Content Clipping

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.

Section III: Portal Services

303

Customizing the WebConnector 3.0 Portlet

304

Remote Content Retrieval and Manipulation

19
Summary: Audience: Topics:

Customizing Federated Search


Describes the Vignette Federated Search framework and explains how to develop integrations that enable external content repositories to participate in federated searches Java developers responsible for customizing Vignette Portal

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.

Section III: Portal Services

305

Federated Search Architecture

Federated Search Architecture


The Federated Search framework consists of three tiers:
User Interface The Federated Search portlet that ships with Vignette

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

Customizing Federated Search

Federated Search Architecture

Figure 56:

Federated Search Architecture


Tier I: User Interface

Federated Search Portlet

Custom Federated Search Application

Tier II: API


Federated Search API (com.vignette.portal.search)

Tier III: Connectors


Federated Search Connector Interface

CAM Search Connector

Vignette Product Connectors

Custom Connectors

CAM API

Products

3rd-party Applications (optional)

(external to Federated Search)

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).

Section III: Portal Services

307

Federated Search Architecture

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

Repositories and Collections


Whereas repositories and connectors have a one-to-one relation, a single repository can contain multiple collections, and its connector can target any or all of those collections. A repositorys collections can either be flat or have a hierarchical relationship to each other. For example, Autonomy supports creation of separate, nonhierarchical search databases; content from each of various sources can be indexed into its own database within the Autonomy repository. An example of a hierarchical repository is the CAM repository, which has a root folder and an arbitrary number of subfolders nested to any depth.

308

Customizing Federated Search

Creating a Custom Search Connector

Search Terms and the Common Vocabulary


A search term is composed of a search field name, an operator, and one or more valuesfor example, title contains "LDAP" or modified date is between January 1, 2006 and January 31, 2006". The search field names and operators are defined in the PortalInstallDir/config/ federated_search_master_vocabulary.xml file. When developing a search connector, one of the tasks involved is mapping the search field names that the target repository uses to the vocabulary defined in that file. You can add more terms to
federated_search_master_vocabulary.xmlfor example, to support

additional fields than are provided by default.

Creating a Custom Search Connector


Federated Search connectors are instances of a service implementation named FederatedSearchService, which supports configuration using the Portal server consoles Service Manager. By identifying your custom connector as an instance of FederatedSearchService, its configuration can be predefined as well as modified through the Service Manager. Developing a custom search connector involves the following steps:
Planning your implementation Implementing the ISearchConnector interface Defining your connectors search field names Creating property files to provide localization of title and description

strings
Creating XML files known as component descriptors in preparation for

deployment of your connector


Packaging your connector for deployment Testing the connector

Each of these steps is detailed below.


See also:

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

Section III: Portal Services

309

Creating a Custom Search Connector

Step 1: Plan the Implementation


This step involves considering Federated Search design principles and gathering information about the repository that is the connectors target.
Selecting the Interaction Model

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

Customizing Federated Search

Creating a Custom Search Connector

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

Gather the following information about your connectors target repository:


Names of the supported searchable fields Names of the available search collections, whether these collections are

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

and port in the case of a web service interaction model


Preparing for Localization

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

supporting classes (exposed through the PortalBean Manager)

Step 2: Implement the ISearchConnector Interface


Create a Java class that implements the ISearchConnector interface. Typically, youll also want to take advantage of the Portal logging API by declaring a static LOG variable (an instance of com.vignette.portal.log.LogWrapper) in your class. For example:

Section III: Portal Services

311

Creating a Custom Search Connector

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

ISearchConnector has five methods that you need to implement, as

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

Customizing Federated Search

Creating a Custom Search Connector

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

Section III: Portal Services

313

Creating a Custom Search Connector

either the set of search collection names against which this search should be

executed, or null if all collections supported by this connector are to be searched


the ConnectorSearchContext object, which provides access to search

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

Customizing Federated Search

Creating a Custom Search Connector

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

typically used in specifying a date rangeit is an instance of


DoubleValueSearchTerm.

Here is an example of an advanced search implementation:


public SearchResults executeAdvancedSearch(SearchCriteria searchCriteria, Set targetCollectionNames, ConnectorSearchContext context, boolean recursive) throws SearchException { StringBuffer sb = new StringBuffer(); // loop through search terms for (Iterator iter=searchCriteria.getSearchTerms().iterator(); iter.hasNext(); ) { SearchTerm term = (SearchTerm) iter.next(); // if term has a single operator, append it if (term instanceof SingleValueSearchTerm) { SingleValueSearchTerm sterm = (SingleValueSearchTerm) term; if (sb.length() != 0) {

Section III: Portal Services

315

Creating a Custom Search Connector

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); }

This implementation would process search criteria as, for example,


title:"Vignette" body:"federated search" daterange:startDateNumericValue-endDateNumericValue.

Step 3: Define the Connectors Search Field Names


Use an XML file to define the search field names that your connector supports and to map them to the common vocabularythe fields defined in the

316

Customizing Federated Search

Creating a Custom Search Connector

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" />

<connector-field id="SUMMARY" name="abstract" />


<connector-field id="URL" name="URL" /> </connector-fields>

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.

Step 4: Create the I18N Property Files


The Vignette Portal I18N framework supports the use of .properties files to define locale-specific strings for values exposed through user interfaces. In the case of search connectors, the server console exposes the title and description of the connectors instance configuration through the Service Manager. In addition, the server console exposes the title and description of the connectors supporting classes (explained in Step 5: Create Component Descriptors on page 318) through the PortalBean Manager. At minimum, your custom connector should include two default property filesone for the Service Manager and one for the PortalBean Manager. Each of these files should contain key/value pairs for title and description. The name of each property file must begin with a 128-bit locale key in hexadecimal notation that is unique across Portal. The simplest way to generate a locale key is by running PortalInstallDir\bin\runs_with_classpath.bat (Windows) or PortalInstallDir/bin/runs_with_classpath.sh (UNIX) with the class com.epicentric.uid.UniqueIDFactoryfor example (assuming bin is your current directory):
runs_with_classpath com.epicentric.uid.UniqueIDFactory

Section III: Portal Services

317

Creating a Custom Search Connector

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

Step 5: Create Component Descriptors


This step involves creating component.xml filesoften referred to as component descriptorsto prepare your connector for deployment. These files are the mechanism by which various types of Portal components (services, grids, styles, etc.) are described to the Portal deployment system and preconfigured upon deployment. A custom search connector should actually consist of two components, each having its own component.xml file:
a support component containing your ISearchConnector

implementation and all other classes upon which the connector depends; visible from the PortalBean Manager

318

Customizing Federated Search

Creating a Custom Search Connector

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>

Every component.xml file must start with the following declaration:


<?xml version="1.0" encoding="UTF-8"?>

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>:

Section III: Portal Services

319

Creating a Custom Search Connector

component-idA string uniquely identifying this component. This

string must be properly namespaced to ensure uniqueness across the Portal.


component-typeThe literal value of "ModuleTypes", used to

identify shared or support components as well as PortalBean portlets.


"ModuleTypes" components are listed in the server consoles PortalBean

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.

This element is a required child element of

<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

Customizing Federated Search

Creating a Custom Search Connector

<web-deployment-path> Element.

This element is a required child element of

<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.

This element is also a required child element of

<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

Section III: Portal Services

321

Creating a Custom Search Connector

Service Instance Component

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

Customizing Federated Search

Creating a Custom Search Connector

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

identify the version of this instance.

Section III: Portal Services

323

Creating a Custom Search Connector

build-versionString identifying the service instances build; useful in

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.

This element is a child element of

<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

Customizing Federated Search

Creating a Custom Search Connector

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>.

This child element of <service-instance> contains connector properties, as explained next.

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.

idUnique string identifying the connector; for internal rather than

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

hierarchical collection should be searched recursively; ignored unless


supportHierarchicalCollection is true.

Section III: Portal Services

325

Creating a Custom Search Connector

connectorClassnameFully qualified classname of your implementation of the ISearchConnector interface (described in Step 2:

Implement the ISearchConnector Interface on page 311).


vocabFileName of the file described in Step 3: Define the Connectors

Search Field Names on page 316.


vocabFileComponentIDID of the component that contains the file identified by vocabFile. The value of this key must match the value of the component-id attribute of the components <epideploy:component> element. This key, along with the vocabFileComponentType key, enables you to maintain a global list of

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

Customizing Federated Search

Creating a Custom Search Connector

<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>

Section III: Portal Services

327

Creating a Custom Search Connector

<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>

Step 6: Package the Connector for Deployment


You prepare Portal components for deployment by creating component archives, also known as CAR files. A component archive is a JAR file in ZIP format that has an extension of .car. It contains all of the files for one or more Portal components. In the case of a custom search connector, you should create three CAR files: one for the support component, one for the service instance, and one that simply provides a container for the other two. For the connector example described in the preceding sections, you might name the support CAR file SampleSupport.car, the service instance CAR file SampleConnectorService.car, and the containing CAR file SampleConnector.car. The following sections explain how to create each of these CAR files.
See also: Chapter 8, Deploying Site Components, for a general discussion of the Portal deployment system

Support CAR File

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

Customizing Federated Search

Creating a Custom Search Connector

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

CAR File Structure. Table 23: Directory root

/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

Section III: Portal Services

329

Creating a Custom Search Connector

Service Instance CAR File

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)

Container CAR File

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

Customizing Federated Search

Creating a Custom Search Connector

Step 7: Test the Connector


To verify the functioning of your connector in a development or QA environment, deploy it and then use the Federated Search portlet to perform searches against it, as described below.
To deploy your connector and verify its deployment: 1

Use either of these Portal deployment mechanisms:


Import the container CAR file using the Service Manager of the Portal

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.

Section III: Portal Services

331

Creating a Custom Search Connector

To test the search functionality of your connector: 1 2

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

Customizing Federated Search

20
Summary: Audience: Topics:

Using the Content Access Management and Indexing APIs


Explains how to customize the Content Access Management system that ships with Vignette Portal; how to develop a connector for a particular search or indexing engine; and how to develop custom content renderers Java developers responsible for integrating Vignette Portal with a content management or search system

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.

Section III: Portal Services

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

Using the Content Access Management and Indexing APIs

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.

Section III: Portal Services

335

CAM Architecture

Figure 57 illustrates the architecture of the CAM framework.


Figure 57: Content Access Management Architecture
Application layer
Portlet 1 Portlet 2 Application JavaServer Pages

Access API
(com.epicentric.contentmanagement)

CMM layer

Content Management Middleware


Connector API
(com.epicentric.contentmanagement.connectors)

Connector layer
Connector 1 Connector 2 Connector n

Data source layer


Data Source 1 Data Source 2 Data Source n

Folders and Documents


The content in the Data Source layer is organized into a hierarchical structure of folders and documents. Folders can contain either documents or subfolders. Documents can be binary files, HTML pages, images, or other MIME types. Folders and documents can be either read-only or writable. A specialized type of document is a document alias, which is an empty document that links to content that resides remotely. (In the CAM user interface, a document alias is known as a "card.")

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,

and modification date) as well as properties that are optional (document

336

Using the Content Access Management and Indexing APIs

Using the Access API

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

executed for documents at various workflow stages

Using the Access API


The Access API can be divided into four categories: content item interfaces, workflow support, the ContentManager class, and utilities and exceptions. This section discusses each of these categories and provides an example of a simple use of the Access API.

Content Item Interfaces


The base interface of the Access API is com.epicentric. contentmanagement.ContentItem. Content items are either documents (which implement the com.epicentric. contentmanagement.Document subinterface) or folders (which implement the com.epicentric.contentmanagement.Folder subinterface). These interfaces contain basic query methodsfor example, to check whether an item supports custom properties, whether a document can be locked, or whether a folder allows subfolders to be createdas well as accessorsfor example, to retrieve custom properties, the name of a particular item, or the folder for a particular document. Writable documents and folders extend the WritableContentItem interface as well as the appropriate specialized interface (either WritableDocument or WritableFolder). These interfaces contain the action methods, such as the property setters and the methods for creating, deleting, and moving items.

Section III: Portal Services

337

Using the Access API

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

Using the Content Access Management and Indexing APIs

Using the Access API

Utilities and Exceptions


The com.epicentric.contentmanagement.ContentUtils class contains static methods for handling paths, retrieving MIME types and descriptions, and providing other utility functions for the Access API. The Access API includes exceptions for such conditions as insufficient permissions, unsupported capabilities, failure to create or find a particular content item or property, and failure to connect to the Content Management Middleware. In addition, ContentException enables the stack trace of a nested exception to be appended to the stack trace of the current exception.

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"); }

Section III: Portal Services

339

Using the Access API

When the ContentManager object is no longer needed, its close() method should be called to release content management resources:
if (myCM != null) { myCM.close(); }

Here are the previous statements assembled into a simple class:


import java.util.*; import java.io.*; import com.epicentric.user.*; import com.epicentric.contentmanagement.*; import com.vignette.portal.log.*; class CMSample { public static final LogWrapper LOG = new LogWrapper(CMSample); public static void main(String[] args) { String username = "Jean Deer"; try { // Retrieve UserManager. UserManager userManager = UserManager.getInstance(); // Retrieve user from UserManager. User user = userManager.getUser("username", username); // Instantiate ContentManager for this user. ContentManager myCM = ContentManager.getContentManager(user); // Retrieve folder at content management system root. Folder folder = myCM.getRootFolder(); // Retrieve all documents from root folder. Collection c = folder.getAllDocuments(); // Retrieve folder at specified path relative to root. Folder folder2 = myCM.getFolder("/local_drive"); // Retrieve document at specified path relative to root. doc = myCM.getDocument("/movies/ABeautifulMind.doc"); // Make sure doc properties are writable. if (doc.canWriteProperties()) { // Recast doc as a WritableDocument. WritableDocument wa = (WritableDocument)doc.getWritable(); // Set two standard properties. wa.setCategory("Drama"); wa.setPublicationDate(new Date()); // Set two custom properties. wa.setCustomProperty("rating", "R"); wa.setCustomProperty("sweep", "Good"); } } catch (ContentException e) { if(LOG.willLogAtLevel(LogConfiguration.INFO)) {

340

Using the Content Access Management and Indexing APIs

Developing Data Source Connectors

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

Developing Data Source Connectors


The term "data source connector" refers to the collection of Java classes that function together to provide integration between a content repository (data source) and Portal. Connectors determine how much content management functionality is exposed to the Access API. The Connector API is a series of interfaces that describe various capabilities a data source might support. The capabilities of a particular connector depends upon the interfaces that are implemented. For example, among the capabilities that the Portal content repository supports are reading, writing, and searching content; maintaining properties on folders and documents; and tracking workflow tasks and stages. As a result, the connector for the Portal content repository implements each of the interfaces that support these capabilities. If you want to integrate Portal with a data source for which a connector has not already been built, create your own connector by performing these steps:
1 2 3

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.

Section III: Portal Services

341

Developing Data Source Connectors

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

Using the Content Access Management and Indexing APIs

Developing Data Source Connectors

Table 25:

Folder, Document, and Connector Capabilities (Continued) Applies to

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

Connector Interface WritableConnectorFolder2


4

X X

WritableConnectorDocument3 LockableDocument3 WritableLockableDocument5 X X ConnectorHelperDependent Copiable Movable WritableMovable7


6

Checking connector capabilities Querying of workflow stages Writable workflow stages and tasks Creating documents and cards in workflow stage
1

X X X

CapabilityCheckable WorkflowAwareFolder2 WorkflowAwareDocument3

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

Section III: Portal Services

343

Developing Data Source Connectors

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

Using the Content Access Management and Indexing APIs

Developing Data Source Connectors

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

Section III: Portal Services

345

Developing Data Source Connectors

WritableConnectorDocument interfaces, in addition to the base

interfaces, as shown in Figure 59.


Figure 59: Writable Connector

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

Using the Content Access Management and Indexing APIs

Developing Search Engine Connectors

Figure 60:

Writable Workflow Connector


Interface PropertyAwareConnector Interface ConnectorContext

Interface ContextAwareConnector

MyWorkflowConnector

MyWorklfowContext

Interface ConnectorFolder

Interface PropertyAware

Interface ConnectorDocument

MyReadableFolder

MyReadableDocument

MyWritableWorkflowFolder

MyWritableWorkflowDocument

Interface WritableConnectorFolder

Interface WritablePropertyAware

Interface WritableConnectorDocument

Interface WritableWorkflowAwareFolder

Interface WorkflowManageableDocument

Developing Search Engine Connectors


The Indexing API (com.epicentric.indexing) supports accessing a search engine and its collections, querying one or more non-CAM collections (source collections), and retrieving search results that contain metadata. In addition, the Indexing API allows index entries to be added to a designated collection (sink collection) with the desired metadata. Search engine connectors are implementations of the Indexing API. A particular search engine connector is an API bridge, providing the capabilities of a specific search/indexing engine through a consistent API. An indexing connector is responsible for accessing the search engine, translating the query calls to the native search syntax, retrieving the results, and populating the result objects of the Indexing API.

Section III: Portal Services

347

Developing Search Engine Connectors

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

search results are returned based on permissions.


Metadata handlingCAM performs metadata and full-text searches

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

Using the Content Access Management and Indexing APIs

Developing Search Engine Connectors

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

indexes in a search engine.


SearchQuerySearch text, metadata, and any search conditions. SearchResultSetSearch engines response to a query. SearchResultA result within a result set. This object represents the

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

Section III: Portal Services

349

Developing Search Engine Connectors

the hidden ones, use getEntireCollections() on your HiddenCollectionAwareEngine implementation.


See also: Search Engine Connector Configuration on page 353 for information about excluding collections using a configuration property

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

allows indexes to be added.


IndexEntryRepresentation of a document index. This object contains

mutators (setters) of metadata.

350

Using the Content Access Management and Indexing APIs

Developing Search Engine Connectors

Figure 62:

Search + Parsable Search Engine Connector


Interface SearchCollection

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.

Section III: Portal Services

351

Developing Search Engine Connectors

Figure 63:

Search + Unparsable Search Engine Connector


Interface SearchCollection

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.)

API Call Examples


You retrieve a search (or indexing) engine using the SearchManager class, as follows:
SearchEngine engine = SearchManager.getEngine("autonomy");

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

Using the Content Access Management and Indexing APIs

Developing Search Engine Connectors

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(); }

Here is an example of how you add an index to the collection:


URL url = null; IndexCollection index_col = (IndexCollection)collection; try { url = new URL("http://usatoday.com"); IndexEntry entry = index_col.parse(url); index_col.index(entry); } catch (MalformedURLException e) { // report error }

You can delete an index from the collection as follows:


if (result != null) { index_col.delete(result); }

Search Engine Connector Configuration


To enable a search engine connector, the Portal configuration file (PortalInstallDir/config/properties.txt) must contain a number of properties. The following procedure summarizes the properties to add; the

Section III: Portal Services

353

Developing Search Engine Connectors

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...

Add the following property to improve search performance on CAM content:


indexing_engine.engine_id.permissions_filtering=false

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

Using the Content Access Management and Indexing APIs

Customizing Content Rendering

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

Customizing Content Rendering


One of the CAM portlets that ship with Vignette Portal is Story Publisher. This portlet dynamically selects content based on content selection rules, and it renders that content based on display options specified by Portal administrators when instantiating the portlet. NOTE: Story Publisher is a PortalBean portlet (as are all of the other CAM portlets). Story Publisher comes with a default renderer, which accepts input from an administrative GUI that presents a number of display options (see Figure 64). For example, administrators can choose to have the main view display links to a specified number of documents that meet the content selection rules; alternatively, the main view can render part or all of the content for one or more of those documents. Other examples of display options supported by the default renderer are whether to show images associated with documents and whether to include specific properties, such as document title, summary, or publication date.

Section III: Portal Services

355

Customizing Content Rendering

Figure 64:

Default Story Publisher Display Options

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

Using the Content Access Management and Indexing APIs

Customizing Content Rendering

This section explains how to create and deploy custom renderers.


See also:

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

Step 1: Create Custom JSPs


The Story Publisher portlet has three views. These views map to three JSP files as shown in Table 26.
Table 26: View ID FRONT_VIEW FULL_VIEW CONTENT_VIEW Story Publisher Views JSP File Name view.jsp full.jsp content.jsp Description Main view; typically shares a Portal page with other portlets Full-page view; uses all available portlet display space Document detail view; displays a particular document

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.

Section III: Portal Services

357

Customizing Content Rendering

Story Publisher Tags

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:printDocumentURL document="string" inSiteContext="true" | "false" documentIndex="integer"/>

<content:printDocumentImageURL document="string"/>

<content:selectedDocument>

<content:printDocumentContent document="string"/>

The taglib directive for these tags is as follows:

358

Using the Content Access Management and Indexing APIs

Customizing Content Rendering

<%@taglib uri="/beans/storypublisher/jsp/taglib/storypub lisher.tld" prefix="content" %>

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

The following are simple examples of custom renderers.


view.jsp.

This example shows the use of the

<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" %>

Section III: Portal Services

359

Customizing Content Rendering

<!-- 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

Using the Content Access Management and Indexing APIs

Customizing Content Rendering

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; } } %>

Section III: Portal Services

361

Customizing Content Rendering

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

Using the Content Access Management and Indexing APIs

Customizing Content Rendering

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"

Section III: Portal Services

363

Customizing Content Rendering

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">&lt; Prev</a> <% }else{ %> <span class="epi-dim">&lt; Prev</span> <% } %> &nbsp;|&nbsp;<%=end>0?start+1:start%>-<%=end%> of <%=length%>&nbsp; <% if(hasNext){ params = new Hashtable(); params.put("start", String.valueOf(start+range)); %> <a href="<%=bean.getFullViewURL(Screens.FULL_VIEW, params)%>" class="epi-nextPrev">Next &gt;</a> <% }else{ %> <span class="epi-dim">Next &gt;</span>

364

Using the Content Access Management and Indexing APIs

Customizing Content Rendering

<% } %> </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.

This example shows the use of the

<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>

Section III: Portal Services

365

Customizing Content Rendering

<% 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; } } %>

Step 2: Create and Upload the CAR File


When you are finished developing your custom JSPs, create a CAR file of them and then use the server consoles Portal Bean Manager tool to upload them. If you created multiple sets of custom JSPs, create a separate CAR file for each set. Place the following files in the root of the CAR file:
component.xml view.jsp full.jsp content.jsp

366

Using the Content Access Management and Indexing APIs

Customizing Content Rendering

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

component.xml File Structure

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,

Section III: Portal Services

367

Customizing Content Rendering

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

Internationalizing Custom Renderers

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

Using the Content Access Management and Indexing APIs

Customizing Content Rendering

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

Step 3: Update Portal Properties


When you upload a custom renderer, you must also update the following property in the Portal configuration file (PortalInstallDir/config/properties.txt):
com.epicentric.portalbeans.beans.storypublisher.customrenderers = componentid1,componentid2

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

Do not include a space between custom renderer IDs.


See also: Vignette Portal Configuration Guide for discussion of the properties.txt file

Step 4: Restart the Portal Application


This step is required for two reasons: to complete the process of deploying your CAR file and to push the properties.txt file changes to the application server.

Section III: Portal Services

369

Customizing Content Rendering

370

Using the Content Access Management and Indexing APIs

21
Summary: Audience: Topics:

Developing and Deploying Custom Services


Explains what constitutes a Vignette Portal service, how to use the Portal Services API to create a configurable service, and how to develop and deploy service types, service implementations, and service instances Java developers responsible for customizing Vignette Portal

Services and Vignette Portal (below) Developing a Configurable Service on page 372 Service Components on page 374 Deploying Services on page 376

Services and Vignette Portal


The Vignette Portal Services API (com.epicentric.services package) enables you to develop entirely new services. A Portal service is a black boxan abstract placeholder for some functionality whose implementation details are unimportant to its users. Services can have multiple implementations; one implementation can be substituted for another, and the default implementation can be specified. At its simplest, a service does not need to implement or use any of the interfaces or classes in the Services API. Portal considers a "service" to be any class that meets these three requirements:
It is a named singleton. It has a public no-argument constructor. It is identified as a "service" type of class in its component descriptor (component.xml file).

Section III: Portal Services

371

Developing a Configurable Service

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

Developing a Configurable Service


If you want your custom service to be configurable through the Service Manager, implement two interfaces of the com.epicentric.services package: ServiceController and Controllable.
See also: Technical Library on Vignette Connect (http://connect.vignette.com) for API documentation (javadocs) of com.epicentric.services

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

Developing and Deploying Custom Services

Developing a Configurable Service

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.

Section III: Portal Services

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

Developing and Deploying Custom Services

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.

Section III: Portal Services

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

Creating the Component Descriptor


A file named component.xml describes any type of Portal component (service, grid, style, etc.) to Portal. All Portal components share many common component.xml elements. Here is the basic structure of a service component.xml file, or any other Portal component (with required elements and attributes shown in bold):
<?xml version="1.0" encoding="UTF-8"?> <epideploy:component component-id="string" component-type="Service Types"|"Service Implementations"|"Service Instances" 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-type="string" component-id="string"

376

Developing and Deploying Custom Services

Deploying Services

major-version="integer" minor-version="integer" /> <epideploy:detail> ... component-specific detail elements ... </epideploy:detail> </epideploy:component>

Every component.xml file must start with the following declaration:


<?xml version="1.0" encoding="UTF-8"?>

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

appropriately namespaced to ensure uniqueness.


component-typeFor services, one of these literal values: "Service Types", "Service Implementations", or "Service Instances". major-version, minor-version, and build-versionCombination

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

characters; displayed by the Service Manager of the Portal server console.


xmlns:epideploy A required attribute whose value is fixed as shown

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

Section III: Portal Services

377

Deploying Services

Component Details for Service Types

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

Developing and Deploying Custom Services

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>

Here is a brief description of each of these possible child elements of <epideploy:detail>:


<service-implementation-definition>Element that encloses

the child elements defining the service implementation.


<locale-key>Unique ID for the service implementations I18N

property file.
<type-version/>Service type and version being implemented. The

attributes of this element correspond to attributes in the service types


<epideploy:component> element, as follows:

Section III: Portal Services

379

Deploying Services

Service Types <epideploy:component> Attribute component-id major-version minor-version

<type-version> Attribute id major minor

<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

Developing and Deploying Custom Services

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

repeated for zero or more objects associated with the service. An


<indexed-property-set-definition> contains one <propertyset-definition>, which in turn can contain definitions of one or more value properties or service properties. An <indexed-property-setdefinition> has three attributes: a unique key that the service implementation uses to refer to the set, and minimum and maximum

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>

Here is a brief description of each of these possible child elements of <epideploy:detail>:

Section III: Portal Services

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

instance is automatically enabled upon deployment.


<type-id>Component ID for the service type for this instance. <implementation-id>Component ID for the service implementation

for this instance.


<locale-key>Unique ID for the service instances I18N property file. <property-set>Element enclosing a list of properties for this service instance. These properties are a subset of those defined in the <propertyset-definition> element of the service implementation. Although this

element is required, it can be empty.


<property>Child element of <property-set> defining the value for the property identified by its key attribute (which must match the value of the key attribute of one of the <value-property-definition> or <service-property-definition> elements of the instances service

implementation).
Examples

Examples of the component.xml files for services follow.


Service Type.

Here is an example of a service type component.xml file:

<?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

Developing and Deploying Custom Services

Deploying Services

</service-type-definition> </epideploy:detail> </epideploy:component> Service Implementation.

Here is an example of a service implementation

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"

Section III: Portal Services

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

Developing and Deploying Custom Services

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.

Here is an example of a service instance component.xml

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>

Section III: Portal Services

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>

Creating the CAR File


The component archive (CAR file) contains all of the files that a particular service type, implementation, or instance require. The Portal deployment system specifies the directory structure for the CAR file. Figure 66 shows the structure of a typical CAR file for services (types, implementations, and instances).
Figure 66: CAR File Structure for Services

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

File name or type component.xml Java 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

Loaded in database; not copied to the file system.

386

Developing and Deploying Custom Services

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.

Uploading the CAR File into Portal


The CAR file for your service can be uploaded using either of these means:
Import the CAR file using the Service Manager of the Portal server

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

Section III: Portal Services

387

Deploying Services

388

Developing and Deploying Custom Services

Appendices

A
Summary: Audience: Topics: See also:

Vignette Portal Custom JSP Tag Reference


Provides details about all of the custom JSP tags provided with Vignette Portal JSP or Java developers responsible for creating or modifying Vignette Portal components

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

understanding of basic HTML.


Backward compatibility is easier to maintain when tags are used. The logic

within the tags can change, but changes are transparent to your code; they do not affect its operability.

Appendices

391

Web Site Tags

API changes are often made within tag implementations to improve

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.

Web Site Tags


<vgn-portal:defineObjects/>
Defines two implicit JSP variables: portalContext (a request-based instance of the com.vignette.portal.website.enduser.PortalContext class) and LOG (an instance of the com.vignette.portal.log.LogWrapper class). SYNTAX:
<vgn-portal:defineObjects />

ATTRIBUTES: None APPLIES TO THESE COMPONENTS: All

<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>

ATTRIBUTES: None APPLIES TO THESE COMPONENTS: Styles, Secondary Pages

392

Vignette Portal Custom JSP Tag Reference

Web Site Tags

<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.

Required. String defining the data to be converted to a localized format.

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

APPLIES TO THESE COMPONENTS: Styles, Secondary Pages

<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

Web Site Tags

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.

Optional. String to be appended to the localized value.

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.

Required. String containing the parameter to the <vgn-

portal:i18nValue> tag.
encode. Optional. Boolean specifying whether the string value is to be encoded.

APPLIES TO THESE COMPONENTS: Styles, Secondary Pages

394

Vignette Portal Custom JSP Tag Reference

Web Site Tags

<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.

APPLIES TO THESE COMPONENTS: Styles, Secondary Pages

<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" />

SYNTAXTAG ENCLOSING ONE OR MORE PARAMETERS:


<vgn-portal:i18nValue . . .> ...one or more parameter tags... </vgn-portal:i18nValue>

Appendices

395

Web Site Tags

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.

Optional. String to be appended to the localized value.

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

Vignette Portal Custom JSP Tag Reference

Web Site Tags

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.

Optional. Map of key-value pairs to be passed to the secondary page.

APPLIES TO THESE COMPONENTS: Grids

<vgn-portal:includeStyle/>
Outputs the current style. SYNTAX:
<vgn-portal:includeStyle friendlyID="string" args="<%= map%>" panelUID="string" />

ATTRIBUTES:
friendlyID. args.

Required. Case-sensitive, meaningful string identifying the style.

Optional. Map of arguments to be executed with the style.

Appendices

397

Web Site Tags

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.

Required. Case-sensitive, meaningful string identifying the user

segment. APPLIES TO THESE COMPONENTS: Styles, Secondary Pages

<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

Vignette Portal Custom JSP Tag Reference

Web Site Tags

<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

Web Site Tags

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.

Required. List object containing realm IDs.

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

Vignette Portal Custom JSP Tag Reference

Web Site Tags

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

PortletWindowBean instance in a request attribute named portletWindow.


portletFriendlyID.

Optional. Friendly ID of the portlet to be rendered.

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.

Deprecated; do not use.

Deprecated; do not use.

APPLIES TO THESE COMPONENTS: Grids

Appendices

401

Story Publisher PortalBean Portlet Tags

Story Publisher PortalBean Portlet Tags


<content:printDocumentContent/>
Prints to the response the transformed content for the selected document. If Story Publisher caching is enabled for the portlet instance, the content is read from the cache. If the MIME type is "html/text" all text outside of the <BODY> tag is stripped off. SYNTAX:
<content:printDocumentContent document="string" />

ATTRIBUTE:
document.

Required. String identifying the selected

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.

Required. String identifying the selected

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

Vignette Portal Custom JSP Tag Reference

Story Publisher PortalBean Portlet Tags

ATTRIBUTES:
document.

Required. String identifying the selected

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

Story Publisher PortalBean Portlet Tags

</content:viewableDocuments>

ATTRIBUTES: None

404

Vignette Portal Custom JSP Tag Reference

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

Component Descriptor Structure

Component Descriptor Structure


The basic structure of the component descriptor (component.xml file) for all Portal components is the same:
The file must start with the following declaration:
<?xml version="1.0" encoding="UTF-8"?>

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

dependencies must be defined in a child element named <epideploy:required-component/>.

<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

Component Descriptor Structure

</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

Component Descriptor Structure

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.

Child Elements of <epideploy:component>

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

Component Descriptor Structure

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

Detail Elements for Styles, Grids, and Secondary Pages

<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>

Detail Elements for Styles, Grids, and Secondary Pages


For styles, grids, and secondary pages, <epideploy:detail> has one child element: <style-info>.

<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

Detail Elements for Styles, Grids, and Secondary Pages

processing-type="JSP_BASED"|"ACTION_BASED"> <actions> ...list of actions (secondary pages only)... </actions> </style-info>

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

Detail Elements for Styles, Grids, and Secondary Pages

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

Detail Elements for Styles, Grids, and Secondary Pages

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>

Child Elements of <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

Detail Elements for Styles, Grids, and Secondary Pages

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

PRE_DISPLAY (for a display action) or PROCESS (for a process action).


Child Element of <action>

The <action> attribute has one required child element: <class>.

<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

Detail Elements for Style Types and Secondary Page Types

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.

Detail Elements for Style Types and Secondary Page Types


For style types and secondary page types, <epideploy:detail> has one child element: <template-info>. NOTE: The "Grid" type is simply a specialized form of style type.

<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

Detail Elements for Style Types and Secondary Page Types

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

Detail Elements for Style Types and Secondary Page Types

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.

Child Element of <template-info>

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

Detail Elements for Style Types and Secondary Page Types

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 id="string"> ...any number of <action> elements... </group> ...any number of additional <group> elements... </actions>

Child Elements of <actions>

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

Detail Elements for Style Types and Secondary Page Types

type.

Required. Literal identifying the type of the action. Valid values are

PRE_DISPLAY (for a display action) or PROCESS (for a process action).


Child Element of <action>

The <action> attribute has one required child element: <class>.

<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

Detail Elements for Service Types

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.

Detail Elements for Service Types


For service types, <epideploy:detail> has one child element: <service-type-definition>.

<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

Detail Elements for Service Types

Child Elements of <service-type-definition>

<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

Detail Elements for Service Types

<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

implements or extends. For example, a MetaStore service extends the


com.epicentric.metastore.MetaStore class.

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

Detail Elements for Service Implementations

Detail Elements for Service Implementations


For service implementations, <epideploy:detail> has one child element: <service-implementation-definition>.

<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>

Child Elements of <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

Detail Elements for Service Implementations

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

type is being implemented. This element has no child elements.


Syntax
<type-version id="string" major="integer" minor="integer"/>

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

Detail Elements for Service Implementations

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

implementation of the interface or abstract class referred to in the


<interface-class-name> of the service type. For example, a SQL

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

Detail Elements for Service Implementations

<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

elements. Its syntax is as follows:


<configuration-validator-class-name> fully.qualified.ClassName </configuration-validator-class-name>

<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>

Child Elements of <property-set-definition>

The following elements may occur zero or more times within the <property-set-definition> element: <value-property-

426

Deployment Reference

Detail Elements for Service Implementations

definition>, <service-property-definition>, and <indexedproperty-set-definition>.

<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

user interface display purposes.


type.

Required. String that specifies in which data type the system stores the property. The data type is one of the following:

Appendices

427

Detail Elements for Service Implementations

integer (maps to the long data type) decimal (maps to the double data type) boolean date string

Child Elements of <value-property-definition>

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>

Child Elements of <option-list>

<option-list> contains one or more <option> elements.

<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

Detail Elements for Service Implementations

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

Detail Elements for Service Implementations

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.

Child Elements of <service-property-definition>

<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

that the current implementation refers to.


<service-type> has no attributes or child elements. Its syntax is as

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

Detail Elements for Service Instances

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.

Child Element of <indexed-property-set-definition>

<indexed-property-set-definition> contains one, and only one, <property-set-definition>. (See Page 426 for details about the <property-set-definition element.)

Detail Elements for Service Instances


For service instances, <epideploy:detail> has one child element: <service-instance>.

Appendices

431

Detail Elements for Service Instances

<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.

Child Elements of <service-instance>

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

Detail Elements for Service Instances

<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

Detail Elements for Service Instances

Syntax
<property-set> ... any number of <property> elements ... </property-set>

Child Elements of <property-set>

<property-set> contains one or more <property> elements.

<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:

Vignette Portal JavaScript Functions


Provides details about JavaScript functions provided with Vignette Portal HTML, JavaScript, JSP, or Java developers responsible for customizing the Portal end-user site

AJAX Library (below) Generic Functions on page 437 Drag-and-Drop Functions on page 441

Vignette does not support any changes to these functions.

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.

Name of the form Method to be invoked

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.

Name of the form Method to be invoked

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.

URL as a string Method to be invoked

callbackMethod.

EXAMPLE:
new VignettePortal.AJAXClient().sendURL("<%=AJAXUrl%>","<%= autoCompletecallbackFunction %>");

436

Vignette Portal JavaScript Functions

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

Clips this object to a specific size and location. SYNTAX:


clipTo(t,r,b,l,setwidth);

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

Gets this objects height in pixels. SYNTAX:


getHeight();

cm_makeObj.prototype.getLeft

Gets this objects left coordinate in pixels. SYNTAX:


getLeft();

cm_makeObj.prototype.getTop

Gets this objects top coordinate in pixels. SYNTAX:


getTop();

cm_makeObj.prototype.getWidth

Gets this objects width in pixels. SYNTAX:


getWidth();

438

Vignette Portal JavaScript Functions

Generic Functions

cm_makeObj.prototype.hideIt

Hides this object. SYNTAX:


hideIt(no);

cm_makeObj.prototype.moveIt

Moves this object to coordinates (x, y) on the page. SYNTAX:


moveIt(x,y);

cm_makeObj.prototype.setCssClass

Sets this objects style class to a new classname. SYNTAX:


setCssClass(classname);

cm_makeObj.prototype.setHeight

Sets this objects height in pixels. SYNTAX:


setHeight(height);

cm_makeObj.prototype.setLeft

Sets this objects left in pixels. SYNTAX:


setLeft(left);

cm_makeObj.prototype.setTop

Sets this objects top in pixels. SYNTAX:


setTop(top);

Appendices

439

Generic Functions

cm_makeObj.prototype.setWidth

Sets this objects width in pixels. SYNTAX:


setWidth(width);

cm_makeObj.prototype.showIt

Shows this object. SYNTAX:


showIt(o);

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

Vignette Portal JavaScript Functions

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

Column when it is rendered.


absPos.

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

Adds an indicator to this Column object. SYNTAX:


addIndicator(indicator);

Column.prototype.addRow

Adds the specified row to this Column object. SYNTAX:


addRow(row);

442

Vignette Portal JavaScript Functions

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

Renders this Column object as well as its child objects. SYNTAX:


render(left,top);

Column.prototype.setIndicatorLoc

Sets the location indicator of this Column object. SYNTAX:


setIndicatorLoc(l,t,w);

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.

Whether this Row is the last item (1) or not (0).

Row.prototype.addColumn

Adds a column to this Row object. SYNTAX:


addColumn(column);

Row.prototype.addIndicator

Adds an indicator to this Row object. SYNTAX:


addIndicator(indicator);

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

Sets the location indicator of this Row object. SYNTAX:


setIndicatorLoc(l,t,w);

444

Vignette Portal JavaScript Functions

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

Vignette Portal JavaScript Functions

D
Summary: Audience: Topics: See also:

Vignette Portal CSS Reference


Provides details about the CSS type and class selectors used in Vignette Portal and their mapping to theme properties, both in the Fonts and Colors page of the administration consoles and in code HTML, JSP, or Java developers responsible for the look and feel of Vignette Portal sites

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

Font and Color Settings in the Administration Consoles


Portal administrators tend to think of fonts and colors in terms of Portal theme settings, rather than in terms of CSS classes, because fonts and colors can be set for Portal themes through the administration consoles. Figure 67 shows the fonts and colors that administrators can set for a theme (Components >> Themes >> Theme Name >> Fonts and Colors within the administration consoles).

Appendices

447

Font and Color Settings in the Administration Consoles

Figure 67:

Fonts and Colors Page of the Administration Consoles

448

Vignette Portal CSS Reference

Vignette Portal Type Selectors

Vignette Portal Type Selectors


Table 29 lists the type selectors defined for Portal. You do not need to apply CSS classes to these HTML elements unless you want to modify their basic display properties. The Theme Property column refers to the Fonts and Colors page shown in Figure 67.
Table 29: Type Selectors Defined for Vignette Portal Theme Property HTML Property (in UI) Theme Property (in Code)

HTML Element Body font settings BODY, PRE, TR, TD, TH, P

font-family font-size color font-style

Body Font Normal Size Body Text None. Hardcoded (normal). None. Hardcoded (0px). None. Hardcoded (1em). None. Hardcoded (bold).

font.body.face font.body.normal fontColor.bodyText N/A N/A N/A N/A

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

background-color Input Field Background

Appendices

449

Vignette Portal CSS Classes (Class Selectors)

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

Vignette Portal CSS Classes (Class Selectors)


Table 30 lists the CSS classes defined for Portal, their corresponding theme properties (or theme settings), and their labels in the Fonts and Colors page (Figure 67 on page 448). The following conventions are used in this table:
Classes shown in italics are descendant selectors. Classes shown in bold get their primary values from classes of the same

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

font-family font-size color font-style

Body Font Normal Size Body Text

font.body.face font.body.normal fontColor.bodyText

None. Hardcoded (normal). N/A

450

Vignette Portal CSS Reference

Vignette Portal CSS Classes (Class Selectors)

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

background- Page Background color

bgColor.page

font-family font-size color

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

font-family font-size color

epi-fontLg, wsui-font-large

font-family font-size color

epi-headline (Figure 68)

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

Vignette Portal CSS Classes (Class Selectors)

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

CSS Class epi-trailOn, wsui-trail-current (Figure 69)

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

background- None. Currently pegged to color Content Block Background.

452

Vignette Portal CSS Reference

Vignette Portal CSS Classes (Class Selectors)

Table 30:

Mapping of CSS Classes to Theme Properties (Continued) HTML Property Theme Property (in UI) Theme Property (in Code)

CSS Class Confirmation Messages epi-ok, wsui-ok, portlet-msg-success

font-family font-size color

Body Font Normal Size Confirmation Messages

font.body.face font.body.normal fontColor.confirmation

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

Vignette Portal CSS Classes (Class Selectors)

Table 30:

Mapping of CSS Classes to Theme Properties (Continued) HTML Property Theme Property (in UI) Theme Property (in Code)

CSS Class Pagination links

(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

background- Button Background color

454

Vignette Portal CSS Reference

Vignette Portal CSS Classes (Class Selectors)

Table 30:

Mapping of CSS Classes to Theme Properties (Continued) HTML Property Theme Property (in UI) Theme Property (in Code)

CSS Class Form fields

(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).

N/A N/A N/A N/A N/A N/A N/A

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

Vignette Portal CSS Classes (Class Selectors)

Table 30:

Mapping of CSS Classes to Theme Properties (Continued) HTML Property Theme Property (in UI) Theme Property (in Code)

CSS Class Data table settings

(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

epi-dataTable TH, wsui-table TH, portlet-table-header TH, portlet-table-header TD

color

fontColor.rowHead bgColor.rowHead 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). 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

N/A fontColor.rowHead N/A fontColor.rowHeadSorted bgColor.rowHeadSorted text-decoration.linkMenu

background- Sorted Column Header color Background textdecoration Underline menu and pagination links (none/underline).

456

Vignette Portal CSS Reference

Vignette Portal CSS Classes (Class Selectors)

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

CSS Class epi-dataTable TD, wsui-table TD, portlet-table-body TD

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

N/A N/A N/A N/A N/A N/A N/A

(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

Vignette Portal CSS Classes (Class Selectors)

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

CSS Class epi-dataTableLite TH

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

padding epi-dataTableLite TH A color textdecoration epi-dataTableLite TD border-top

N/A fontColor.rowHead N/A bgColor.dataTable

border-right

bgColor.dataTable

padding-top paddingbottom padding-left paddingright epi-dataTableLite epi-padRight epi-dataTableLite epi-embeddedTable TD paddingright border padding

N/A N/A N/A N/A N/A N/A N/A

458

Vignette Portal CSS Reference

Vignette Portal CSS Classes (Class Selectors)

Table 30:

Mapping of CSS Classes to Theme Properties (Continued) HTML Property Theme Property (in UI) Theme Property (in Code)

CSS Class Data trees

(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

fontColor.rowHead bgColor.rowHead bgColor.dataTable

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).

N/A N/A fontColor.rowHead N/A N/A N/A N/A N/A N/A

Appendices

459

Vignette Portal CSS Classes (Class Selectors)

Table 30:

Mapping of CSS Classes to Theme Properties (Continued) HTML Property Theme Property (in UI) Theme Property (in Code)

CSS Class Special header rows

(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

background- Odd Row Background color

bgColor.rowOdd

460

Vignette Portal CSS Reference

Vignette Portal CSS Classes (Class Selectors)

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

Vignette Portal CSS Classes (Class Selectors)

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

CSS Class epi-BG2 epi-BG3 epi-BG4 epi-font1

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

font-family font-size color

epi-font3

font-family font-size color

epi-font4

font-family font-size color

A.epi-link1:link, A.epi-link1:visited

color textdecoration

A.epi-link1:active, A.epi-link1:hover

color textdecoration

462

Vignette Portal CSS Reference

Vignette Portal CSS Classes (Class Selectors)

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

CSS Class A.epi-link2:link, A.epi-link2:visited

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

Mapping of Theme Settings to CSS Classes

Mapping of Theme Settings to CSS Classes


Table 31 shows the relationship of a themes font and color settings to the Vignette Portal CSS classes. The labels shown in Figure 67 on page 448 correspond to the Theme Setting column of this table.
Table 31: Mapping of Theme Settings to CSS Values CSS Value Affected CSS Classes

Theme Setting Font Face and Size Body Font

{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}

Small Size Large Size

{font-size: n} {font-size: n}

464

Vignette Portal CSS Reference

Mapping of Theme Settings to CSS Classes

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

Theme Setting Title, Trail Font

Page Title Size

{font-size: n}

Section Title Size

{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

Page & Section Titles

{color: n}

Appendices

465

Mapping of Theme Settings to CSS Classes

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

Error & Warning 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

Other Links: Active, Hover

{color: n}

Underline links

{text-decoration: underline}

466

Vignette Portal CSS Reference

Mapping of Theme Settings to CSS Classes

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 menu and pagination links {text-decoration: none/underline}

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}

{color: n} {background-color: n} {background-color: n} {background-color: n}

epi-chromeHeader epi-chromeHeader epi-chromeBG epi-chromeBorder

{background-color: n} {background-color: n} {border: 1px solid [n]} {background-color: n}

epi-pageBG epi-blockBorder, epi-block epi-block General <hr> element, epi-lineBreak

{color: n} {background-color: n} {color: n} {background-color: n}

epi-button, portlet-form-button epi-button, portlet-form-button epi-input, portlet-form-input-field epi-input, portlet-form-input-field

Appendices

467

Mapping of Theme Settings to CSS Classes

Table 31:

Mapping of Theme Settings to CSS Values (Continued) CSS Value Affected CSS Classes

Theme Setting Data Table Colors Data Tables Border

{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

{color: n} {background-color: n} {color: n} {background-color: n} {color: n}

Special Row Background

{background-color: n}

Highlighted Row Text Highlighted Row Background Footer Row Text Footer Row Background Odd Row Background

{background-color: n} {background-color: n} {color: n} {background-color: n} {background-color: n}

Even Row Background

{background-color: n}

Generic Font Faces and Size Font 1 {font-family: n} epi-font1

468

Vignette Portal CSS Reference

Mapping of Theme Settings to CSS Classes

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

Mapping of Theme Settings to CSS Classes

Figure 68:

Sample Implementation for the epi-headline CSS Class

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

Vignette Portal CSS Reference

Mapping of Theme Settings to CSS Classes

Figure 69: Classes

Sample Implementation for the epi-trail and epi-trailOn CSS

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 &raquo; <span class="epi-trailOn">Search Results</span> </h1> </td> </tr> <tr><td valign="top" height="18"><hr size="1" /></td></tr> </table>

Appendices

471

Mapping of Theme Settings to CSS Classes

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

Vignette Portal CSS Reference

Mapping of Theme Settings to CSS Classes

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">&laquo; Prev</span> | 1-5 of 47 | <a href="#" class="epi-nextPrev">Next &raquo;</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

Mapping of Theme Settings to CSS Classes

<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:

Sample Implementation for the epi-buttonLink CSS Classes

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

Vignette Portal CSS Reference

Mapping of Theme Settings to CSS Classes

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

Mapping of Theme Settings to CSS Classes

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

Vignette Portal CSS Reference

Mapping of Theme Settings to CSS Classes

<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

Mapping of Theme Settings to CSS Classes

Table 32: CSS Class

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-dataTableTD, wsui-TableTD epi-dataTable.epi-padRight

epi-dataTable.epi-embeddedTable TD

Figure 76:

Sample Implementation for the epi-dataTree CSS Class

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

Vignette Portal CSS Reference

Mapping of Theme Settings to CSS Classes

<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

Mapping of Theme Settings to CSS Classes

<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

Vignette Portal CSS Reference

Mapping of Theme Settings to CSS Classes

Table 33: CSS Class

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 TH epi-dataTree TH a epi-dataTree.epi-padRight

epi-dataTree.epi-embeddedTable TD

Figure 77: Sample Implementation for the epi-rowSpecial1, epirowFooter, epi-rowOdd, and epi-rowEven CSS Classes

Appendices

481

Mapping of Theme Settings to CSS Classes

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:

Sample Implementation for the epi-block CSS Classes

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

Vignette Portal CSS Reference

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

epi-button-current a epi-button-current-rollover epi-button-current-rollover tablerollover epi-button-normal epi-button-normal tablerollover epi-button-rollover a

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

Vignette Portal CSS Reference

E
Summary: Audience: Topics: Note:

Compatibility with Version 4.x


Outlines coding differences between versions 7.x and 4.x of the Portal product. JSP and Java developers who have experience with 4.x versions of the Portal product

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

NOTE: It is best not to use a combination of 4.x and 7.x components.

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.

Page Display Secondary Page


The Page Display secondary page can display Java standard, WSRP, and PortalBean portlets in version 7.x, but only PortalBean portlets in version 4.x. Therefore, if you customized the Version 4.x Page Display secondary page, you can continue to use it with Version 7.x to display PortalBean portlets. However, if you want to be able to display Java standard and WSRP portlets as well, you must move to the 7.x version of the Page Display secondary page and reapply your customizations.

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

Compatibility with Version 4.x

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

JSP Programming Constructs

JSP Programming Constructs


Various JSP programming constructs have changed:
When developing a Portal 7.x-style JSP page, the PortalContext must be made available as a default page variable by adding the <vgnportal:defineObjects/> custom tag to each page. All process JSPs should be removed and replaced by process actions. (See

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:checkTicket/> can be completely removed from JSPs.

Its function is replaced by the JSP Secure Access servlet filter.

<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

page types and style types.


The cache-control directive [ response.setHeader("CacheControl","no-cache"); ] can be removed from JSP pages, as this

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

Compatibility with Version 4.x

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()

methods consistent with the behavior of the


<vgn-portal:i18nValue/> and <mod:i18nValue> tags. To include

line breaks in text, create separate keys for each line.


The isHTML Boolean of the getValue() method and of the <vgnportal:i18nValue/> and <mod:i18nValue> tags no longer have any effect. The two getValue() method signatures that include this parameter have been deprecated. Prior to version 7.2, isHTML determined whether <span> tags would be added to surround text that could not be localized. Now, the <span> tags are always added in that circumstance.

Appendices

489

Changes Affecting PortalBeans

Changes Affecting PortalBeans


As of version 7.0, the PortalBean technology is being replaced by Java standard portlets (as specified by JSR 286). The PortalBean APIs are continuing to be supported for maintenance of existing PortalBeans (formerly called "modules"); new development should use Java standard portlets. While the PortalBean APIs have not been enhanced appreciably in version 7.x (and will not be enhanced in future Portal releases), the following changes introduced in version 7.0 affect or may affect existing PortalBeans:
Due to site presentation framework changes related to the order in which components are invoked, the sendRedirect() method on PortalPageContext no longer works within a PortalBean JSP view. The

temporary workaround is to use the (deprecated)


com.epicentric.common.website.RedirectUtils.printRedire ct() method. To avoid creating a "flash" effect in the browser (caused by the grid momentarily displaying before the redirect occurs), use RAW_VIEW as the views ID. Note that sendRedirect() continues to work when

called within a Java class rather than a JSP view.


The Portal 7.x framework namespaces request parameters in URLs. For example, directory=test is now something like javax.portlet.prp_abf64b17a31de3fca5de9464f576efa0_dire ctory=test. As long as the supported methods for generating portlet

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

Compatibility with Version 4.x

Changes Affecting PortalBeans

request.getParameter(), it will not be able to retrieve the

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

Changes Affecting PortalBeans

492

Compatibility with Version 4.x

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

Portal Developers Guide

493

allow-guest-access attribute, component.xml 202, 260, 416 alt text, and internationalization 161

permission-checking APIs 267 Autonomy 308, 349, 351

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()

.class files, deploying 141, 142, 199,

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

Portal Developers Guide

495

structure 199204 See also components, Vignette Portal component-id attribute,


component.xml

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

createPortletURI() method 235 createTemplateProcessURI()

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

Portal Developers Guide

497

description attribute, components 200,

377, 408 descriptors, XML See component.xml files;


validation.xml file DHTML grids and 81 navigation styles and 55 Portal support for 18 portlet display and 117119 See also JavaScript diaglets 378, 380, 422, 425 disabilities and accessibility 161 display actions, secondary page 38 display requests, secondary page 3639, 97, 110, 172 distributed environment 269, 271 Div object constructor, JavaScript 437 dob user property, Vignette Portal 212 documents Content Access Management 336, 355366 MetaStore 250 searching and indexing 305332, 347355 doesAccountExist() method 262 Dojo Java standard portlets and 216 navigation style and 178 PortalBean portlets and 239, 240 styles, secondary pages, and 183, 184 Domino integrations 20 double validation rule 129 doublerange validation rule 128 DoubleValueSearchTerm class 315 downloading See deployment drag-and-drop JavaScript functions 441 dragElementID variable 66 duplicating

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

encoding and decoding 170


endLevel variable 57, 59 endString attribute, I18N tag 160 EndUserFormBean class 122, 167 EndUserUtils class 187, 267

Entity API 255258


entity_management.xml file 211, 255 epi_html tags 44, 488 epi-build attribute, component.xml

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

federated search See search, federated


federated_search_master_vocabul ary.xml file 309, 316, 317 FederatedSearchService class 309,

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

Portal Developers Guide

499

friendly URI, of menu items 35, 60 FRONT_VIEW, Story Publisher 357 full view, Story Publisher 357, 359, 362, 366

getProperty() method, MenuItemNode 63 getServiceInfo() method 373 getSubCollections() method,

federated search connectors 312

G
GenericAuthenticator class 261 GenericBeanView class, PortalBeans

getTarget() method 60 getTitle() method 60 getView() method, WebConnector and

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

element 380, 425


<implementation-id> element 382,

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

Portal Developers Guide

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

isSpacer() method 60 is-system attribute, component.xml

202, 412, 416


isSystemAdministrator() method

268
isUserAuthorized() method 268 isUserInRole() method 210 isValidCollection() method,

federated search connectors 313


isViewModeAllowed() method 268 isVisible() method 64

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

Portal Developers Guide

503

major-version attribute, component.xml

minor-version attribute, component.xml

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

NORMAL portlet window state 176, 226

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

NT authentication 21 numbers, internationalizing 163

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

Portal Developers Guide

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 descriptor 243


PortalBean interface 243

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

Portal Developers Guide

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

read-only connectors, Content Access Management 342, 345

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

Portal Developers Guide

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

<service-implementationdefinition> element 379, 423 <service-instance> element 382, 432 <service-property-definition>

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

Portal Developers Guide

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

UIDRegistry class 255, 256, 258 UltimateDestination interface 298

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

85, 89, 191, 392


<vgn-portal:i18nElement> tag

161162, 392, 394, 396


<vgn-portal:i18nFormat/> tag 163,

393
<vgn-portal: i18nFormattableValue/> tag

164, 393
<vgn-portal:i18nParam/> tag 162,

164, 394

Portal Developers Guide

513

<vgn-portal:i18nParams/> tag 163,

viewableDocuments custom JSP tag

164, 395
<vgn-portal:i18nValue/> tag

160166, 392, 394, 395


<vgn-portal: includeNavigation/> tag 58,

85, 91, 396


<vgn-portal: includePageContent/> tag

reference 397 using 79, 82, 85, 91


<vgn-portal:includeStyle/> tag 85,

90, 188, 397


<vgn-portal:inSegment> tag 255,

257, 398
<vgn-portal: insertPortletContent/> tag

69, 174, 398, 401


<vgn-portal:onRenderFailure> tag

69, 174, 175, 399, 401


<vgn-portal:onRenderSuccess> tag

reference 398, 399, 401 using 69, 174


<vgn-portal: pageContentTitle/>

tag 85, 90, 399


<vgn-portal:realmSelector/> 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

warning logging level 185 wasSelected() method 60, 61

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

Portal Developers Guide

515

516

Index

You might also like