Download as pdf or txt
Download as pdf or txt
You are on page 1of 392

Open Text Training Session: 300

Livelink Builder
Fundamentals
Course
Copyright
Copyright 1995-2004 by Open Text Corporation. This documentation and the software described in it are
copyrighted with all rights reserved. The software is subject to the terms of a license agreement. Under the
copyright laws, this manual or the software may not be copied in whole or part, without the written consent of
Open Text Corporation, except in the normal use of the software itself, or to make a backup copy. The same
proprietary and copyright notices must be affixed to any permitted copies as were affixed to the original. This
exception does not allow copies to be made for others, whether or not sold. You may use the software on any
computer, but extra copies cannot be made for this purpose. Under the law, copying includes translating into
another language or format.

Open Text Corporation is the owner of the trademarks Open Text, Livelink®, Livelink Intranet, Livelink Change
Agents, Change Agents, Livelink Channels, Livelink Discussions, Livelink Explorer, Livelink Library, Livelink
Collaboration, Livelink Project Collaboration, Livelink SDK, Livelink Search, Livelink Spider, Livelink Tasks,
Livelink Workflow, Livelink Channels, Livelink Forms, Livelink LiveReports, Livelink Prospectors, Livelink X-
Active, and Livelink Activators. Other trademarks and trade names in the documentation are owned by other
companies and are used for product and company identification and information only.

©1995-2004 Open Text Corporation. All rights reserved.

185 Columbia Street West


Waterloo, Ontario
N2L 5Z5
Canada
(519) 888-7111

Credits: Howard Pell, Dave Slater, Marie Lindsay, Dee Keyser and Rahmat Costas. Many thanks to the other
Open Text staff who assisted with the creation of this course.

Course 92-300, Release 2.1

Last modified on 2004-Mar-23


Welcome to the Livelink Builder Fundamentals Course
Overview and Objectives:
Builder Fundamentals provides an in-depth understanding of the functionality of Livelink
Builder, the application development component of the Livelink SDK. By the end of this
course, you will know how to:

• Create modules to package your customizations for easy installation and upgrades
• Write code using OScript, Livelink's programming language
• Create request handlers to process new functionality
• Add new types of items to be stored and managed by Livelink
• Add new interface components and modify the current interface
• Integrate your code into the Livelink object system in supported ways

Prerequisites:
• Programming knowledge and experience (especially object-oriented languages such as
C++)
• Application development knowledge and experience
• Basic knowledge of HTML for Web interface customization
• Strong knowledge of the Livelink interface and functionality

Livelink Builder Fundamentals Course Page i


Table of Contents

Typographical Conventions Used in this Manual


Document Conventions:

You will see the following conventions used in this manual:

Convention Indicates

Monospaced text Fragment or block of code – for example:


integer k = 1

featureName Describes a component of OScript code in a syntax description

<snip> Indicates that a segment of code has been omitted for brevity

Italics • Emphasis – for example:


Your password is case sensitive.

Bold • Term being introduced for the first time – for example:
Livelink is a web-based system that enterprises use for
intellectual capital management.

• Name of a button or other interface element that you use while


performing an operation – for example:
Choose Info from the menu.

Underline • The name of a hypertext link that you click while performing an
operation – for example:
Locate the group you want, then click its Select link.

“Quoted string” • The name of a particular Livelink item, folder on disk, or other
element used in an example or exercise – for example:
Locate the “Sample Docs” folder on your C: drive.

Page ii Open Text Corporation


Table of Contents
Section 1: Introduction

1.1 Livelink ...................................................................................................................... 1-3

1.2 The Livelink SDK...................................................................................................... 1-4

1.2.1 The Livelink API (LAPI)............................................................................... 1-4

1.2.2 Livelink Builder ............................................................................................. 1-4

1.3 The Builder Fundamentals Course............................................................................. 1-5

1.4 Upgradeable Customization....................................................................................... 1-7

1.4.1 Supported Customizations ............................................................................. 1-7

1.5 Summary .................................................................................................................... 1-8

1.6 Resources in Addition to this Course ........................................................................ 1-8

Section 2: How Requests are Processed

2.1 Livelink’s Architecture .............................................................................................. 2-3

2.2 Focusing on the Livelink Server ................................................................................ 2-5

2.2.1 Livelink Modules ........................................................................................... 2-5

2.3 Livelink Request Handlers......................................................................................... 2-7

2.4 Summary .................................................................................................................... 2-8

2.5 How Requests are Processed ..................................................................................... 2-9

Section 3: The Builder as a Development Environment

3.1 The Builder as a Miniature Livelink Server .............................................................. 3-3

3.2 Object Terms.............................................................................................................. 3-5

3.3 The Builder Tools ...................................................................................................... 3-7

3.4 Manipulating Objects: The Object Browser Window ............................................... 3-9

3.5 OSpace Commands.................................................................................................. 3-11

Livelink Builder Fundamentals Course Page i


Table of Contents

3.6 Object Commands.................................................................................................... 3-13

3.7 Working with Features............................................................................................. 3-15

3.8 Feature Commands .................................................................................................. 3-17

3.9 Inheritance and Inheritance Rules............................................................................ 3-19

3.9.1 Inheritance Rules ......................................................................................... 3-19

3.10 Searching for Code .................................................................................................. 3-21

3.11 The Inspector Tool................................................................................................... 3-23

3.12 Getting Help............................................................................................................. 3-25

3.13 Summary .................................................................................................................. 3-26

3.14 Exercise.................................................................................................................... 3-27

Section 4: Setting Up a Module

4.1 Livelink Modules ....................................................................................................... 4-3

4.1.1 The Kernel Module, Core Modules, and Optional Modules ......................... 4-3

4.1.2 Module Components...................................................................................... 4-5

4.2 When a Module is Installed ....................................................................................... 4-7

4.3 Working with OSpaces .............................................................................................. 4-9

4.4 The WebModule Object........................................................................................... 4-11

4.5 Enabling and Initializing Objects............................................................................. 4-15

4.6 The Configure Request Handler .............................................................................. 4-17

4.7 Registering Your Request Handlers......................................................................... 4-19

4.8 The Module.INI File ................................................................................................ 4-21

4.9 Installing Your Module............................................................................................ 4-23

4.10 Summary .................................................................................................................. 4-24

4.11 Exercise.................................................................................................................... 4-25

Section 5: OScript

Page ii Open Text Corporation


Table of Contents

5.1 The Use of OScript in Livelink.................................................................................. 5-3

5.2 The Script Editor........................................................................................................ 5-3

5.3 Compiling Scripts ...................................................................................................... 5-5

5.4 Saving Scripts ............................................................................................................ 5-5

5.5 Other Script Commands............................................................................................. 5-7

5.6 The Debug Window and the Debugger ..................................................................... 5-9

5.7 General OScript Syntax ........................................................................................... 5-10

5.8 Variables and Datatypes .......................................................................................... 5-11

5.9 Operators.................................................................................................................. 5-13

5.10 Control Structures .................................................................................................... 5-15

5.11 Three Flavors of For Loops ..................................................................................... 5-17

5.12 Datatype Notes......................................................................................................... 5-19

5.12.1 Strings .......................................................................................................... 5-19

5.12.2 Lists.............................................................................................................. 5-21

5.12.3 Assocs .......................................................................................................... 5-23

5.12.4 Records and RecArrays................................................................................ 5-25

5.12.5 DAPINodes .................................................................................................. 5-25

5.13 Built-in Functions .................................................................................................... 5-27

5.13.1 DAPI Package.............................................................................................. 5-27

5.13.2 Online OScript Reference ............................................................................ 5-27

5.14 Objects ..................................................................................................................... 5-29

5.15 Globalizing Objects ................................................................................................. 5-33

5.16 Creating Your Own Functions ................................................................................. 5-35

5.17 Summary .................................................................................................................. 5-38

5.18 Exercise.................................................................................................................... 5-39

Livelink Builder Fundamentals Course Page iii


Table of Contents

Section 6: Making a Request Handler

6.1 Reminder of How Request Handlers Work ............................................................... 6-3

6.2 Subclassing a Request Handler Object ...................................................................... 6-5

6.3 Creating a Request Handler for New Code................................................................ 6-7

6.4 Key Request Handler Features................................................................................... 6-9

6.5 Request Handlers with Input Arguments................................................................. 6-11

6.6 “Making It Go”—the Execute() Method ................................................................. 6-13

6.7 WebLingo Files—a Quick Introduction .................................................................. 6-17

6.8 Testing a Request Handler ....................................................................................... 6-19

6.9 Summary .................................................................................................................. 6-20

6.10 Exercise.................................................................................................................... 6-21

Section 7: Taking Advantage of WebLingo

7.2 Example Livelink Pages ............................................................................................ 7-3

7.1 Writing WebScripts ................................................................................................... 7-5

7.1.1 Defining a Webscript ..................................................................................... 7-5

7.1.2 Calling a Webscript........................................................................................ 7-7

7.2 Special Characters...................................................................................................... 7-9

7.3 Compiling and Debugging WebLingo Files ............................................................ 7-11


7.4 Cascading Style Sheets (CSS) ................................................................................. 7-13

7.5 Overriding Cascading Style Sheets.......................................................................... 7-15

7.6 Overriding Livelink Pages ....................................................................................... 7-17

7.5 Summary .................................................................................................................. 7-18

7.6 Exercise.................................................................................................................... 7-19

Section 8: Plugging into the Livelink Interface

8.1 Ways to Hook Your Work into Livelink ................................................................... 8-3

Page iv Open Text Corporation


Table of Contents

8.2 The Navigation Menus............................................................................................... 8-3

8.3 How the Menu Commands are Identified.................................................................. 8-5

8.4 Navigation Menu Caching and URLs........................................................................ 8-7

8.5 Defining the Menu Command’s Result .................................................................... 8-9

8.7 Summary .................................................................................................................. 8-10

8.8 Exercise.................................................................................................................... 8-11

Section 9: Overview of Livelink Node Objects

9.1 How Items are Stored in Livelink.............................................................................. 9-3

9.2 DAPI and the Node Objects....................................................................................... 9-5

9.3 How Item Commands Are Processed: The LL Request Handler ............................. 9-7

9.4 Identifying the Item Type: Global Variables for SubTypes ...................................... 9-9

9.5 Extend Without Overriding: ApplTypes.................................................................. 9-11

9.6 Item Type “Engine”: LLNode Object...................................................................... 9-13

9.7 Item Type Interface “Driver”: WebNode Objects ................................................... 9-17

9.8 Summary .................................................................................................................. 9-20

9.9 Exercise.................................................................................................................... 9-21

Section 10: Controlling the Commands for a Node Type

10.1 Node Commands...................................................................................................... 10-3

10.2 Using Existing Commands with Your Node ........................................................... 10-5

10.3 Controlling Tabs On Your Node Type’s Info Page ................................................. 10-9

10.4 Controlling the Add New Item Menu for a Node Type......................................... 10-11

10.5 Summary ................................................................................................................ 10-12

10.6 Exercise.................................................................................................................. 10-13

Section 11: Storing Additional Node Data

11.1 Storage Options........................................................................................................ 11-3

Livelink Builder Fundamentals Course Page v


Table of Contents

11.2 Using the DTree ExtendedData Column to Store Node Data.................................. 11-5

11.3 Passing Data from Request to Output...................................................................... 11-7

11.4 How the Add Item Page is Created.......................................................................... 11-9

11.5 Getting the Additional Data Off the Form............................................................. 11-13

11.6 Getting the Additional Data into the Database ...................................................... 11-15

11.7 Summary ................................................................................................................ 11-18

11.8 Excercise ................................................................................................................ 11-19

Section 12: Adding a New Node Command

12.1 Details: How Commands Are Called....................................................................... 12-3

12.2 Passing Data from Request to Output...................................................................... 12-7

12.3 Doing the Work: The Action Object’s _SubclassExecute()and WebLingo ............ 12-9

12.4 Tying the Action Object to the Interface with a WebNodeCmd Object................ 12-11

12.5 Using Action Objects to Override Existing Commands ........................................ 12-15

12.6 Summary ................................................................................................................ 12-16

12.7 Exercise.................................................................................................................. 12-17

Section 13:The Chain of Events in Servicing a Request

13.1 The Start of the Chain .............................................................................................. 13-3

13.2 The APISRV OSpace (The Start of the Chain) ....................................................... 13-5

13.3 The WEBDSP OSpace............................................................................................. 13-7

13.4 The WEBNODE OSpace......................................................................................... 13-9

13.4.1 The LL Object............................................................................................ 13-11

13.4.2 The WebNode Object ................................................................................ 13-15

13.5 Summary ................................................................................................................ 13-16

13.6 Exercise.................................................................................................................. 13-17

Section 14: Modifying the Navigation Menus

Page vi Open Text Corporation


Table of Contents

14.1 The Navigation Menus............................................................................................. 14-3

14.2 Let the Hunt Begin................................................................................................... 14-5

14.3 The dashboard.html File .......................................................................................... 14-7

14.4 The LivelinkNavigationCallbackSubsystem ......................................................... 14-11

14.4.1 The Items Method ...................................................................................... 14-11

14.4.2 The GetItems Method ................................................................................ 14-11

14.5 The Execute Method of Home LivelinkNavigationCallback ................................ 14-13

14.6 A New Orphan ....................................................................................................... 14-15

14.7 WEBLL and LivelinkNavigationCallback ............................................................ 14-17

14.8 Your Orphan .......................................................................................................... 14-19

14.9 A Final Word on Navigation Menu Items – Removing Them .............................. 14-19

14.10 Summary ................................................................................................................ 14-20

14.11 Exercise.................................................................................................................. 14-21

Appendix A: Internationalization

Appendix B: Creating Online Help for Your Module

Appendix C: List of Pkg and Util Objects

Appendix D: Glossary

Appendix E: Quiz

Livelink Builder Fundamentals Course Page vii


Table of Contents

Notes:

Page viii Open Text Corporation


Section 1: Introduction
Overview:

As we start the course, we want to make sure you understand what Livelink is, what the
Livelink SDK is, and what the goals are for this course.

Objectives:

By the end of this section, you will be able to:

• Identify where the Livelink SDK fits into the overall Livelink product

• Define differences between Livelink Builder and the Livelink API and when to use which
one

• Determine the overall objectives for this course

• Understand the general areas of customization that are supported by Livelink Builder

Livelink Builder Fundamentals Course 92-300 04Feb11 Page 1-1


Section 1: Introduction

Figure 1-1: About Livelink page

Page 1-2 Open Text Corporation


Section 1: Introduction

1.1 Livelink

Livelink is a web-based system that enterprises use for


collaborative knowledge management. Livelink is
designed to handle the work of large enterprises, with
thousands of people and vast amounts of data. With
Livelink, people can use their web browsers to easily get
work done.

With Livelink, you can:

• Publish and share documents and other work in an


organized, central location

• Work on projects as a team, even if the team members


are geographically dispersed

• Manage and simplify business processes by creating


and using workflows

• Communicate news and other information to other


members of a group or to an entire enterprise,
regardless of its size

• Track the flow of work and the lifecycles of work via


audit trails and version control

Livelink Builder Fundamentals Course Page 1-3


Section 1: Introduction

1.2 The Livelink SDK

The Livelink SDK (Software Development Kit) provides


two tools for customizing Livelink:

1.2.1 The Livelink API (LAPI)

LAPI (The Livelink Application Programmers Interface)


allows developers to bypass the Livelink interface and To learn more about
write Visual Basic, C, C++, Java, or .Net code to access the LAPI, see the Livelink API
Livelink engines. Developer’s Reference in
the Builder online help.

If you do not need to modify the Livelink interface, but


instead want to access and update the Livelink database
from custom or third party applications, you can use the
Livelink API (Application Programming Interface), called
LAPI.

1.2.2 Livelink Builder

Livelink Builder (which we simply call “the Builder” in


this course) is an application development environment for
customizing Livelink. If you want to change the look and
feel of the interface, or if you want to modify or add to the
basic functionality, you need to use the Builder.

The basic tasks in customizing Livelink include:


• Creating a module in which to store your
customizations. If you do this properly, your
enhancements will be easy to install and maintain.
The Livelink Builder is
• Creating request handlers, LLNodes, WebLingo files, required for extending
Livelink functionality. LAPI
and other module components to implement new alone can enhance but not
functionality or change the look and feel. extend the way Livelink
works. You can use both of
• Overriding existing components to change the existing these tools to customize
Livelink.
functionality.

The Builder is the subject of this course.

Page 1-4 Open Text Corporation


Section 1: Introduction

1.3 The Builder Fundamentals Course

The Builder includes an interface for creating and


manipulating objects, a programming language, and more.
We’re assuming that you already know how to use other
programming languages and application development
environments. During the course, we will:

• Show you how to use the Builder’s interface.

• Introduce you to Livelink’s programming language,


OScript.

• Explain the basics of how Livelink’s object system


works and how its code was implemented.

• Most importantly: Teach you a development


methodology for your customizations.

Our primary goal for the course is to give you the


understanding you need to:

• Create new features in a supported way.

• Understand how particular features of Livelink were


implemented, so that you can reuse and enhance them.

When you work with the Builder, you can see and
manipulate the objects that create Livelink’s functionality.
The greatest area of complexity in doing development with
the Builder is trying to understand and maneuver in this
large set of code. You need to know what kinds of
customizations are easy, what are hard, and which are
supported when you upgrade to new releases. We will lay
out the guidelines in this course.

Livelink Builder Fundamentals Course Page 1-5


Section 1: Introduction

The Navigation
Menus

The
Function/Info
menu

Livelink
Nodes

Figure 1-2: Sample Areas for Livelink Customization

Page 1-6 Open Text Corporation


Section 1: Introduction

1.4 Upgradeable Customization

Many Livelink enhancements can be implemented so that


they are upgradable as new versions of Livelink are
released. There is a base set of objects and a development
methodology that Open Text has committed to support. By
following the development methodology (as explained
throughout this class) and orphaning the supported objects,
most enhancements will be compatible with future Livelink
versions.

1.4.1 Supported Customizations

These are the principal types of customizations that Open


Text has committed to support:

• Adding a module to Livelink*

• Creating new request handlers to implement new


functionality*

• Adding new commands to the Navigation Dropdown


menus*

• Adding a new type of item (LLNode) to Livelink*

• Storing additional data by adding schema to the


Livelink database or by using the DTree table’s
ExtendedData column*

• Extending and overriding the functionality of existing


Livelink nodes*

• Adding sections to the About Livelink page

• Adding context sensitive help for a new module

• Adding sections to the Livelink Administration page

• Adding a workspace to Livelink

*
We will cover this topic in class, and give you a basis for exploring the other customizations. You will find
more information about the other topics in the product documentation.

Livelink Builder Fundamentals Course Page 1-7


Section 1: Introduction

1.5 Summary

• Livelink is an enterprise-wide, collaborative knowledge


management system.

• The Livelink Builder is a modular, object oriented


development environment for customizing Livelink.

• Livelink comprises modules, which makes Livelink


easy to customize and maintain.

• When approaching customization, it is important to


implement changes in a manner that will allow them to
be upgraded later.

• During this course, we’ll teach you a development


methodology for creating your enhancements in a way
that is easily installed and upgraded.

1.6 Resources in Addition to this Course

The Livelink Builder includes extensive documentation,


including:

• The Livelink Module Development Guide

• The OScript Language Reference and Built-in Package Index

• The Livelink Builder Developer’s Guide

We will be using some of this documentation during the


course. The Open Text Publications department is in the
process of creating additional tech notes and other SDK
documentation.

The Open Text Knowledge Center contains product


information and “user spaces” for customers, including
areas devoted to the Livelink SDK.

In addition to this course, the Open Text Technical


Education department is in the process of creating various
workshops on technical topics, including workflow
customization, forms customization, and more.

Page 1-8 Open Text Corporation


Section 2: How Requests Are Processed
Overview:

At the heart of every Livelink transaction lies a request handler object containing a set of
code for processing a URL sent from a user’s web browser. This section focuses on the
concepts behind the architectural components of Livelink and the lifecycle of a request
handler.

Objectives:

By the end of this section, you will be able to:

• Identify the main components of a Livelink module, the


main unit of customization

• Describe how Livelink uses request handlers to process


requests

• Trace the path of execution of a request from a Web


browser to the server and back

Livelink Builder Fundamentals Course 92-300 04Feb11 Page 2-1


Section 2: How Requests Are Processed

Web browser
Web browser Web browser Web browser

Web server

Livelink server

Database External File Store

Figure 2-1: Livelink’s architecture

Page 2-2 Open Text Corporation


Section 2: How Requests Are Processed

2.1 Livelink’s Architecture

The key components to a Livelink installation include:

• web browsers on each user’s workstation, for viewing


data and issuing requests in the form of URLs

• a web server for processing URLs and calling Livelink


sever code for URLs directed to Livelink.

• the Livelink server code, which processes the URL to


determine what function to execute and sends
commands to the DBMS

• a relational database management system (DBMS),


which stores the Livelink data in a database

• a directory for storage of externally stored files (if the


external file storage option is chosen)

Livelink Builder Fundamentals Course Page 2-3


Section 2: How Requests Are Processed

Web browser
Web browser Web browser Web browser

Web server

opentext.ini file

Livelink CGI

Modules
Other executables
Livelink server
module.ini file

WebLingo
objects files and
support files

Database

Figure 2-2: Livelink server components

Page 2-4 Open Text Corporation


Section 2: How Requests Are Processed

2.2 Focusing on the Livelink Server

As the Livelink Server is started, Livelink uses a file called The opentext.ini file is
opentext.ini to initialize the system. The opentext.ini file described in detail in the Help
pages on the Administration
stores various startup and configuration parameters, such section.
as:

• The database connection information

• The ports on which to listen for requests When a web server


receives a URL containing a
process to perform, rather
• Settings regarding maximums and minimums, formats than just a request to “serve”
and debugging an HTML page, it redirects
the request to a CGI
(Common Gateway
• Most importantly for this course: A list of setup Interface) such as the
parameters specifying which modules to open Livelink CGI. The web server
must be configured to map
certain segments of a URL
string (such as “Livelink” in
2.2.1 Livelink Modules “http://xx.opentext.com/
Livelink/livelink”) to the
corresponding CGI code.
The code that drives each major functional area of Livelink
is stored in a module. You’ll write your own modules when
you customize Livelink. Modules are designed to:

• Make it easy to install, remove, and upgrade areas of


functionality, including customizations

• Decrease development time


As in all object based
• Allow VARs and developers to package their Livelink systems, an object is a set of
enhancements. functions and values which a
developer has defined to
Each module comprises: represent one element of the
overall functionality—for
example, all the code and
• A set of objects containing the programs and other other information required to
code that drives the functionality create and manipulate a
document.

• A set of WebLingo files for dynamically generating the A WebLingo file is an HTML
interface for the functionality (optional) file containing embedded
OScript. OScript is Livelink’s
programming language. The
• A set of images, help files, and other support files OScript in the file is
(optional) processed to dynamically
generate HTML pages that
reflect system data.
• An INI file defining the configuration parameters for
the module

Livelink Builder Fundamentals Course Page 2-5


Section 2: How Requests Are Processed

?func=user.edituser&userID=5644

Web Browser User


Web Server

Dynamically Generated
HTML File
1
Livelink CGI

$WebDsp.
2
RequestHandlerSubsystem
Object
Dispatch() method
fRegistry = <’admin.adminfactories=#180025f2,…
‘user.edituser’=#59000194, …>

4
edituser.html
WebLingo EditUser Request Handler
File Object Database
Execute() method
fHTMLfile string ----‘edituser.html’
3

Figure 2-3: Example of how a request handler is processed

Page 2-6 Open Text Corporation


Section 2: How Requests Are Processed

2.3 Livelink Request Handlers

Each URL that is sent to Livelink from a web browser


contains a call to a request handler. A request handler is
an object that implements a Livelink CGI function (i.e.,
“…livelink?func=…”). Here are the steps taken when the
Livelink CGI receives a request:

1. The Livelink CGI executes a particular method of a A feature is a string,


particular object, called the $WebDsp.Request number, script or other value
HandlerSubsystem.Dispatch() method. The request that is stored as a component of
an object. A method is a
handler that is being called is identified in the URL by feature of a Livelink object that
the string following the question mark (for example, contains a function written with
“…?func=user.edituser…”, where user.edituser is the OScript. An attribute is any
feature of an object that is not a
request handler). method, such as a string, date,
or integer.
2. The request handler object is found by searching the
A subsystem contains a
RequestHandlerSubsystem object’s registry of registry of related objects that
request handlers. This registry is populated at startup. Livelink uses to quickly locate
the object it needs to perform a
particular function. For example,
3. Certain methods of the request handler object are the Request Handler subsystem
executed, most notably the Execute() method. These allows the Dispatch() method to
quickly locate a particular
methods contain calls to perform any database request handler.
transactions needed to gather or input data. The
Execute() method sometimes calls methods of other
objects to do its work. Any data that is gathered is
stored in features of the request handler object.

4. After processing the Execute() method, the request handler


determines what sort of interface should be the result of the
request: a new dynamically generated HTML page, an error
message, or a redirection to another web page.

5. For a dynamically generated HTML page, the request


handler specifies which WebLingo file should be used to
generate the page. Livelink processes the OScript
embedded in the HTML page, displaying data from the
database by referring to the features of the request handler
in which it was stored (see step 3).

As you enhance Livelink, you will write code to create new


request handlers and to take advantage of existing request
handlers.

Livelink Builder Fundamentals Course Page 2-7


Section 2: How Requests Are Processed

2.4 Summary

• The principal architectural components of a Livelink


installation are a web server, a Livelink server, and a
database managed by a relational database management
system.

• The Livelink server code is organized into modules,


which makes Livelink easier to upgrade and enhance.
Each module contains a set of objects (whose attributes
and methods form the functionality of the module),
some WebLingo files for defining the interface, some
other support files, and an INI file for module
installation.

• When the Livelink server is started, it reads the


opentext.ini file to initialize various configuration
parameters and to open and initialize the installed
modules.

• All URLs sent to the Livelink server contain calls to


request handler objects. When a call is sent to the
Livelink CGI, the Livelink CGI runs a Dispatch()
method to locate the request handler. The request
handler runs a series of methods, most notably an
Execute() method, to perform the requested function.
During the process, it may execute transactions against
the database to input or gather data. The request
handler then determines the response to be made to the
user and builds an HTML page of results.

• As you work to customize Livelink, you will create new


modules to store your work. You will both create new
request handlers and use existing request handlers as
you create new and customize existing Livelink
functionality.

Page 2-8 Open Text Corporation


Section 2: How Requests Are Processed

Livelink Builder Fundamentals Course


Student Exercises

Welcome to the exercises! We assume that some of you attending this course would prefer
step-by-step details as you practice, that some of you would prefer to just experiment, and
that most of you would prefer something in between. So each exercise begins with a
summary of what we recommend you do at the top, then a detailed list of the actions to take.
You can glance at the summary and follow it, or you can follow each step. We recommend
that you read through each exercise before following the step-by-step details so that you can
better understand what is required. If you like to just experiment, please do, but please do the
exercise first — each exercise builds upon the previous one.

Notes:

• The variable LLHOME is used throughout these exercises to represent the Livelink
installation directory on your computer. If you cannot find this directory, please ask the
instructor. Please write it here __________________________________________

• In all cases spelling counts. Inside methods, Livelink is case insensitive except for string
comparisons; however, outside methods, always consider things are case sensitive.

• Pay particular attention to the data types of features, especially of Dynamic features.

Legend:

Direction Example

Commands are indicated by THIS TYPEFACE. EDIT the method.

Interface elements (buttons, fields, menu items) are CHOOSE Inspect from the Tools menu.
indicated in bold.

Object and feature names are indicated by this EDIT LLNode.Execute() to include the new code.
typeface.
SET fName = contact
String values and code samples also use .fFilesToCopy = {'two'}
this typeface.

Livelink Builder Fundamentals Course Page 2-9


Section 2: How Requests Are Processed

2.5 How Requests Are Processed

Here are the components of a thread of execution for a


request handler. Can you put them in order? (Without
looking back at the manual?) You may want to use some
items more than once.

1. A 2. 3. 4. 5. 6. 7. 8. 9. 10.A

A Web Browser User B Web Server C Database D Livelink CGI

F Dynamically Generated
HTML File

E $WebDsp.
RequestHandlerSubsystem
Object
Dispatch() method
fRegistry -----…<’admin.adminlogin=#900014b,…
> ---------- ‘user.edituser’=#22000194, …>

Page 2-10 Open Text Corporation


Section 3: The Builder as a Development Environment
Overview:

As you get ready to create a new module, you need to understand the basics of the Builder’s
interface and functionality. In this section, we’ll show you the Builder tools for working with
objects, searching for items, and examining item values.

Objectives:

By the end of this section, you will be able to:

• Set up a development environment for doing Livelink


customization

• Use the Object Browser window to peruse objects,


create objects, and create object features

• Understand the inheritance of features between objects

• Locate objects, features, and script content with the


Search tool

• View the results of code fragments and objects using


the Inspector tool

• Locate the information you need in the online help

Livelink Builder Fundamentals Course 92-300 04Feb11 Page 3-1


Section 3: The Builder as a Development Environment

Web browser
Web browser Web browser Web browser

Web server

Livelink Builder

Livelink server

Database

Figure 3-1: How the Livelink Builder replaces the Livelink server during development

Page 3-2 Open Text Corporation


Section 3: The Builder as a Development Environment

3.1 The Builder as a Miniature Livelink Server

As you start Livelink development, you need to set up a


development environment on a server running NT server or
NT workstation:

1. Install Livelink on an NT system. Your NT system


must have a web server and a Livelink server, plus a
connection to a Livelink database (which can be on the
same NT server or on another server). When you launch the
Builder, the startup code checks
2. Install the Builder. When you install the Builder, you to see whether the Livelink
are prompted to specify the Livelink installation to server process is running. If it is
running, you’ll be prompted with
which you want to add the Builder’s files; choose the the message “Service
Livelink installation you’ve defined as your ServiceName is running. Do
development system. you wish to shut down the
service, continue in read only
mode, or quit the Builder?”
When you launch the Builder, the Builder acts as the Normally, you’ll choose
Livelink server—it is able to process requests sent from “Shutdown.”
web browsers. Whereas the Livelink server is multi- If you use continue you are in a
threaded and designed to handle large numbers of read only state and cannot
transactions, the Builder is single-threaded and designed to modify anything.
help you test and debug your code.

Remember that after you create a module in your


development environment, you can install it on any
Livelink system, on any supported server platform.

Livelink Builder Fundamentals Course Page 3-3


Section 3: The Builder as a Development Environment

Object
Root object OSpace A

Orphan object

OSpace B

OSpace C

Figure 3-2: Livelink Object Tree

Page 3-4 Open Text Corporation


Section 3: The Builder as a Development Environment

3.2 Object Terms

Livelink is an object-based system. There is underlying


code, written mostly in C++, that you cannot access, but the
majority of the code is contained in features of objects in
OSpaces.

OSpace A set of objects stored in a file, including


a root object, the root object’s descendants
(called an object tree), and often some
orphan objects.

Object A set of features which represent one


element of the overall functionality, such
as a set of file management routines.

Root object The object at the very top of an object


tree. There is one root object per OSpace.

Parent object The object that is directly above an object


in an object tree, from whom an object
inherits features.

Child object An object directly below another object in


an object tree, which inherits features
from its parent. If you are an expert in
object-oriented theory, note that
Orphan object A child object which is not stored in the we use the terms “class” and
same OSpace as its parent. If an OSpace “subclass” loosely. Livelink is
actually a prototype-based
contains an orphan, the OSpace containing system, where any object can be
the orphan’s parent must be opened before used as the prototype for
the OSpace containing the orphan. another object.

Class object An object containing some base


functionality that is reused and augmented
by the children of that object, which
children are often called subclasses.

Feature A script (small program), string, number,


or other value. Script features are called
methods, and features of other values are
called fields or attributes.

Livelink Builder Fundamentals Course Page 3-5


Section 3: The Builder as a Development Environment

The Debug window

The Object Browser

The Search Tool

The Inspector

The Debugger

The Script Editor


Figure 3-3: The Builder tools

Page 3-6 Open Text Corporation


Section 3: The Builder as a Development Environment

3.3 The Builder Tools

Here’s a quick overview of the tools that comprise the


Builder. You’ll be using all of them during the course:

Debug For viewing debug and other


window output. Lists messages sent to it by
the Echo() OScript function.

OSpace For viewing, creating, and


Browser managing objects and their
features. Lists all open OSpaces in
the current Livelink installation.

Script Editor For viewing, creating and editing


scripts written with OScript. Can
also be used as a text editor for
any sort of text-only file (such as a
WebLingo file).

Debugger For debugging methods,


WebLingo files, and other scripts
written with OScript. Allows you
to step through a script as it
executes, set breakpoints, and
more.

Inspector For examining the contents of


features and of variables in
executing scripts. Especially
useful when the value is of a
complex datatype, such as a list or
Assoc.

Search tool For locating objects, attributes,


and script contents that contain a
particular string.

Livelink Builder Fundamentals Course Page 3-7


Section 3: The Builder as a Development Environment

Browsing
Preference

Locked
OSpace

Features Pane
(see feature
Expanded
details later in
OSpace
this section)

Selected Selected
object’s object’s ID
OSpace number

Figure 3-4: The Object Browser Window

Page 3-8 Open Text Corporation


Section 3: The Builder as a Development Environment

3.4 Manipulating Objects: The Object Browser Window

The Object Browser tool is a developer’s “home base”


inside the Builder. It lists all of the objects in all of the open
OSpaces and allows you to:

• view objects and features

• create and modify OSpaces, objects, and features

Some of the mechanics:

• Click the expand/contract symbol next to an OSpace or


object to see its children.

• Right mouse click an object or OSpace to see a list of


actions you can perform against that item

There are several commands under the OSpace, Browser,


Object, and Feature menus for working with OSpaces,
objects, and their features. We’ll discuss many of them in
class, but we recommend that you take a look at and
experiment with these commands at your leisure.

Livelink Builder Fundamentals Course Page 3-9


Section 3: The Builder as a Development Environment

Figure 3-5: The OSpace Menu

# OSpace dumped on
m {'kernel'}
I {#1,&INVALID MAP[0]}
N Suggestions Root
f Documentation
s
#ifdef DOC

Put your documentation here

#endif
sEND
f Globals
v #101
f Startup
s
// Initialize globals object
$Suggestions = .Globals.Initialize()
sEND
I {#108,#1}
N Exercises
f Tester

Figure 3-6: Sample from an OSpace Export File

Page 3-10 Open Text Corporation


Section 3: The Builder as a Development Environment

3.5 OSpace Commands

Right-click an OSpace or select the OSpaces menu to


display a set of commands for working with OSpaces. The
File menu also contains commands for working with
OSpaces.

New The New OSpace command opens a dialog


OSpace box for creating a new OSpace (see Section
4).

Open The Open OSpace command opens an input


OSpace file dialog box for selecting an OSpace to
open.

Close The Close OSpace command closes the


OSpace selected OSpace, automatically saving any
changes made to that OSpace.

Lock/Unlock The Lock OSpace and Unlock OSpace


OSpace commands toggle the read-only status of the
OSpace.

Properties The Properties command displays basic


information about the OSpace, such as the
path to its file and the OSpaces it is dependent
upon.

Save Choosing the Save command with a Browser Important: The Save
window active causes all changes you’ve command saves to disk only if
the Browser window is active;
made to any OSpace to be saved to disk.
if another window (such as the
script editor) is active, the Save
Export Choosing the Export OSpace command command only registers
OSpace causes a text file of the OSpace to be created. changes to the active item, and
This is essential for backing up your work and that only to memory.
in case your original OSpace file (which is
binary) becomes corrupted. Preferences
control how the export file is named. Save
and export often.
After importing an OSpace,
Import You can recreate an OSpace from an you must run BuildOspace()
OSpace exported file by choosing the Import OSpace and SetRequestHandlers().
command and selecting the DMP file from a We’ll explain these later.
dialog box. The DMP file will be imported into
the unlocked OSpace you have selected

Livelink Builder Fundamentals Course Page 3-11


Section 3: The Builder as a Development Environment

Figure 3-7: The Object Menu

Page 3-12 Open Text Corporation


Section 3: The Builder as a Development Environment

3.6 Object Commands

Right-click an object or select the Object menu to display a


set of commands for working with objects. The File menu
also contains commands for working with objects.

New Child/ The New Child and New Orphan commands


New Orphan create a new object (see Section 4).

Browse The Browse command opens a second object


browser window and displays the object in
context with all of its siblings.

Delete Object The Delete Object command deletes the


selected object. (See “Inheritance” later in this
section.)

Properties The Properties command displays basic


information about the object, including its
ancestry.

Duplicate The Duplicate Object command creates an


Object object that is a twin sibling (in inheritance
terms) of the object.

Add to The Add to Globals command creates a global


Globals variable for the selected object. (See
Section 5.)

Search The Search command opens a search window


with the “This object” option selected. (See
Section 3.10.)

Create The Create Feature command creates a new


Feature feature in the object

Livelink Builder Fundamentals Course Page 3-13


Section 3: The Builder as a Development Environment

Attribute:
stores default
date format

Method: Formats
date using
fDefFormat
feature

Figure 3-8: Features—Attributes and Methods

Page 3-14 Open Text Corporation


Section 3: The Builder as a Development Environment

3.7 Working with Features

An object is a set of features grouped together for a


specific purpose (for example, a menu driver, a set of
handy scripts, a set of scripts and features for controlling a
type of item, etc.).

A feature is, quite simply, a value, given a name and stored


as a component of an object. Features can be dynamically
typed in Livelink, which means that you can store a date in
them one moment, and a string the next moment.

Livelink developers tend to think of two basic kinds of


features:

• those that are scripts (routines written in OScript, also


called methods)

• those that are not scripts, but strings, dates, recArrays,


object references, or other values (called value
features, fields, or attributes)

When a new object is created, it inherits all of the features


of its parent. You modify the new object by overriding and
adding features.

Livelink Builder Fundamentals Course Page 3-15


Section 3: The Builder as a Development Environment

Figure 3-9: New Feature submenu of the Object menu

Figure 3-10: Feature menu

Select a feature to
see its value at the
bottom of the window

Figure 3-11: Quickly seeing the value of a selected feature

Page 3-16 Open Text Corporation


Section 3: The Builder as a Development Environment

3.8 Feature Commands

The Object menu and the Feature menu (and the context
menu, which appears when you right-click a feature)
display several commands for working with features.

New Feature The New Feature command is used to create a


new feature in the selected object. (see Section
4).

Change The Change Type to command allows you to


Type to enter a value for the feature that is of a different
data type, by clearing the currently stored value
and preparing to show you an editor for the type
you selected.

Edit Feature The Edit Feature command opens an editor for


editing the feature. (Double-clicking the feature
has the same effect.) (See Section 4.)

Browse The Browse command is available only for


object reference features (discussed in Section
4). This command opens an object browser
window and displays the referenced object.

Inspect The Inspect command opens an inspector


To quickly see the
window and displays the selected feature. (We value of a feature, you
will discuss the Inspector window in more detail can click it and look in
in Section 4.) the lower right of the
Object Browser
window.
Delete The Delete Feature command deletes the
Feature selected feature. Inheritance rules play a role
here — see the Inheritance and Inheritance
Rules topic later in this section.

Duplicate The Duplicate Feature command creates a copy


Feature of the feature, in the same object.

Run Script The Run Script command executes the selected


method.

Livelink Builder Fundamentals Course Page 3-17


Section 3: The Builder as a Development Environment

A x=5

x=5 x=5 All objects


B C inherit the
features of their
parents
x=5 x=5 x=5
D E F

G x=5 H x=5 I x=5 J x=5 K x=5

A x=5
When an object is
overridden, all
B x=5 C x=10 descendants of the
object inherit the
changes
x=5 x=10 x=10
D E F

G x=5 H x=5 I x=10 J x=10 K x=10

A x=60
When an inherited
feature has already
B x=60 C x=10 been overridden it no
longer re-inherits
changes from its parent
x=60 x=10 x=10
D E F

G x=60 H x=60 I x=10 J x=10 K x=10

Figure 3-12: Inheritance Rules

Page 3-18 Open Text Corporation


Section 3: The Builder as a Development Environment

3.9 Inheritance and Inheritance Rules

An icon next to each feature in the Browser window


displays the inheritance status of the feature:

Inherited feature a feature inherited from the parent You can clear the
checkboxes at the top
that has not been modified in the of the features list to
object filter out the types of
features you do not
Overridden a feature inherited from the parent want to see at the
moment.
feature that has been modified in this object

New feature a new feature for this object that


does not exist in the parent object

3.9.1 Inheritance Rules

• When a feature is added to an object, the children of the


object automatically inherit the feature.

• When a feature is modified, its descendants


automatically inherit the modifications. Except: If an
inherited feature of an object has already been
overridden, and that same feature is then modified at
the parent (or other ancestor), the changes are not
inherited by the object (or its descendants).

• When an inherited feature is deleted, its value is cleared


and a new value is automatically re-inherited from its
parent. (This is a good way to cancel modifications to a
feature.)

• When a new feature is deleted, it is deleted for all


descendants of the object, regardless of whether the
feature has been modified by one of the descendants.

Livelink Builder Fundamentals Course Page 3-19


Section 3: The Builder as a Development Environment

Contents of list
depends on type
of item you’re
searching for;
double-click to
open found item

Figure 3-13: The Search Window

Page 3-20 Open Text Corporation


Section 3: The Builder as a Development Environment

3.10 Searching for Code

Using the Search tool, you can search for:

• fragments of OScript in methods

• values of other features

• features by name

• objects by name

Across:

• one object

• an object and all its descendants

• an OSpace

• all OSpaces

To use the Search tool:

1. With an object or OSpace selected (if desired),


choose OSpace Search from the Tools menu to open
and use the Search window.

2. As found items appear in the list in the lower half of


the window, you can double-click to open them.

Livelink Builder Fundamentals Course Page 3-21


Section 3: The Builder as a Development Environment

Object number and


name of currently
selected feature

Value of currently
selected feature
Feature
dragged
into the list

Object
dragged
into the
list

Figure 3-14: The Inspector Window

Page 3-22 Open Text Corporation


Section 3: The Builder as a Development Environment

3.11 The Inspector Tool

You can use the Inspector tool to:

• Type a fragment of OScript to see the result (for example, you


can type the name of a global variable to see whether it is
defined as you expect)

• Display the contents of a feature and watch it change as you


debug a script which assigns values to that feature

The Inspector Tool is especially helpful for viewing the


contents of recArrays and other multi-value features,
because it displays their contents in a nested hierarchical
list.

To use the Inspector tool:

1. Choose Inspector from the Tools menu to open the The values listed in
Inspector Browser window, or with a feature the Inspector window are
selected, choose Inspect from the Features menu. direct references to
features. This means that
if you change the feature
2. To add a new expression: either (a) in the value in the Inspector,
uppermost textbox, type a fragment of code whose you are changing the
value stored in the
result you wish to see, or (b) drag a feature or object feature.
from a features list into the lower half of the
Inspector window and the select the Eval button.

3. Click the Store button to save changes made to a


feature.

4. Click a row of the list to re-evaluate its value (for


example, if a script is executing), or choose Refresh
from the Inspector menu to refresh all expressions.

5. When you save or close the inspector tool you will


be prompted for a path and name of a file to store
the data. You can open this file later and see the
same variables and their values.

Livelink Builder Fundamentals Course Page 3-23


Section 3: The Builder as a Development Environment

Figure 3-15: The Builder online help index

Page 3-24 Open Text Corporation


Section 3: The Builder as a Development Environment

3.12 Getting Help

The Builder includes online reference and developer


documentation, available by choosing Builder Help Topics
from the Help menu or by choosing the Livelink Builder
Help program item from your desktop’s Start menu.

The online help is presented in HTML and PDF format.

Livelink Builder Fundamentals Course Page 3-25


Section 3: The Builder as a Development Environment

3.13 Summary

• Before you use the Builder, you first need to set up a


development environment on an Windows system.
When you run the Builder, the Builder acts as the
Livelink server, which allows you to test and debug
your work.

• Livelink is an object-based system. The objects that


drive the Livelink functionality are stored in OSpaces.
Each OSpace contains a hierarchy of objects, starting
with a root object. An OSpace can also contain orphans,
objects whose parents reside in a different OSpace.

• Each object (except for an OSpace’s root object)


inherits all of the features of its parent object. You add
and override features of the child object to create new
functionality. Object based systems allow developers
to affect changes to large parts of code by adding and
modifying features of one object—since all the
descendants of the object will usually inherit those
changes.

• The Builder’s Object Browser window is used to view,


create, and otherwise manipulate OSpaces and objects.
The OSpaces and their objects are listed in the left pane
of the window, and the features of a selected object are
listed in the right pane of the window.

• The Search Tool lets you look for a particular string


anywhere in the Livelink OSpaces. You can search for
objects and features by name, and you can search the
contents of features.

• The Inspector Tool lets you examine the contents of


features and test fragments of OScript code, which can
be very helpful when debugging.

Page 3-26 Open Text Corporation


Section 3: The Builder as a Development Environment

3.14 Section 3 Exercise

3.14.1 Part A. Familiarize Yourself with the Builder Tools

Try the Search and Inspector tools.

□ 1. LAUNCH the Livelink Builder. OPEN the Search


window.
How: Tools menu → OSpace Search.

□ 2. SEARCH for all objects containing the text


“subsystem”.
How: Search For → Object Names. In → All
OSpaces. Containing subsystem CLICK Search.

Livelink lists of all the objects with names containing


the string “subsystem” in all OSpaces.

□ 3. LOCATE and DOUBLE-CLICK the


RequestHandlerSubsystem object.

An OSpace Browser window opens, showing the


RequestHandlerSubsystem object. (This is the
subsystem we discussed in the previous section).

□ 4. CLICK the temporary child object (the one with a


number as a name) below the
RequestHandlerSubsystem object.

□ 5. What feature has been overwritten in this temporary


object? __________________

□ 6. Now look at the fRegistry feature, this is where all


the request handlers in Livelink are registered.
DOUBLE-CLICK fRegistry to open an editor for it.

□ 7. In what format is the information presented? (Be


sure you are looking at the temporary child of the
RequestHandlerSubsystem object and not the
RequestHandlerSubsystem object itself.)
__________________

□ 8. CLOSE the editor for the fRegistry feature, RIGHT-


CLICK the fRegistry feature, and select Inspect. (Give

Livelink Builder Fundamentals Course Page 3-27


Section 3: The Builder as a Development Environment

Livelink a moment to complete your request, as this


feature contains many elements.)

□ 9. What are some differences between editing and


inspecting a feature? _______________

□ 10. LOCATE the Execute() method of the


user.edituser request handler within the
fRegistry inspector window. (How: While still
inspecting the fRegistry feature, SCROLL DOWN to the
user.edituser request handler and CLICK the “+”
symbol to expand its features, including Execute().)
This is the method we discussed during this section.
Later in the course, if you have a spare minute, you
may want to read through this script and other request
handler Execute() methods.

□ 11. CLOSE the Inspector, new OSpace Browser and


Search windows.

3.14.2 Part B. Browsing Around

□ 1. LOCATE LLIAPI : LLIApi Root : LLNode.


How: In the OSpace Browser window, NAVIGATE to the
LLIAPI OSpace and EXPAND the LLIAPI Root object.
FIND the LLNode object (a child of LLIAPI Root).

□ 2. What do red leaves indicate within an OSpace?


_____________________

□ 3. How many direct (don’t count grandchildren)


children (including orphans) does the LLNode object
have? _______

□ 4. EXPAND the object named Folder under the LLNode


object. Is there a WorkFlowAttachments object as a
child of the Folder object? If not, try selecting the
Inheritance radio button on the upper left corner of
your OSpace Browser.

□ 5. In what OSpace does the WorkFlowAttachments


object reside?______________

□ 6. How many features of the WorkFlowAttachments


object have been overwritten?____

Page 3-28 Open Text Corporation


Section 3: The Builder as a Development Environment

□ 7. How many features of the WorkFlowAttachments


object are new? ______

□ 8. Which direct children (including orphans) of the


LLNode object have new features (if any)? ______

Livelink Builder Fundamentals Course Page 3-29


Section 3: The Builder as a Development Environment

Notes:

Page 3-30 Open Text Corporation


Section 4: Setting Up a Module
Overview:

The first work you do in the Livelink Builder should be to set up a module to contain your
customizations. Modules make your work easy to package and move to production
environments, and are easily created in Livelink.

Objectives:

By the end of this section, you will be able to create and


install a new module. In the process you’ll learn how to:

• Locate the key modules in a standard Livelink


installation

• Describe what a module does during its installation


(and with what objects)

• Orphan, enable, and initialize objects

• Orphan key objects for module installation and register


them with the appropriate “subsystem” if necessary

Livelink Builder Fundamentals Course 92-300 04Feb11 Page 4-1


Section 4: Setting Up a Module

Figure 4-1: The top of the Install Modules page, showing installed modules

Figure 4-2: The bottom of the Install Modules page, showing modules that
can be installed

Page 4-2 Open Text Corporation


Section 4: Setting Up a Module

4.1 Livelink Modules

There is a Livelink module created for each of the main


functional areas of Livelink.

Modules are designed to:

• Make it easy to install, remove and upgrade


customizations

• Decrease development time

• Allow VARs and developers to package their Livelink


enhancements

4.1.1 The Kernel Module, Core Modules,


and Optional Modules

• There is a Kernel module on which all other modules


depend. It contains core Livelink code and does not
appear in the Install Modules page.

• There is a set of core modules that are automatically


installed when you install Livelink.

• There are optional modules written by Open Text


Corporation, third party developers, and other Livelink
Builder users.

Livelink Builder Fundamentals Course Page 4-3


Section 4: Setting Up a Module

Module
ini file
OSpace files for deriving functionality:
WebModule object
RequestHandlerGroup object
ospace Request Handler object

html WebLingo (HTML) files:


create.html
update.html
support browse.html

Support files:
help node.gif
28_node.gif

toc.txt HTML files for online help:


n_additem.html
n_deleteitem.html
Figure 4-3: The module directory structure
n_listitems.html

Page 4-4 Open Text Corporation


Section 4: Setting Up a Module

4.1.2 Module Components

A Livelink module must have:

• An initialization (INI) file

• An OSpace in a directory named ospace, containing


subclasses of certain objects

Livelink imposes a limit


A Livelink module may have: of 256 for the total number
of OSpaces and XDB files
that can be opened at
• Additional OSpaces, in order to split up functionality once. Keep this is mind
when doing your
• WebLingo files (HTML with embedded OScript) customizations.

• Web support files (.gif, .class, .jar, .cab, etc. )

• Web help files (a set of HTML files and toc.txt file—


see Appendix A)
• XDB files (used for localizing a module’s user text
when it needs to be displayed in multiple
languages—see Appendix A)

Livelink Builder Fundamentals Course Page 4-5


Section 4: Setting Up a Module

staging Configure
Request Handler Object
Performs the work of installing and
uninstalling the module. Uses
module.ini file features of the WebModule object
to determine what to do.

WebLingo WebModule Object


objects files and
in OLL support files Features store all the key
file information describing the
module: its name, version
number, dependencies on other
modules, etc. A method of this
object is used to create the
module’s INI file.

module support database

Figure 4-4: The objects involved in the installation of a module

Page 4-6 Open Text Corporation


Section 4: Setting Up a Module

4.2 When a Module is Installed

All installed modules are found in the modules directory of


the Livelink installation. If a module’s name is listed in the
“Installable Modules” portion of the Install Modules page,
then the module’s directory of files is in the Livelink
installation’s staging directory. Livelink reads the
module’s INI file to determine basic information about the
module, such as its version number and the other modules
upon which it depends.
Why is the support
The INI file is created by a special method in the module’s directory of a module duplicated
WebModule object, which stores all the key information in the Livelink installation’s
about the module. The module’s Configure request handler support directory?
performs the actual installation, uninstallation, and upgrade
of a module. When a module is installed, its directory is
moved to the module directory from the staging directory.
Its support directory is copied to the support directory of
the Livelink installation. The Modules section of the
opentext.ini file (located in the config folder) is modified to
include the information needed for the new module during
Livelink startup. What else happens depends upon how the
module was configured: The module may alter the database
schema and/or add data to the database.

Step set 4.1: Setting up the module directory structure

1. Decide on a name for your new module. It’s a good idea to use something relevant to
your customizations. (We’re going to make a “suggestions” module during the course
lectures).

2. Navigate to the staging directory in your Livelink installation’s root directory. If there
is no staging directory, create one.

3. Create a new directory in the staging directory and name it using your module name
followed by the major version number, minor version number and revision number of
your module separated by “_” (for example, “suggestions_1_0_0”).

4. Create the directories needed for your customizations within your new module’s
directory. At minimum your module will need an “ospace” folder. It will also
probably need an “html” folder, a “support” folder and maybe a “help” folder.

Livelink Builder Fundamentals Course Page 4-7


Section 4: Setting Up a Module

module.ini file
RequestHandlerGroup

Configure Root

WebLingo
WebModule New functionality objects
OSpace files and
New functionality support files
New functionality
Globals
Module
Other orphans

Figure 4-5: Some of the objects in an OSpace for a module

Figure 4-6: The OSpace Menu

Page 4-8 Open Text Corporation


Section 4: Setting Up a Module

4.3 Working with OSpaces

When you want to customize Livelink’s objects, you


should create a new OSpace. You should not modify the
OSpaces that ship with Livelink. The new OSpace will
contain:

• objects that contain new functionality

• objects that are meant to extend or override existing


objects

When you make a module, you create an OSpace for the


module’s objects. You can create more than one OSpace
for a module, but this is not normally necessary and is not
recommended.

Step set 4.2: Creating a New OSpace

1. Choose New OSpace from the OSpaces menu (see


Figure 4-6).

An output file selection dialog box opens.

2. Navigate to the ospace directory in your module


directory. As we noted earlier,
every OSpace contains a
3. Enter a file name for the OSpace. Use the same root object. When Livelink
creates an OSpace, it
name as your module (to avoid confusion), and the automatically creates the root
extension “OLL”—for example, suggestions.oll. object with a few features. It
also automatically creates a
Globals object, which serves
Livelink creates the new OSpace, automatically as a registry of important
adding a root object and a Globals object. objects in the OSpace (see
Section 5).

Livelink Builder Fundamentals Course Page 4-9


Section 4: Setting Up a Module

Figure 4-7: Orphaning the WebModule Object

Page 4-10 Open Text Corporation


Section 4: Setting Up a Module

4.4 The WebModule Object

Every Livelink module must contain a WebModule object.


The WebModule object’s features store all the details about
a module that are required during installation, initialization,
and uninstallation of your module.

The WebModule object is also used whenever Livelink is


trying to locate weblingo, support, and help files within its
module

Step set 4.3: Creating a WebModule Object


In this course manual, we
use the syntax
1. Locate the WebDsp:WebModule object (see note to OSpaceName:ObjectName to
refer to particular objects. So in
right). the example at left,
WebDsp:WebModule means
2. Right-click the object and choose the New Orphan “WebDsp OSpace, WebModule
object”. When an object or
command from the context menu. From the feature is a number of levels
dropdown list, choose the name of your new deep in the OSpace hierarchy,
OSpace. (See Figure 4-7.) we’ll name its full “path”, for
example, “WebDsp: WebDsp
Root: RequestHandler.
3. When prompted, name the orphan object after your Execute()”.
module—for example, SuggestionsModule.

Livelink Builder Fundamentals Course Page 4-11


Section 4: Setting Up a Module

Figure 4-8: WebModule object in the Object Browser window

WebModule Object
Features:
fEnabled -------------True
fName ----------------“Suggestions Module”
fModuleName ------“suggestions”
fOSpaces------------{‘suggestions’}
fVersion--------------{‘1’,’0’,’r’,’0’}
fDependencies ---{{‘kernel’, 8, 1}}
fFilesToCopy -------{{'%3support%1','%4%5%1'}}
fSetupQueryString “func=suggestions.configure&module=suggestions&nextURL=%1”
0DumpModuleConfigToFile() method

Figure 4-9: The WebModule object’s principal features

Regarding the fDependencies feature: All modules depend on the Kernel module. Do not remove this
module from the dependencies list. You should add additional dependencies as additional list items.
You should add a module to your dependencies list if:
• You orphan any object from a non-core Module OSpace into your module
• You use any global references to a non-core Module’s objects in your scripts

Page 4-12 Open Text Corporation


Section 4: Setting Up a Module

Step set 4.4: Setting the WebModule Object’s Features

Set the features of the WebModule object according to the


example in Figure 4-9.

Feature Notes
fEnabled Many of the objects you create will inherit an fEnabled feature. This boolean
controls object initialization (see the Initialization topic later in the section for more
details) and is used to enable and disable functionality.
fName The fName feature stores the display name of your module. This name will be
displayed on the Livelink Administration pages when your module is ready to
install, uninstall and upgrade.

fModuleName The fModuleName stores the internal name for your module. It should be in all
lower case and match the name you used when creating your module directory
structure.
fOSpaces This feature specifies the list of OSpaces in your module. The order in which the
OSpaces appear in the list is unimportant.
fVersion In order for your module to install and upgrade properly, the numeric list items
must match the numbers specified in your module’s directory name, such as
suggestions_1_0_0.

The elements of the list:


• major version number (of your module, not of Livelink)
• minor version number
• build level, which may contain ‘r’ for release, ‘d’ for development or ‘b’ for
beta. This feature is for informational purposes only, and will not impede the
installation or upgrading of a module.
• revision
fDependencies This list of lists includes the name, and the major and minor version numbers of
any other modules on which your module depends. These modules must be
opened prior to this one.

fFilesToCopy This feature is used by the Configure request handler (see Section 4.6) to specify
the “from” and “to” directories where your module will be copied during
installation. The % signs indicate placeholders for parameters used during the
installation (see the object’s Documentation feature for details).

fSetupQuery This string contains the URL for the Configure request handler (see Section 4.6.
String During execution, the nextURL=%1 parameter is populated with a call to the
request that should be performed after the configuration request completes.

Livelink Builder Fundamentals Course Page 4-13


Section 4: Setting Up a Module

Another Object that needs initializing

Another Object that needs initializing

SuggestionsModule Object
Features concerning initialization:
• __Init() method
• fEnabled ------ TRUE
Suggestions Globals Object
Features:
• BuildOSpace() method (setup script)
• f__InitObjects list --- {#35000132,#35000134,#350003b5…} Root Object
• (other features for global references…) Startup() method runs
at system startup,
locates all objects
named by f_InitObjects,
runs their _Init()
methods

Figure 4-10: How an OSpace’s Globals object keeps a list of all objects
that need initialization

Page 4-14 Open Text Corporation


Section 4: Setting Up a Module

4.5 Enabling and Initializing Objects

Livelink does not assume that you want every object you
create to become part of the interface right away. Most
class objects have an fEnabled feature that is defaulted to
False, and this “turns off” the functionality of the orphans
and children you create of the object.

One of the purposes of enabling an object is to allow it to


be initialized. Many objects must be initialized at startup—
in order to set features of the object, make temporary
children of the object in which to cache information,
register objects with subsystems, and more. Objects that
need to be initialized include a method called __Init(), and
this method does whatever work needs to be done to
initialize the object. In this example, the ModuleObject
orphan must be initialized at startup so that it registers with
the Module subsystem.

The Globals object for every OSpace contains a list feature Reminder: The Startup()
called f__InitObjects, a list of all the objects in the OSpace method of an OSpace’s Root
which need to be initialized. As a developer, you must tell object is automatically executed
whenever the OSpace is
Livelink to update this list whenever you create an orphan opened.
or child object that needs to be initialized. To update the
f__InitObjects list, just run the BuildOSpace() method in There is a BuildOSpaces
command under the Tools
the Globals object of your OSpace. When you run this menu of the Builder. This
script, Builder will look for all the objects in your OSpace command will run the
that contain an __Init() script and add each object’s id to Globals.BuildOSpaces() method
of every open OSpace. Since
f__InitObjects. this can take some time to
transact, we normally
When a module’s OSpace opens during system startup, the recommend that you run the
BuildOSpace() method for the
OSpace’s Root.Startup() method automatically runs the OSpace in which you’re working
__Init() method of every object listed in the OSpace’s instead. You may want to run
Globals.f__InitObjects feature. If an object’s fEnabled the BuildOSpaces command
once towards the end of your
feature has been set to true, that object will be initialized development project, just to
and registered with its subsystem. make sure you haven’t forgotten
to enable any objects.
Step set 4.5: Enabling Objects

1. Set the object’s fEnabled feature to TRUE (if


present).

2. Run the BuildOSpace() method of your OSpace’s


Globals object.

Livelink Builder Fundamentals Course Page 4-15


Section 4: Setting Up a Module

Configure
request
handler

WebModule object (with


fQueryString and fFilesToCopy)

RequestHandlerGroup
object

Figure 4-11: OSpace containing basic set of module objects

module.INI file

Figure 4-12: Structure and contents of a module directory ready for "staging"

Figure 4-13: The Configure request handler object

Page 4-16 Open Text Corporation


Section 4: Setting Up a Module

4.6 The Configure Request Handler

Each module must have a Configure request handler


object to perform module installs, uninstalls and upgrades.

The fFuncPrefix feature of the Configure request handler


can be used to name the module the request handler will
install. Some of the other features of the Configure request
handler can direct Livelink to perform special actions as a
module is installed and uninstalled, such as adding and
removing schema.

Step set 4.6: Create a Configure Request Handler

1. Orphan the WebAdmin:AdminRequestHandler:


Configure object in the module’s OSpace and name
it “Configure”.
This is the standard naming convention used
throughout Livelink, not a required name.

2. Set fEnabled to TRUE.

3. Set fFuncPrefix to the name of your module.


By convention, this prefix matches the name (and
case) of your module name.

In our example, we’re using “suggestions” as the


prefix. The URL for calling the request handler will
therefore have the form
“http://….?func=suggestions.Configure”.

Livelink Builder Fundamentals Course Page 4-17


Section 4: Setting Up a Module

Suggestions
$WebDsp. Request Handler Group Object
RequestHandlerSubsystem
SetRequestHandlers() method
Object
fRequestHandlers list—
Dispatch() method {{'sug.Configure,#7e003993},
{'sug.ListSuggestions',#7e003430}, …}
fRegistry assoc…<’admin.adminlogin=#900014b,…
> ---------- ‘project.editparticipants’=#40000aac, …>

Configure Request
Project Handler Object
Request Handler Group Object
SetRequestHandlers() method ListSuggestions Request
fRequestHandlers list— {{'project.Configure',#400007f5}, Handler Object
-------------- {'Projects.AddParticipants',#40000aaa},
-------------- {'Projects.AddParticipants2',#40000aab},
-------------- {'Projects.EditParticipants',#40000aac}…}

Configure Request AddParticipants


Handler Object Request Handler Object

AddParticipants2 EditParticipants
Request Handler Object Request Handler Object

Figure 4-14: RequestHandlerGroup initialization

ll
WebNode RH
Request
Handler Fetch
Request Group RH
Handler Add
Subsystem Version
Registry WebDoc RH
Request View
Handler RH
Group Check
In
RH
Suggestions Reserve
Request RH
Handler Group
Suggestions
RH

Figure 4-15: Another way to view RequestHandlerGroup initialization

Page 4-18 Open Text Corporation


Section 4: Setting Up a Module

4.7 Registering Your Request Handlers

The next step in setting up a module is to create a


Configure request handler—but before you make your first
request handler, you need to make a Request Handler
Group object.

There are many request handler objects in Livelink, so


many that their initialization and registration with the
Request Handler Subsystem object would take too long if it
had to be done at each Livelink startup. Request Handler
Group objects were created to optimize request handler
initialization.

There is one Request Handler Group object for each


Livelink OSpace that contains request handlers (and most
of them do). The fRequestHandlers feature of the object
contains a list of all request handlers in the OSpace. At
startup, as each Request Handler Group object is initialized,
it passes the list of its request handlers to the Request
Handler Subsystem for registration. In this way,
initialization is performed on only one object (the Request
Handler Group) instead of many (all of the individual
Request Handler objects).

Step set 4.7: Creating a Request Handler Group Object

1. Orphan the WebDsp:WebDsp Root:


RequestHandlerGroup object and name it after your
module, for example,
“SuggestionsRequestHandlerGroup”.

2. Set the object’s fEnabled feature to TRUE. Once the request


handler group object is
created, you can start
3. Select the Globals object in your OSpace. Right adding request handler
click the BuildOSpace() method and choose the Run objects. As you add
Script command. request handler objects,
you need to remember to
run the method called
4. Run the SetRequestHandlers() method in your SetRequestHandlers() in
module’s request handler group object to register the Request Handler Group
the Configure request handler with the request object to have your new
request handler registered
handler group object and to regenerate the with the subsystem.
fRequestHandlers list.

Livelink Builder Fundamentals Course Page 4-19


Section 4: Setting Up a Module

[dependencies]
requires_1={'kernel',8,1}

[description]
Version=1.0 r 0
Name=Suggestions Module
moduleName=suggestions

[install]
Url=func=suggestions.configure&module=suggestions&nextURL=%1

[OSpaces]
ospace_1=suggestions

Figure 4-16: Sample module.INI file

Page 4-20 Open Text Corporation


Section 4: Setting Up a Module

4.8 The Module.INI File

The module.INI file is read when a module is installed,


upgraded or uninstalled. The file contains:

• a list of the module dependencies

• a description of the module, including its name and


version number

• the URL of the Configure request handler object that


will be called to perform the installs, upgrades and
uninstalls
Methods that start with
• a list of the OSpaces contained in the module the character “0” are setup
scripts. “Setup” is a
Do these items sound familiar? That’s right, they’re mostly developer’s naming
convention indicating that the
stored in features of the module’s WebModule object. The method is never called at
WebModule.0DumpModuleConfigToFile() method runtime, but instead is run
generates a module.INI file based on the values stored in manually by a developer
during development. Setup
the features of the WebModule object. If you change any scripts are used to populate
features of the WebModule object, you must run the complex features, create
0DumpModuleConfigtoFile() again. external files like this INI file,
and more.

Step set 4.8: Creating the INI File

1. Run the 0DumpModuleConfigToFile() method in


your module’s WebModule object.

2. In the file selection dialog box, select the root


directory of your module, and save the INI file
there. The contents of the INI file will also be
echoed in the Debug window.
dependencies
requires_1={'kernel',8,1}
description
moduleName=suggestions
Name=Suggestions Module
Version=1.0 r 0
install
Url=func=suggestions.configure&module=suggestions&nextURL=%1
OSpaces
ospace_1=suggestions

Livelink Builder Fundamentals Course Page 4-21


Section 4: Setting Up a Module

Figure 4-17: A new module in the “Installable Modules” section of the Install Modules page

Page 4-22 Open Text Corporation


Section 4: Setting Up a Module

4.9 Installing Your Module

Installing a module removes it from the Livelink root “staging”


directory and places it in the Livelink root “module” directory.
The functionality implemented by the module becomes
available after installation.

Step set 4.9: Install Your Module

1. Save and export your new Ospace, then quit and restart
Builder. It may also be a
good idea to make a
backup copy of your
2. Navigate to the Livelink Admin Install Modules Page. whole module while
The Installable Modules section of the page displays a list Builder is closed and
prior to attempting the
of modules that can be installed. module installation.
Don’t forget to backup
3. Click the checkbox to the left of the Suggestions module the opentext.ini file at
the same time
and then click the Install button.
Livelink will install your module, and you will be prompted
to restart your server.

At this point in the course, the module doesn’t actually do


anything—but it is fully installed, and will be ready for use by
the Builder.

Auto Unlocking for Your OSpace

If you are developing your module, you’ll probably want your OSpace to open in “unlocked” mode automatically
when you start the Builder. This will save you time as you develop. To do this you need to make a small change
to the webbuilder.lxe file.

1. Navigate to your Livelink root installation directory, and open the webbuilder.lxe file (from within the
Builder or with a text editor).

2. Find the line that says:


List changeStateOSpaces = { }

3. And change it to include the name of the ospace in all upper case and between quotes:
List changeStateOSpaces = { "SUGGESTIONS" }

4. Save and close webbuilder.lxe and restart the Builder.

Livelink Builder Fundamentals Course Page 4-23


Section 4: Setting Up a Module

4.10 Summary

• Modules allow developers to develop and package their


enhancements in a way that is easy to install, update,
and remove.

• When you make a module, you set up a standard


directory structure in the staging directory of the
Livelink installation. You then create an OSpace and
orphans of particular objects.

• The WebModule object stores all of the basic


information about the module, such as its name and
version number. After setting its features, you run a
method of the WebModule object to create the INI file
for the module.

• The Configure request handler is the object which


actually handles installation, uninstallation, and
upgrade of a module.

• Each OSpace that contains request handlers contains a


Request Handler Group object. The fRequestHandlers
feature of this object is a registry of all request handlers
in the OSpace, built when you run the
SetRequestHandlers method of the object.

• After you have created the module’s directories,


orphaned the objects, and set their features, you can
perform the module installation. You can then start
creating enhancements using the Builder.

Page 4-24 Open Text Corporation


Section 4: Setting Up a Module

4.11 Section 4 Exercises

4.11.1 Creating a new module

Create a new module using the wizard

□ 1. In the builder select File->open and navigate to your solutions CD -> toolkit directory.
Open the makeANewModule.lxe file and select the command Script->run.

□ 2. Call your new module “contact”, and “Contact Module”. You can number it 1 0 r 0 if
you like.

Bonus:

Do you recall how to force the Builder to open your OSpace in unlocked mode? EDIT the
webbuilder.lxe file to enable this, following the instructions in the note of section 4.9.

Alternatively perform the following 5 sections!

4.11.2 Creating a New Directory Structure

Create a directory structure to hold your new module.

□ 3. CHOOSE a suitable name for your module: During these exercises, you will be making
a module for managing information about contacts, such as the customer contacts for a
sales organization. We will refer to the module as the “contact” module throughout these
exercises.

□ 4. If there is no “staging” directory below LLHOME, CREATE one. (Reminder: We are using
“LLHOME” to represent the Livelink installation directory.)

□ 5. CREATE a new directory in LLHOME\staging and name it contact_1_0_0.

□ 6. Create three new directories in LLHOME\staging\contact_1_0_0 called html,


support, and ospace, all lower case.

□ 7. Your directory structure should look similar to the following (supposing LLHOME =
“C:\livelink”):
C:\livelink\staging\contact_1_0_0\ospace\
C:\livelink\staging\contact_1_0_0\html\
C:\livelink\staging\contact_1_0_0\support\

Livelink Builder Fundamentals Course Page 4-25


Section 4: Setting Up a Module

4.11.3 Adding OSpaces

Add your new OSpace.

□ 1. From the Builder, CREATE a new OSpace and name it contact.oll. Do you recall
where this OSpace file should reside?
How: OSpace menu → New OSpace. NAVIGATE to
LLHOME\staging\contact_1_0_0\ospace. NAME the file contact.oll.

4.11.4 Adding the WebModule Object

Add the WebModule object, configure its features, and make it start automatically when
Livelink is started.

□ 1. ORPHAN WEBDSP : WebModule in the contact OSpace, calling it ContactModule.


(Note: Don’t see the object? Make sure you’re viewing the objects by OSpace, not by
inheritance.)

□ 2. CHANGE ContactModule.fName’s datatype to String, then SET ContactModule.fName


= Contact

□ 3. SET the following features of ContactModule: (Do you recall what each one does?)

□ a. fEnabled (Boolean) = True

□ b. fModuleName (String) = contact

□ c. fOSpaces (List of strings) = {'contact'}

□ d. fVersion (List of strings) = {'1','0','r','0'}

□ e. fDependencies (List of List of strings and numbers) = {{'kernel',8,1}}

□ f. fFilesToCopy = (List of List of strings) {{'%3support%1','%4%5%1'}}

□ g. fSetUpQueryString = (String)
func=contact.configure&module=contact&nextURL=%1

□ 4. SELECT each of the features you set in step 3 and look in the lower right of the OSpace
Browser window to VERIFY that the contents are set as you expected.

□ 5. RUN Contact Globals.BuildOSpace(). Do you remember why?

□ 6. RUN ContactModule.0DumpModuleConfigToFile()to create the module INI file


contact.ini. Put this file in LLHOME\staging\contact_1_0_0.

Page 4-26 Open Text Corporation


Section 4: Setting Up a Module

4.11.5 Adding the Configure Request Handler Object

□ 1. ORPHAN WEBADMIN : AdminRequestHandler : Configure in the contact OSpace


and name it Configure.

□ 2. Set fEnabled = True.

□ 3. Set fFuncPrefix = contact


Do you remember why?

4.11.6 Registering Your New Request Handler

□ 1. ORPHAN WEBDSP : WebDspRoot : RequestHandlerGroup in the contact OSpace and


name it ContactRequestHandlerGroup.

□ 2. SET fEnabled = True.

□ 3. RUN Contact Globals.BuildOSpace().

□ 4. RUN ContactRequestHandlerGroup.SetRequestHandlers(). Do you remember


what this does?

□ 5. SAVE and EXPORT your new OSpace. STOP and START the Builder.

□ 6. INSTALL your module from the Livelink Administration pages. As a precaution, you
might want to back up your module and the opentext.ini file before you attempt an
install (just in case things go wrong during your install).

Livelink Builder Fundamentals Course Page 4-27


Section 4: Setting Up a Module

Notes:

Page 4-28 Open Text Corporation


Section 5: OScript
Overview:

At its most basic level, Livelink is a set of scripts and a set of values used by those scripts.
This section introduces OScript, Livelink’s scripting language, and it introduces the tools
for creating and debugging scripts.

Objectives:

By the end of this section, you will be able to create and debug scripts written with OScript.
In the process, you’ll learn how to:

• Use the Script Editor to edit, compile, and save scripts

• Use the Debugger to troubleshoot errors during


execution

• Write OScript, understanding its general syntax,


variable and datatype rules, operators, control
structures, and function header syntax

• Create methods in objects, refer to methods in other


objects, and make an object’s methods and other
features referenceable from other methods

Livelink Builder Fundamentals Course 92-300 04Feb11 Page 5-1


Section 5: OScript

Inheritance
Method name List of all methods in this object
state

“Break on entry”
Edit status (changed, toggle for
locked, unlocked) debugging

Editing pane

Figure 5-1: Script Editor window

Page 5-2 Open Text Corporation


Section 5: OScript

5.1 The Use of OScript in Livelink

OScript is a full featured programming language which


lies at the heart of Livelink. OScript is used in three ways:

• Many of the features of objects are scripts (methods)


written in OScript.

• OScript is embedded in the WebLingo files which are


used to dynamically generate HTML pages.

• There are also files external to Livelink that contain


OScript scripts. For example, the launch script you run
to start Livelink is written in OScript.

In OScript, you will see the power of Livelink as an object


system and as a knowledge management system
development environment, especially when you peruse its
packages of built-in functions.

5.2 The Script Editor

As with most development environments, the Builder


includes a Script Editor with functionality specific to
writing OScript. To create a new method:

1. Select the object in which you want to create the


new method in the Browser window.

2. Choose the New Feature command from the


Feature menu or from the context menu.

3. Choose “Script” from the list of feature datatypes to


open the Script Editor (instead of an editor for
another datatype).

4. Enter a name for the method when prompted.

5. Enter your script in the editing pane of the window.


Compile it (see Section 5.3) and save it (see Section
5.4) to create the method.

Livelink Builder Fundamentals Course Page 5-3


Section 5: OScript

Figure 5-2: Error window showing a compilation error

Figure 5-3: Script window, with an error highlighted by


double-clicking a row of the Error window

Page 5-4 Open Text Corporation


Section 5: OScript

5.3 Compiling Scripts

OScript is a compiled language. Each script is checked for


errors and made into an “executable” before it is run.

Choose the Compile command from the Script menu (or Livelink maintains both a
click the button) to compile a script. “text” and a “compiled”
version of methods. Scripts
that are stored as external
Click the button to compile (and save to memory) all files are always compiled
before they are executed.
scripts for a selected object.

If there are any errors, Livelink sends error messages to the


Error window. Select a row to see the textual error
message. Double-click a row of the window to jump to the
corresponding line of code in the Script Editor window.

5.4 Saving Scripts

If you are editing a script and you choose the Save


command from the File menu, the script is saved to
memory. This command does not save the script to disk,
nor does it compile the script. (But it is very useful as you
develop and test methods, since it will allow you to run the
version saved to memory as you test.)

The script is only saved to disk when you save all OSpace
changes to disk, which happens when you choose the Save
command with an Object Browser window active.

Livelink Builder Fundamentals Course Page 5-5


Section 5: OScript

Figure 5-4: The Script menu

Figure 5-5: The Open Selection command, available when a method is highlighted

Page 5-6 Open Text Corporation


Section 5: OScript

5.5 Other Script Commands

The Script menu contains several commands for working


with scripts:

Run The Run command runs the script. (You will


get an error if you try to run a script which
has input arguments with no default values.)

Debug The Debug command opens the Debugger


(see the next pages) and allows you to step
through the code line by line, watching its
progress. The Toggle Break on Entry
command switches the “break on entry”
status of the script. When break on entry is
set, the Debugger will automatically open
The File menu also has a
whenever the script is called. The Go to Line handy command for script
command is used when debugging, to jump editing: If you highlight a
to a specified line of code. method name, you can use
the Open Selection
Indent and The Indent and Undent commands move the command to open that
method in a new window. If
Undent selected line(s) of code in or out one tab the method is a method of
position. another object, you should
highlight both the object
Find, Find The Find, Find Again, and Replace reference and method name,
for example, all of
Again, and commands allow you to search and replace “$DatePkg.FormatLong”.
Replace within the script. (The Search tool allows you
to search across scripts.)

Xlate The Xlate commands at the bottom of the


commands menu are used if you want to translate the
user messages in your code to a different
language.

Livelink Builder Fundamentals Course Page 5-7


Section 5: OScript

Figure 5-6: The Debug window (Debug command from the Window menu)

List of
variables

Stack
(Intermediate
values of a
computation are
stored on the
stack.)

If you select a
variable you
can edit it here.
Press TAB to
Status of the current save your edits.
line of code

Lists all
Breakpoint (Set by methods
double-clicking.) currently
involved and
allows switching
between the
Pointer to current methods.
line of code

Figure 5-7: The Debugger window (Debug command from Script menu)

Page 5-8 Open Text Corporation


Section 5: OScript

5.6 The Debug Window and the Debugger

The Debug window opens automatically when you launch


the Builder, and we recommend that you leave it open.
(You can also open it by choosing Debug from the Window
menu.) The Debug window lists messages sent to it by the
Echo() built-in OScript function.

The Debugger is a tool for stepping line by line through


the code of a script, watching the values of variables and You can set a preference
concerning whether the
checking the status line for errors. The Debugger opens if Debugger should open
you choose the Debug command from the Script menu. It automatically by choosing the
also opens automatically if Livelink encounters an error Preferences command from
the Tools menu.
when running a script or if Livelink runs a script with the
“break-on-entry” toggle set.

The panes in the Debugger:

Variable list of all script variables and their values

Stack current stack values

Value value of the variable currently selected in the


variable pane

Script the current method

The buttons in the Debugger:

Step attempts to execute the current line of code (the


one pointed to by the arrow)

Go runs the script until it hits a breakpoint, an error, or


the end of the script

In switches the Debugger to the method being called


by the current line of code (if any), allowing you to
debug that method

Out completes the execution of the current method


and switches the Debugger from the current
method to the one that called it (if any), allowing
you to continue to debug that method

Livelink Builder Fundamentals Course Page 5-9


Section 5: OScript

5.7 General OScript Syntax

This sample script illustrates the basics of the OScript


language syntax:

// Private method
// Override this method to perform specific attribute assignment to
// the node.
// Parameters:
// node The DAPI node to be created.
// createInfo Addition information in order to create the node.
// context Custom parameter
// Return an assoc: Statements are terminated by
// OK TRUE if ok. the end of the line, and the
// ErrMsg Application error message if not ok. backslash (\) is the line
// ApiError Error returned by API if not ok. continuation character.

function Assoc NodeCreateSubclassPre(DAPINODE node,\


Dynamic createInfo,\ A semi-colon (;) can be
Dynamic context ) used as a statement
Assoc rtnval; Dynamic apiError separator (but we usually
String errMsg don’t use this).

Boolean ok = TRUE
Convention: Variable
//insert custom code here names start with a lower
//create assoc to store new data case character, and each
assoc suggBox; dynamic request = createInfo.request word of a “compound”
name is capitalized.
//populate assoc
suggBox.dept = request.dept
suggBox.subject = request.subject There are two options for comments: double
slashes (//) and C-style:
//store sugg data /* This is a comment too*/
node.pExtendedData = suggBox

if IsUndefined( rtnval.OK )
rtnval.OK = ok
rtnval.ErrMsg = errMsg
rtnval.ApiError = apiError
end Convention: FunctionNames are
capitalized, with each word of a
return( rtnval ) “compound” name capitalized.
end

Figure 5-8: Example OScript code, outlining syntax

Page 5-10 Open Text Corporation


Section 5: OScript

5.8 Variables and Datatypes

• Names may consist of up to 255 characters (from A-Z


and a-z, 0-9 and _). They must start with an alphabetic
character.

• Variables are local to a function (except for global


variables).

• Variables can be dynamically typed, but declaring type


aids in checking for errors.

• OScript includes a number of common and less


common datatypes. Here are some of the datatypes you
may use the most:
assoc list
boolean object
date real
dynamic RecArray
error record
file string
integer undefined

There are also a number of datatypes which correspond


directly to the various document management,
workflow, and other built-in functions (we’ll see
various examples throughout the course). See the
OScript built-in section of Livelink’s online Developer
documentation for more details about these datatypes.

• Records, RecArrays, Assocs, and Objects are passed by


reference. All other OScript datatypes are passed by
value.

• Regardless of their declared datatype, all variables can


contain a value of datatype Error or Undefined.

• When declaring a variable, you can also assign an


initial value. For example:
date entryDate = Date.Now()

Livelink Builder Fundamentals Course Page 5-11


Section 5: OScript

* Multiplication &= Bitwise And assignment || Logical Or (or OR)


/ Division |= Bitwise Or assignment ^^ Logical XOr (or XOR)
% Modulo ^= Bitwise XOr assignment << Bit shift left
! Unary Not %= Modulo assignment >> Bit shift right
< Less than [] Subset operator = Assignment
<= Less than or equal to (or le) : Subset range operator += Plus assignment
> Greater than {} List creation -= Subtract assignment
>= Greater than or equal to (or ge) @ List expansion operator *= Multiply assignment

== Equals (or eq) $ Global variable indicator /= Divide assignment

!= Not equals (or <> or ne)


+ Addition
- Subtraction

Figure 5-9: List of the Livelink operators

Page 5-12 Open Text Corporation


Section 5: OScript

5.9 Operators

The operators used in OScript are very similar to those used


in other languages. Take a look at the set in Figure 5-9—
are there any you don’t recognize?

Livelink Builder Fundamentals Course Page 5-13


Section 5: OScript

if budget < 3500


reviewby = "Editor"
elseif ( budget >= 3500 ) && ( dtype == "Draft" )
reviewBy = "Sr. Editor"
end

Figure 5-10: If statement example (testing the value of a variable)

file infile = File.Open( "StRept.TXT", File.ReadMode )


string inline = File.Read( infile )

while ( !File.EOF( infile ) )


Echo( inLine )
inLine = File.Read( infile )
end

File.Close( infile )

Figure 5-11: While loop example (reading an external file’s contents)

string color = “blue” // or other code for assigning value


string outputString

switch color
case "pink"
outputString = "Just right."
end
case "red"
outputString = "Needs more white."
end
case "white"
outputString = "Needs more red."
end
default
outputString = "You need to combine red and white to make pink."
end

end

Figure 5-12: Switch statement example (creating output for various values)

Page 5-14 Open Text Corporation


Section 5: OScript

5.10 Control Structures

You will know about these kinds of control structures from


your experience with other programming languages. For
your reference, here are the OScript syntax details.

If Statements
if boolean_expression
statements In these syntax
elseif boolean_expression descriptions, italics
statements denote a “placeholder”
else for a variable or value,
statements and angle brackets (< > )
end denote optional code.

While Loops
while ( boolean_expression )
code_block
end

Repeat/Until Loops
repeat
code_block
until ( boolean_expression )

Switch Statements
switch variable
case value1
code_block
end
case value2
code_block
end
[default
code_block
end]
end

Livelink Builder Fundamentals Course Page 5-15


Section 5: OScript

string message
integer i
for i = 2 to 10
message = "And then there were " + Str.String(I)
Echo( message )
end

RESULT
And then there were 2
And then there were 3
And then there were 4
(etc.)

Figure 5-13: Simple for loop example (simple string output)

string message
integer i
for ( i = 2; i <= 10; i += 1 )
message = "And then there were " + Str.String(i)
Echo( message )
end

Figure 5-14: C-style for loop example (same result as in Figure 5-13)

RecArray empsData = code for selecting from EMP table


record employee
string msg
for employee in empsData
msg = Str.Format( "Employee: %1. Dept: %2. Phone: %3",\
employee.NAME, employee.DEPT, employee.EXT )
Echo( msg )
end

RESULT (with imagined data in the empsData RecArray):


Employee: Jack Garcia. Dept: Human Resources. Phone: 2934
Employee: Chris Ho. Dept: Finance. Phone: 2943
Employee: Sammy Bagacracus. Dept: IT. Phone: 8473
Employee: Johanna Johannesburg. Dept: IT. Phone: 8732
etc.

Figure 5-15: Example of looping through a RecArray and building output using the
Str.Format() function (see also Section 5.12.1)

Page 5-16 Open Text Corporation


Section 5: OScript

5.11 Three Flavors of For Loops

1. Standard For loop syntax (see Figure 5-13):


for var_name = init_val <down>to end_val <by incr>
statements
end

2. C-Style For loop syntax (see Figure 5-14):


for ( initial_expr; end_expr; increment_expr )
statements
end

3. List, RecArray, and Assoc For loop syntax (see Figure


5-15):
for element_or_record in list_or_recArr_or_assoc
statements
end

Livelink Builder Fundamentals Course Page 5-17


Section 5: OScript

string s = "This is Joe's string" + \


' and this is too'

Figure 5-16: Example strings with single and double quotes

string msg = "What a lovely day!"

msg[1:4] —> "What"


msg[-4:-2] —> "day"

Figure 5-17: Examples of locating subsets of strings

string name = "Joseph"


string dept = "Accounting"
string ext = "3340"
string s = Str.Format( \
"Emp: %1. Department: %2. Phone: %3.", \
name, dept, ext )
Echo( s )

RESULT s —> Emp: Joseph. Department: Accounting. Phone: 3340.

Figure 5-18: Example of formatting a string using the Str.Format() function

Page 5-18 Open Text Corporation


Section 5: OScript

5.12 Datatype Notes

Here are some details about some of the more interesting


Livelink datatypes:

5.12.1 Strings

• You can use single or double quotes when declaring


and working with strings (see Figure 5-16).

• You can specify ranges, using both positive and


negative numbers (see Figure 5-17).

• Use the Str.Format() built-in function to create


complex strings more easily (see Figure 5-18).

Livelink Builder Fundamentals Course Page 5-19


Section 5: OScript

list xlist = { 'A', 100, { 1, 2, 'X'} }

Figure 5-19: A list with elements of different datatypes

list ylist = { 'A', 'B', 'C', 'D', 'E' }

ylist[1] —> 'A'


ylist[2:-2] —> { 'B', 'C', 'D' }

Figure 5-20: Examples of retrieving elements and ranges of elements


from a list

xlist = { ylist[1:2], 100, ylist[3:] }

RESULT xlist —> {{'A','B'},100,{'C','D','E'}}

xlist = { @ylist[1:2], 100, @ylist[3:] }

RESULT xlist —> {'A','B',100,'C','D','E'}

Figure 5-21: Example of defining a list with and without the


expansion operator (@)

Page 5-20 Open Text Corporation


Section 5: OScript

5.12.2 Lists

• Lists are like arrays in other languages. In OScript, each


element can be of a different datatype (see Figure 5-19).

• You can use subset ranges with positive and negative


numbers (see Figure 5-20).

• You can use the expansion operator (@) to expand a list


within another list (see Figure 5-21).

Livelink Builder Fundamentals Course Page 5-21


Section 5: OScript

assoc userData
userData.dept = "Accounting"
userData.name = "Joseph"
userData.ext = "3340"
string s = Str.Format( \
"Emp: %1. Department: %2. Phone: %3.", \
userData.name, userData.dept, userData.ext)
Echo( s )

RESULT s —>"Emp:Joseph. Department: Accounting. Phone: 3340."

Figure 5-22: Example of using an Assoc to store and retrieve a set of related information

list userData
userData[1] = "Accounting"
userData[2] = "Joseph"
userData[3] = "3340"
string s = Str.Format( \
"Emp: %1. Department: %2. Phone: %3.", \
userData[2], userData[1], userData[3] )
Echo( s )

RESULT s —>"Emp:Joseph. Department: Accounting. Phone: 3340."

Figure 5-23: The same as Figure 5-22, but using a list—see the advantages of an Assoc?

List columnNames = {'ID','FIRST','LAST'}


Assoc rowValues
rowValues.ID = "123"
rowValues.FIRST = "Jack"
rowValues.LAST = "Garcia"

String outputString
String columnName

for columnName in columnNames


outputString = outputString + Str.Tab() + rowValues.(columnName)
end

Echo( outputString )

RESULT outputString —> " 123 Jack Garcia"

Figure 5-24: Example of using the “value of” operator to retrieve Assoc elements by using
the values of a list’s elements

Page 5-22 Open Text Corporation


Section 5: OScript

5.12.3 Assocs

An Assoc is a multi-value datatype, like a list, but its


elements are named, so you don’t have to remember their
positions.

You can declare an Assoc, assign values to it, and retrieve


values from it very easily (see Figure 5-22). The Assoc’s
elements are dynamically typed.

Assocs are very handy for storing sets of related values,


especially when passing them to and from functions. It’s
especially handy to be able to refer to the Assoc’s elements
by name instead of by position—for an example, contrast
the examples in Figure 5-22 and Figure 5-23.

Getting the “Value of a Value”

The syntax ( y ) is used to access the value stored in y and use it


like a variable in a statement. The variable in the parentheses is
evaluated instead of being treated literally. This can be handy
when writing code where variable values should be used as
variable names. See Figure 5-24 for an example.

Livelink Builder Fundamentals Course Page 5-23


Section 5: OScript

RecArray empData = CAPI.Exec( \


.fPrgCtx.fDbConnect.fSession, "Select * from EmpTBL" )
record employee = empData[1]
outputString = employee.NAME + "works in " + employee.DEPT

RESULT outputstring —> "Ramiro Alba works in Accounting"

Another way to get the same result:


outputString = empData[1].Name + "works in " + empData[1].DEPT

Figure 5-25: Example of retrieving values from a RecArray

DAPINode xfolder
// code for getting a folder here
xfolder.pName = "Training documents"
xfolder.pDComment = "various training docs"

RESULT Assigns values to the Name and Comment properties


of the folder being created

Figure 5-26: Example of assigning values to properties of a DAPINode

Page 5-24 Open Text Corporation


Section 5: OScript

5.12.4 Records and RecArrays

A record is a set of named elements, similar to an Assoc.


Unlike an Assoc, you can “stack up” a bunch of records to
make a RecArray.

RecArrays are commonly used when working with data in


database tables.

• You create records and RecArrays using built-in


functions (starting with RecArray.Create()).

• Identify rows in a RecArray by number, columns by


name (see Figure 5-25 for an example.)

• A record is a direct reference to a row of a RecArray.

5.12.5 DAPINodes

DAPINodes are a multi-value datatype, used to work with


Livelink items (documents, folders, workflow maps,
projects, and other types of Livelink items). The DTree
table in the database stores the base set of information for
each Livelink item. (DAPI refers to the document
management built-in package of functions.)

DAPINodes are similar to Assocs and Objects (see Sections


5.12.3 and 5.14), except that there are predefined names for
the DAPINode elements, and the syntax for referring to
them is different. The predefined elements correspond to
the columns of Livelink’s DTree table. There is not necessarily
a one-to-one correspondence
Use the syntax DAPINodeVariableName.pPropertyName between DTree column
names and DAPINode
to refer to a DAPINode property (see Figure 5-26). See the datatype properties. Check
online help for a full list of property names. the online help’s DAPI
package reference for a full
list of property names.

Livelink Builder Fundamentals Course Page 5-25


Section 5: OScript

integer price = 100


string s = 'The price is $' + Str.String( price )
Echo( s )

RESULT
"The price is $100"

Figure 5-27: Example of calling a built-in function, passing a parameter

string s = "Employee" + Str.Tab() + "Dept"

Figure 5-28: Example built-in function that requires no parameters—Str.Tab()

Assoc File RecArray


Bytes List Str
CAPI Math System
DAPI OS UAPI
Date Pattern WAPI
Error Prefs

Figure 5-29: Some of the built-in packages

Page 5-26 Open Text Corporation


Section 5: OScript

5.13 Built-in Functions

OScript includes an extensive set of built-in functions,


grouped into packages (see Figure 5-29). These are the
heart of Livelink.

Syntax:
PackageName.FunctionName( parameters )

• Functions requiring no parameters are suffixed with an


empty set of parentheses (see Figure 5-28).

• There is a “Core” package of functions that can be


called without a package name. Examples: Echo(),
IsUndefined(), IsNotError().

• The Livelink Developer’s online help is your best


source of documentation for the built-in functions.

5.13.1 DAPI Package

One of the packages that you may use often is the DAPI
package of built-in functions.

The DAPI package is used to access, add, and manipulate


data in the Livelink DTree table. Livelink’s DTree table
stores most of the information about the items in Livelink
(object ID, name, parent ID, type, etc.). Functions such as
DAPI.GetNodeByID(), DAPI.UpdateNode(), and
DAPI.DeleteNode() make customizing Livelink much
easier if your customizations include working with the
DTree data.

5.13.2 Online OScript Reference

Documentation for all of the built-in functions, as well as


the syntax for OScript control structures and more, is
contained in the Livelink Developer’s online help.

Livelink Builder Fundamentals Course Page 5-27


Section 5: OScript

FilePkg Object
Features:
• FormatFile()
• GetFiles()
• fDefaultDir

Figure 5-30: Example object: FilePkg

The GetFiles method:


function void GetFiles()
list filelist = File.FileList( .fDefaultDir )
string f
for f in filelist
Echo( .FormatFile( f ) )
end
end

Figure 5-31: FilePkg object method calling other FilePkg features

This line creates an object variable


and assigns it a value from a global
variable.

These lines retrieve values


object dataStore = $DataStorageObject from the object’s features.
list regions = dataStore.fRegions
date endDate = dataStore.fEndDate
string endDateString = dataStore.FormatDate( endDate )

dataStore.fStartDate = Date.Now() This line runs a


method of the object,
This line sets a passing it a date.
feature of the object
to today’s date.

Figure 5-32: Example of retrieving feature values, running methods, and populating a
feature of an object

Page 5-28 Open Text Corporation


Section 5: OScript

5.14 Objects

The Object datatype is another multi-value datatype, used


for manipulating OSpace objects. When writing OScript
code, you will sometimes assign an object to a variable in
order to more easily refer to its features.

It’s important to understand how objects are used in


Livelink: When writing a request handler, you will often
store values you retrieve from the database in the features
of the request handler object, then call that object’s features
from the HTML page to display the results of the request
handler.

• To refer to an attribute (“value” feature) of the same


object, use the syntax .featureName.

• To refer to a method of the same object as the calling


script, use the syntax .methodName(), placing any
needed input arguments in the parentheses. (See Section
5.16).

• To refer to a feature of another object, precede the


feature reference with a reference to the object. The
object reference can be a global variable, or it can be
passed to the script as an input argument—see the
example in Figure 5-32, Section 5.15, and later sections
of the course for more information.

Livelink Builder Fundamentals Course Page 5-29


Section 5: OScript

Suggestions Object
Globals object for the OSpace
“Suggestions”. Global variable
$Suggestions used to refer to
FilePkg Object
the object.
Features:
Features:
• FormatFiles() method
• CompileAll() method
• fFileType feature
• FilePkg object reference
• EnterSuggestion object reference

result = $Suggestions.FilePkg.FormatFiles()

Figure 5-33: Example Globals object—$Suggestions—and a call using the object

Page 5-30 Open Text Corporation


Section 5: OScript

5.14.1 Calling Features of Other Objects Using a Global Variable

If you want to call an object’s features from other objects,


you can create a global reference to it in your OSpace’s
Globals object.

Each Livelink OSpace contains one Globals object. Any


script, value or object can be accessed globally when added
to its features list using the syntax

$GlobalName.featureName

If you select the full name


The Globals object itself is named “[OSName] Globals” (in of a method that is called in a
our example, “Suggestions Globals”). The global variable script (i.e., from the $ to the end
created to reference the object is usually shortened to of the feature name), you can
choose Open Selection from the
$OSName (in our example, $Suggestions). This naming File menu to open that method,
convention identifies the OSpace where the Globals object without having to locate it using
originated. the Browser window.

How does an OSpace’s Globals object get its features? And


how is the global variable created for the object?

Livelink Builder Fundamentals Course Page 5-31


Section 5: OScript

The $ syntax is used


for both defining and
calling global
variables.

The OS.NewTemp()
built-in function creates
a temporary object for
the current Livelink
Session.

Figure 5-34: The Root.Startup() and Globals.Initialize() methods

The Initialize() method


creates a new,
temporary object
whose features are the
“registry” of objects
you want globally
accessible.

Figure 5-35: The Suggestions Globals Object (Initialized)

Page 5-32 Open Text Corporation


Section 5: OScript

5.15 Globalizing Objects

Each OSpace includes a Globals object. The Globals object


serves as a registry of all the objects, scripts, and other Just as with other
programming languages, the term
features within that OSpace which require global access. A initialize means to prepare an
Globals object is automatically created when you create an item for use, which could mean
OSpace. many things. In the case of
Livelink objects, initializing them
often means running certain
When an OSpace opens, the Root:Startup method is methods to build “registry”
automatically executed. This method calls other methods, features, and create temporary
objects in which to store
one of which initializes the Globals object and creates a information.
global variable for the object. (See Figure 5-34.)

Step set 5.1: Adding to the Globals Object Registry

When you create a new object and want its features


available globally, put a reference to it in your OSpace’s
Globals object:

1. Select the object that you want to “globalize”, then


choose Add to Globals command from the Object
menu.
This command creates an object reference feature in
the Globals object that refers to your object.

2. When prompted, specify a name for the object


reference feature. Normally, you use the same name
for the feature that you gave to the object, omitting
any spaces. This avoids confusion when referring to OTC developers also use the
‘add to globals’ function. Many of
the object, which can now be done from any script the objects that they make global
in any OSpace, using the syntax: are suffixed with ‘pkg’ or ‘utils’ and
are full of handy-dandy features.
$GlobalName.ObjectReferenceName.featurename Always look inside these objects

For example, given a Suggestions OSpace that contains a


“globalized” object called “GetSuggestion”, the object’s
“fFile” feature can be referred to by:
$Suggestions.GetSuggestion.fFile

The Application Globals command under the Tools menu


lists all currently defined global variables and their values.
Livelink keeps a hash table of all global variables as long
as Livelink is running.

Livelink Builder Fundamentals Course Page 5-33


Section 5: OScript

returned value's datatype


function keyword

function string LongDateFormat ( date inDate )

string dateString = \ input


Date.DateToString( inDate, '%A, %B %d, %Y' ) argument
datatype
and name
return dateString

end returning a value to


the calling function

Figure 5-36: Example function that requires one date input argument and returns a string,
stored in the DatePkg object’s FormatLong() method—note that the method name
is not the same as its first function’s name

date newDate = Date.Now()


string dateString = $DatePkg.FormatLong( newDate )
Echo( "The date is " + dateString )

RESULT: If today is 1/1/2000, the Echo() statement displays


The date is Saturday, January 01, 2000

Figure 5-37: Example of calling the method in Figure 5-36

(Example of
an “implied
string output = FormatDate( Date.Now(), "international" ) main
echo(output) function”)

function string FormatDate( date inputDate, string formatString = \


"short" )

string outputString

switch formatString
case "long"
outputString = Date.DateToString( inputDate, '%A, %B %d, %Y' )
end
case "international"
outputString = Date.DateToString( inputDate, '%Y%m%d' )
end
case "short"
outputString = "etc."
end
end
return outputString
end

Figure 5-38: Example of a method which calls a function within the method

Page 5-34 Open Text Corporation


Section 5: OScript

5.16 Creating Your Own Functions

As in most programming languages, you can create your Reminder: A method is a


own functions in Livelink. Most of the functions you create feature of an object that
contains code written in
will be stored as methods of objects. OScript.
• All methods are considered “functions” by Livelink.
If there is no explicit function declaration, there is
an implicit “main” one.
• Use function headers to pass arguments and return
values to and from your scripts. You must include a
function header in your method if the function will
be passed data from other functions or if it will
return data.

• When you call a method, call it by the method’s name,


not by the name of any function within the method.
When a method is called, Livelink passes arguments to
and executes the first function within the method. (For
example, the code in Figure 5-37 calls a method named
“FormatLong”, but the method’s first function,
displayed in Figure 5-36, is named “LongDateFormat”.)

• You can include “subroutines” or “subfunctions” inside


a method. The first function is the one executed by the
call to the method, and it can call the second, third, and
any other functions. The functions within a method can
also be called by each other.

Livelink Builder Fundamentals Course Page 5-35


Section 5: OScript

function string CreateLogString( \


string action = 'ENTERED', \
date when = Date.Now(), \
string who = "Administrator")

string auditString

// rest of code here,


// assigning value to auditString

return auditString
end

Figure 5-39: A function header that uses all the declaration options

auditLine = CreateLogString()
auditLine = CreateLogString( 'DELETED' )
auditLine = CreateLogString( 'ENTERED', Date.Now(),"cho" )

Figure 5-40: Examples of calling the function in Figure 5-39, sometimes using the default
values for input arguments

function CreateLogString( action, when, who )

string auditString
// rest of code here,
// assigning value to auditString
return auditString
end

Figure 5-41: A function header for the same function as in Figure 5-39—but this time, with
only the declaration options that are absolutely required for the function to operate

auditLine = CreateLogString( 'DELETED', Date.Now(),"Administrator" )


auditLine = CreateLogString( 'DELETED', Date.Now(),"ralba" )
auditLine = CreateLogString( 'ENTERED', Date.Now(),"Administrator" )

Figure 5-42: Examples of calling the function in Figure 5-41—note that since none of the
arguments are optional, they must all be passed to the function

Page 5-36 Open Text Corporation


Section 5: OScript

5.16.1 Function Syntax


function returnType functionName ( \
arg1type arg1 = default1, \
arg2type arg2 = default2, ... )

// function code here

return returnValue
end

Several components of the function declaration are


optional, including:

• the return datatype and the datatypes of the


arguments (which aid in checking code at runtime)

• the return statement — since it is not necessary to


return a value from a function (unless the return
type is specified to be other than VOID)

• default values for the arguments — it is not


mandatory that they be defaulted

Defaulting arguments allows you to omit them when you


call the function. Note that you cannot skip arguments in
the middle of an argument list. Therefore, make the
rightmost arguments the ones with the default values.

Livelink Builder Fundamentals Course Page 5-37


Section 5: OScript

5.17 Summary

• OScript is used to drive all aspects of the Livelink


functionality. OScript is found embedded in HTML
templates, as methods of Livelink objects, and as
external script files. The Script Editor window is used
to write scripts.

• OScript is a compiled language. Scripts are compiled


using the Compile command under the Script menu. If
there are compilation errors, they are presented in an
Error window, whose rows can be double-clicked to
highlight the associated offending lines of code. When
a script compiles successfully, it can be executed by
choosing the Run command from the Script menu.

• OScript’s syntax reminds many users of C and C++. It


contains the datatypes present in most 4GLs, plus a
number of more unusual (but very useful) datatypes like
DAPINode, RecArray, and list. Its operators (like +
and -) and control structures (such as if statements and
for loops) are standard and straightforward.

• References to objects are used extensively in OScript.


Objects that will be referred to by other objects must be
“registered” with the Globals object in their OSpaces.
They can then be referred to with the syntax
$OSpaceName.ObjectName.

• The real power of OScript lies in its extensive packages


of built-in functions. There are packages of functions
for common operations, such as string manipulation and
math; the Document Services, Workflow, and User API
functions are the true focus of Livelink.

• You can create your own functions, using the same sort
of syntax you use in other programming languages.
Functions are normally stored in methods; when you
want to call the function, you use the method name, and
Livelink will execute the first (main) method in the
function.

Page 5-38 Open Text Corporation


Section 5: OScript

5.18 Section 5 Exercise

Create a utility object and make this object globally available in Livelink. Write a script in
this object that will accept a string containing an external file path, will read that external
file (a file of contacts) into a RecArray, and will then return the RecArray. Then, in the root
object of your contact module, create a method that will call this utility script, and assign the
results to a dynamic feature you have also created in your root object. Obtain an input file
(contacts.txt) from your CD.

□ 1. Your instructor will provide a file called contacts.txt. (On your CD in the Student
Solutions directory) Each line of the file contains comma-delimited contact information
for a customer. LOCATE this file. It will be used in subsequent steps.

□ 2. CREATE a child object of your OSpace’s root object and call it ContactUtils. Make
this object globally available. (How: RIGHT-CLICK the object → Add to Globals) Use
the default name ContactUtils as the name for the global object reference feature.

□ 3. CREATE a new script in this object called ReadContacts.

(If you like, see the example code at the end of this section’s exercise for reference, as
you perform this and the subsequent steps.)

□ 4. EDIT the ReadContacts() script:

• CREATE a function header that defines a return datatype of RecArray and accepts a string
parameter containing a file path

• Using the RecArray built-in function RecArray.Create(), WRITE some code to create a
RecArray with five fields named to correspond to the fields in the contacts.txt file:
firstname, lastname, email, phonenumber, and customernumber.

• WRITE code to read each line of the contacts.txt file and add it as a record to your new
RecArray.
There are multiple ways to do this, but we think you’ll find these built-in functions
useful: File.Open(), File.Read(), Str.Elements(), Str.Tab(), File.EOF(),
RecArray.AddRecord(), File.Close().

• INCLUDE CODE in your ReadContacts() method to convert the customernumber string


values to integers for each record.

□ 5. COMPILE and SAVE ReadContacts().

□ 6. ADD a dynamic feature called fContacts to your OSpace’s root object. You will store
information in this feature.

Livelink Builder Fundamentals Course Page 5-39


Section 5: OScript

□ 7. ADD a script named CallReadContacts to your OSpace’s root object.

□ 8. EDIT CallReadContacts():

• CALL your ReadContacts() method (do you remember how to call global objects?),
passing it the path to the contacts.txt file.

• SAVE the return value from ReadContacts() in your new fContacts dynamic feature.

• WRITE a for loop in CallReadContacts()that echoes each record in your fContacts


feature, one at a time, to the Debug window.
(Depending on how ambitious you feel, you may find these built-in functions useful:
Str.Elements(), RecArray.FieldNames(), and RecArray.GetRecord().)

□ 9. COMPILE and SAVE CallReadContacts(). SAVE and EXPORT your OSpace.

□ 10.MAKE SURE your Debug window is open and RUN CallReadContacts(). LOOK at the
Debug window for results.

□ 11.INSPECT the fContacts feature.

ReadContacts() method:

function RecArray ReadContacts( string filepath )

/* Declare recarray to store contents of the file of contacts */

RecArray Contacts = RecArray.Create( { "firstname", \


"lastname", "email", "phonenumber", "customernumber"} )
record currentRecord

/* Open the file containing the contacts */

file contactsFile = File.Open( filePath,File.ReadMode )


if IsNotError( contactsFile )

/* Read a line of the contacts file */

string contactLine = File.Read( contactsFile )


while not File.EOF( contactsFile )

/* Convert line read from the contacts file to a list


and add it as a record to the allContacts recArray,
currentRecord points to the just added record */

currentRecord = Contacts[RecArray.AddRecord( Contacts, \


Str.Elements( contactLine, ',' ) )]

/* Change the datatype of the current record’s


customerNumber element to an integer */

currentRecord.customerNumber = \

Page 5-40 Open Text Corporation


Section 5: OScript

Str.StringToInteger(currentRecord.customerNumber)

contactLine = File.Read( contactsFile ) /*read next line */


end
File.Close( contactsFile )
else
Echo( contactsFile ) /* echo error */
end
return contacts
end

Livelink Builder Fundamentals Course Page 5-41


Section 5: OScript

CallReadContacts() method:

/* Call the utility you created passing it the name of the


contacts file you want to be processed. Save the results
in an fContacts feature you created */

.fContacts = $Contact.ContactUtils.ReadContacts( \
"c:\Builder Course files\contacts.txt" )

record contactRec

/* Echo the names of the columns of the contact recArray that


was stored in fContacts, putting tabs between each */

Echo( Str.Catenate( RecArray.FieldNames( .fContacts),\


Str.Tab() ) )

/* Loop through the recArray saved in fContacts, echoing out each


record */

for contactRec in .fContacts

Echo( Str.Catenate( RecArray.GetRecord( contactRec ), \


Str.Tab() ) )

end

Page 5-42 Open Text Corporation


Section 6: Making a Request Handler
Overview:

You now know what a request handler is, and you have used one to set up your module. Now
that you have had an introduction to OScript, it’s time to show you how to create new request
handlers to implement new functionality.

Objectives:

By the end of this section, you will be able to implement a


new function or request in Livelink by creating a request
handler. In the process, you will learn how to:

• Write requests that accept input arguments

• Generate output for the request, creating WebLingo


files

• Test and troubleshoot request handlers

Livelink Builder Fundamentals Course 92-300 04Feb11 Page 6-1


Section 6: Making a Request Handler

?func=user.edituser&userID=5644

Web Browser User


Web Server

Dynamically Generated
HTML File
1
Livelink CGI

$WebDsp.
2
RequestHandlerSubsystem
Object
Dispatch() method
fRegistry = <’admin.adminfactories=#180025f2,…
‘user.edituser’=#59000194, …>

4
edituser.html
WebLingo EditUser Request Handler
File Object Database
Execute() method
fHTMLfile string ----‘edituser.html’
3

Figure 6-1: Example of how a request handler is processed

Page 6-2 Open Text Corporation


Section 6: Making a Request Handler

6.1 Reminder of How Request Handlers Work

As we discussed in Section 2, each URL that is sent to


Livelink from a web browser contains a call to a request
handler. A request handler is an object that implements a
Livelink CGI function (i.e., “…livelink?func=…”). When
the Livelink CGI receives a request:

1. The Livelink CGI executes the Dispatch() method of


the RequestHandlerSubsystem object in the WebDsp
OSpace.

2. Using the data following the question mark in the URL,


the Dispatch() method locates the request handler For the LL Request
object for the function named in the URL by searching Handler object (the one we
the subsystem object’s fRegistry feature. orphan in this section), the
Dispatch() method of the
RequestHandlerSubSystem
3. Certain methods of the request handler object are object calls LL Request
executed. These methods contain calls to perform any Handler’s ExecuteRequest()
database transactions needed to gather or input data. method, which calls
ExecuteWithLogin(), which
The Execute() method does the majority of the work calls Execute().
that is unique to the function, sometimes calling
methods of other “utility” objects. Any data that is
gathered is stored in features of the request handler
object.

4. After processing the Execute() method, the request


handler uses the GenerateOutput() method to determine
the sort of interface that should be the result of the
request, be it a new HTML page, an error message, or a
redirection to another request handler.

5. In the case of an HTML page, the request handler


specifies which WebLingo file should be used to
dynamically generate the page. Livelink processes the
OScript embedded in the HTML page, displaying data
from the database by referring to the features of the
request handler in which it was stored (see step 3).

As you enhance Livelink, you will write code to create new


request handlers and to take advantage of existing request
handlers.

Livelink Builder Fundamentals Course Page 6-3


Section 6: Making a Request Handler

Figure 6-2: Some of the many descendants of WebDsp:WebDsp Root:RequestHandler

Page 6-4 Open Text Corporation


Section 6: Making a Request Handler

6.2 Subclassing a Request Handler Object

When you’re preparing to implement new code, you can


choose to subclass either the parent of all request handlers,
WebDsp:WebDsp Root:RequestHandler, or one of its
descendants:

• Subclassing the WebDsp: WebDsp Root:


RequestHandler object ensures that you’ll be working
“from scratch”, without many new or overridden
features. This choice is the easiest to upgrade—Open
Text developers may need to modify some of the other
request handler objects as they work on future versions
of Livelink.

• Subclassing the WebLL:LLRequestHandler object


gives you extra code which verifies whether the user is
logged in and automatically prompts the user to log in if
necessary. Most of the request handlers used in the end-
user interface are descendants of this object.

Some of your customizations may require orphaning


further descendants of the WebDsp:WebDsp Root:
RequestHandler. This may not be a good choice when
thinking of future upgradability, but may be unavoidable.
Here is a small sample of the request handler objects you
can consider orphaning in Livelink:

• Configure – Every Livelink module has a Configure


request handler object. Livelink calls these to perform
the install, upgrade and uninstall of a module.

• LL – Most user requests for accessing data in Livelink


are handled by the LL request handler object.

• DocRequestHandler – This is a class object. Its


children (there are many) handle requests for working
with documents in Livelink.

• UserRequestHandler – This is a class object. Its


children are used for most of the operations performed
on users and groups (such as adding, deleting, or
modifying).

Livelink Builder Fundamentals Course Page 6-5


Section 6: Making a Request Handler

Figure 6-3: Request handler example

Page 6-6 Open Text Corporation


Section 6: Making a Request Handler

6.3 Creating a Request Handler for New Code

After you decide which request handler object to subclass,


you can start to create your new request handler.

Step set 6.1: Creating a Request Handler

1. Create an orphan of the WEBLL:LLRequestHandler


object in your OSpace. We recommend that you name it
according to your OSpace name, in the format
YourOSpaceNameRequestHandlers.

2. Set the fFuncPrefix to a string prefix for your request


handler parent. The inherited value is ll; if you don’t
change this value, your request handler call will look
like this: …?func=ll.yourrequesthandlername…. (In
this example, we’re using suggestions for
fFuncPrefix. All request handlers we make as children
of this object will be called with the prefix
suggestions, for example,
?func=suggestions.getsuggestions).

3. Make a child of this new orphan and give it a name


appropriate to its function. (Our example is called
GetSuggestions.)

4. Set the fEnabled feature of your new request handler to


TRUE. You need to set the
fFuncPrefix feature before
you run SetRequestHandlers,
5. Run the SetRequestHandlers() method of your since the string in fFuncPrefix
RequestHandlerGroup object to register your new is a part of the registration of
request handler. the request handler.

Livelink Builder Fundamentals Course Page 6-7


Section 6: Making a Request Handler

Example Request Handler Object


Features:
0 Setup()
Documentation ------ “This object…”
ExecuteHandler()
Execute()
fArgs …'func=user.edituser&userID=1000&nextURL=%2FLivelink81d9
------------------ %2Flivelink%2Eexe%3Ffunc%3Duser%2Elistusers’…
fEnabled -------------- True
fErrorPrefix ----------- “Error accessing User edit page.”
fError ------------------ (Undefined)
fFuncPrefix ----------- “user”
fHTMLFile ------------ “edituser.html” (optional)
fHTMLLetter --------- “” (optional)
stHandlerSubsystem
Object

Figure 6-4: Key features of the Request Handler object (EditUser example)

Page 6-8 Open Text Corporation


Section 6: Making a Request Handler

6.4 Key Request Handler Features

Here are some of the other features that request handlers share. The ones that are most
commonly modified for customizations are highlighted in bold:

Documentation Text describing the request handler’s purpose. (Defined as a script to make it
easier to read.)

ExecuteHandler() Entry point for the request handler, directing the error checking, execution, and
output generation.

Execute() The method that performs database transactions (or calls other methods that
perform database transactions) and sets required request handler features.

fArgs A record of information passed back from the web browser.

fDownloadFile The file name of a file being sent to the client.

fDownload The MIME type of a file being sent to the client.


MimeType

fError If defined, Livelink will display its contents in an error page as the output for the
request handler instead of the defined HTML page. (Normally, you set this
feature to a string from within the Execute() method if an error occurs.)

fErrorPrefix A “header” message for an error page—displayed above the contents of fError
(if fError is defined).

fHTMLFile The name of the WebLingo file that generates the HTML page with the results
of the request.

fHTMLLetter If the fHTMLFile feature is not set, Livelink appends the request handler object
name to the string in fHTMLLetter and looks for a WebLingo file of this name to
generate the HTML page with the results of the request.

fLocation The URL to call after the Request Handler finishes executing (and before it
checks fHTMLfile or fHTMLLetter).

fPrototype A list of lists that define the datatypes of input arguments passed to the request
handler via the URL.

GenerateOutput() Determines the output to display, be it an HTML file, an error page, a file
download dialog box, or a different URL.

SetPrototype() Setup script for populating the fPrototype features.

Livelink Builder Fundamentals Course Page 6-9


Section 6: Making a Request Handler

?func=user.edituser&userID=5644&nextURL=TRUE

EditUser Request Handler Object


fPrototype -----------
{{'userID',integerType, ‘ID of the user to edit’,false},
{'nextURL', booleanType, ‘whether to return to calling page’, false}}

Figure 6-5: How the URL relates to the request handler’s fPrototype feature

{ "parentID", IntegerType, "parent ID number", FALSE, 2000, FALSE }

The name of the A description of the A default value


argument (a string) argument (a string) (optional)

The datatype of Whether the Whether the


the argument (an argument is optional argument is a
integer) (a boolean) list (boolean—
optional)

Figure 6-6: The elements of an element of the fPrototype feature

function void SetPrototype()

.fPrototype =\
{\
{ 'filepath', StringType,”The path of the file to read”, FALSE },\
{ 'nextURL', StringType, [WebUser_RHParam.NextURL], TRUE }\
}
end Xlate—you can
just use a string
Figure 6-7: Example SetPrototype() method constant

Page 6-10 Open Text Corporation


Section 6: Making a Request Handler

6.5 Request Handlers with Input Arguments

When a URL is sent to Livelink, Livelink looks for input


arguments, separated by ampersands (&). See Figure 6-5
for an example. The input arguments are converted from
“URL-escaped” text to strings and other datatypes and
stored in the fArgs feature of the request handler. The
fPrototype feature that is inherited by all request handlers
provides you with a means for specifying a sort of
“function header” for the request handler. The fPrototype
feature:

• verifies the datatypes of the input arguments, generating


an error message if they are incorrect

• converts the input arguments from strings (which is


how they are sent by the URL) to the appropriate
datatype

• assigns default values to any optional parameters The OScript constants that
represent the datatypes include:
The fPrototype feature is a list containing one list element IntegerType
StringType, BooleanType,
for each input argument. See Figure 6-6 for the details of DateType, ListType,
the list for each input argument. ObjectType, RealType. There
are others (see the Builder
The second element of the lists, which is the datatype of the online help) but the above listed
ones are datatypes that can be
argument, is most easily defined by passing one of the passed to request handlers in
OScript keywords representing datatypes. For this reason, the URL arguments.
use the SetPrototype() method in the request handler
object as a setup script for defining the fPrototype feature.
And don’t forget to run the method!

Step set 6.2: Defining Input Arguments for a Request Handler

1. Edit the request handler’s SetPrototype() method to


define the fPrototype list, using Figure 6-7 as a
guide.

2. Run the SetPrototype() method. If you like, open


the fPrototype feature to verify its contents.

If your request handler is sent a URL with parameters that


do not comply with the parameters defined by the
fPrototype feature, Livelink will generate an error message.

Livelink Builder Fundamentals Course Page 6-11


Section 6: Making a Request Handler

function Dynamic Execute( Dynamic ctxIn, Dynamic ctxOut, Record r )

Strin filepath = r.filepath


recarray suggestions Using the
arguDatabase
If IsDefined(filepath) sed to the request
suggestions = \
$Suggestions.SuggestionsUtils.ReadSuggestions(filepath)
end

If IsDefined(suggestions) \ New feature


and IsNotError(suggestions) to store the
.fSuggestions = suggestions results of the
else transactions
.fError = "Error loading suggestions"
end

return Undefined
end

Figure 6-8: Example Execute() method, using the r parameter to get data sent to the
request handler

Page 6-12 Open Text Corporation


Section 6: Making a Request Handler

6.6 “Making It Go”—the Execute() Method

While the ExecuteHandler() method of a request handler


drives the process of handling the request, it is the
Execute() method of the request handler that actually does
the work that is unique to the request handler. The
Execute() method serves as a “stub” for you to edit when
creating a new request handler.

The purpose of the Execute() method is:

• To perform any database transactions and other work


that is required, usually by calling methods of other
utility/package objects

• To direct Livelink to display any results

The Execute() method stores the results of the transactions


(especially those that are needed for the interface) in
features of the request handler. Developers often create
new features to store the results.

Common types of work that request handlers do:


Never change the
function header or the return
• Display tables of data statement of a request
handler execute method
• Open and display forms

• Save the data entered on a form

How the process arrives at the Execute() method depends


on the request handler, but all request handlers are passed a
very important record that contains the information sent
from the URL, as well as the session information (userid,
etc.), to the WebDsp: WebDsp Root: RequestHandler and
WebDsp: WebDsp Root: LLRequestHandler objects. This
record is named “r”. Other request handlers may use
different names for this record (for example, the LL request
handler uses “request”). The Execute() method uses the r
record to get values sent from the URL, then uses those
values in data transactions. See Figure 6-8 for an example.

Livelink Builder Fundamentals Course Page 6-13


Section 6: Making a Request Handler

Path
if .fError is defined (for example, “Couldn’t locate directory.”), then
display the error message in a dynamically generated page
else if .fDownloadFile is defined (for example, “out.txt”), then
download the file
else if .fLocation is defined (for examle, “http://www.corphome.com”) then
go to that URL
else make an HTML page,
using file named in fHTMLfile (for example, “listregions.html”)
or if fHTMLfile is undefined, using file name of fHTMLletter + objectname + “.html”
else
make up an error message and display it in a dynamically generated page

Figure 6-9: GenerateOutput() method’s logic

function Dynamic Execute( Dynamic ctxIn, Dynamic ctxOut, Record r )

String filepath = r.filepath


recarray suggestions

If IsDefined(filepath)
suggestions = \
$Suggestions.SuggestionsUtils.ReadSuggestions(filepath)
end

If IsDefined(suggestions) \
Setting new feature to
and IsNotError(suggestions) data to be used on
.fSuggestions = suggestions HTML page if there’s
else no problem
.fError = "Error loading suggestions"
end Setting fError to
trigger Error page
return Undefined if there’s a problem
end

Figure 6-10: Sample Execute() method, setting fError if there is a problem

Page 6-14 Open Text Corporation


Section 6: Making a Request Handler

6.6.1 Generating Output

After the Execute() method executes, the GenerateOutput()


method is called to create and display some sort of result in Actually, some request
the interface. The Execute() method must set features of the handlers don’t override the
request handler to trigger the proper behavior, especially Execute() method, but only set the
fHTMLFile feature. In this case,
the interface result (see Figure 6-9). the request handler simply
displays the page named by the
Step set 6.3: Editing the Execute() Method request handler. You’ll see this
most often in request handlers
whose purpose is to display an
1. If necessary, create new features in your request HTML form for entering new data.
handler to store the data gathered by the Execute()
method (in this example, a dynamic feature named
fSuggestions).

2. Edit the Execute() method of the request handler


and add the code to perform the request. (See Figure
6-10.) In the code:

a. Save any data you want to display as a result of


this request handler in the feature(s) you created
in step 1.

b. If there are errors, set fError to the error string


you want Livelink to display to the user.

c. If you want to redirect the client to another URL


instead of creating an HTML page dynamically,
set fLocation to the desired URL.

d. If you want to display a dynamically generated


HTML page:

• Set the fHTMLFile feature to the name of the


file. (You can set this feature from within your
Execute() method or by editing the feature
directly.) —OR—
Don’t forget to save and
• If you do not set fHTMLfile, Livelink will use export your OSpace.
the string in fHTMLLetter and combine it with
the name of your request handler object and use
this as the name of the HTML file to call after
the request handler executes.

3. Compile and save the method.

Livelink Builder Fundamentals Course Page 6-15


Section 6: Making a Request Handler

//
// Display the suggestion boxes
<html>

;recarray suggestions = .fsuggestions


;record suggestion ler
statements
<body>
<table>
<tr>
<td>Department</td><td>Subject</td><td>Contact</td>
</tr>

;for suggestion in suggestions


<tr>
<td>`str.string(suggestion.department)`</td>
<td>`suggestion.subject`</td>
<td>`suggestion.contact`</td>
</tr> expressions
;end

</table>
</body>
</html>

Figure 6-11: Example WebLingo file

Figure 6-12: Result of the WebLingo file

Page 6-16 Open Text Corporation


Section 6: Making a Request Handler

6.7 WebLingo Files—a Quick Introduction

WebLingo is the term used to describe the files that are a


combination of HTML and OScript.

If there are no error messages or other redirection, the


GenerateOutput() method directs Livelink to process the
WebLingo file and use it to dynamically generate an
HTML page.

The Weblingo file is treated as if it were a feature of the


calling request handler. In this way it can refer to the other
features of the calling request handler as siblings using the
dot notation.

In processing the file, Livelink assumes that each line of


code is HTML, unless it encounters some of the special
characters and other directives used to denote OScript.
There’s quite a bit to know about WebLingo, so we created
a separate section for it. To get you started, know that:

• Semi-colons (;) at the beginning of a line of code define


OScript statements, lines of OScript among lines of
HTML.

• Back ticks (`) define OScript expressions, segments of


OScript within a line of HTML.

Livelink Builder Fundamentals Course Page 6-17


Section 6: Making a Request Handler

…?func=suggestions.getsuggestions&filepath=c:\builder+course+files\suggfi
le.txt

Figure 6-13 The URL suffix to call the new request handler

Figure 6-14: The request handler’s result if no error

fErrorPrefix

fError (set by Execute() )

Figure 6-15: Possible request handler result if there is an error

Page 6-18 Open Text Corporation


Section 6: Making a Request Handler

6.8 Testing a Request Handler

When your request handler is ready for testing, exit and


restart the Builder, launch your web browser, and enter the
URL that will trigger the request handler, in the form:
http://localhost/LivelinkInstallationName/
livelink.exe?func=funcprefix.requesthandlerName

If you subclassed the LLRequestHandler object, you will


be prompted to log in, and if all goes well, you will see the
results of your request handler.

In Section 8, we’ll show you one way to tie the URL into
the interface, so that you (and other users) don’t have to
type it manually.

6.8.1 Troubleshooting Request Handlers

Some of the most common problems developers encounter:

Web browser “hangs.”

Take a look at the Builder—there’s probably a Debugger


window frontmost, pointing to a line of code it finds
“offensive”. This is usually traced to a problem in your
Execute() method.

“Server did not respond” error.

Livelink tried to execute the request handler, but it


encountered an untrapped error condition. Set “break on
entry” on your Execute() method and step through the code.

“Error dispatching request. Invalid function


"samp.badrhname."”

Livelink looked in the RequestHandler subsystem’s


fRegistry feature and did not find an entry for the function
you entered. First make sure you typed the correct URL.
Then, check the Request Handler Group’s
fRequestHandlers feature to verify that your request
handler is there. (See Section 6.2 for a refresher.)

Livelink Builder Fundamentals Course Page 6-19


Section 6: Making a Request Handler

6.9 Summary

• When Livelink receives a request, it searches the


fRegistry feature of the Request Handler Subsystem in
the WebDsp OSpace to locate the request handler
object to execute.

• The fRegistry feature is generated during system


startup, by methods which locate all of the “registered”
request handler objects in each OSpace.

• The SetRequestHandlers() method in each OSpace’s


Request Handler Group object searches the OSpace for
all request handlers and “registers” them by adding
them to an fRequestHandlers feature of the object. You
must remember to run this method as you develop
request handlers.

• When you want to make a request handler, you need to


decide which request handler variant to subclass. Most
commonly, you’ll subclass LLRequestHandler.

• The ExecuteHandler() method of a request handler is


the entry point for the request handler’s execution. This
method, and the methods it calls, use various features of
the request handler to determine the path of execution.

• The Execute() method of the request handler is a


developer’s main point of customization. This is where
the request handler does database transactions and
directs the result by setting the fError, fDownloadFile,
or fLocation features—or by letting the request handler
proceed to process the WebLingo file named in the
fHTMLFile feature.

• A WebLingo file is a combination of OScript and


HTML that is “preprocessed” by Livelink when
triggered by a request handler. A WebLingo file
dynamically generates an HTML page using data stored
in features of the request handler.

Page 6-20 Open Text Corporation


Section 6: Making a Request Handler

6.10 Section 6 exercise

Make a request handler whose execute method will call the utility script you created in the
last section, and pass it the same external file path. Create an fResponse feature in your
request handler. Have the Execute() method save the returned value of that script in an Assoc
called response.data.contacts, and save that assoc in the fContacts feature you created.

6.10.1 Part A: Making Your Request Handler Work

□ 1. ORPHAN the WEBLL : LLRequestHandler object, calling it


Contact RequestHandlers.

Note: you could have orphaned the WEBDSP : WebDsp Root : RequestHandler
instead. Why wouldn’t you?

□ 2. Set fFuncPrefix = contact, so that calls to the child request handlers will have the
format “?func=contact.requesthandlerName”.

□ 3. MAKE a child of the Contact RequestHandlers object and call it GetContacts.

□ 4. SET GetContacts.fEnabled = True.

□ 5. RUN the SetRequestHandlers() method of your RequestHandlerGroup object, then


INSPECT the fRequestHandlers feature to see the change.

□ 6. ADD a new dynamic feature to your GetContacts request handler to store the results
of the request. Call this new feature fContacts, and leave it Undefined.

□ 7. EDIT the SetPrototype() method to set GetContacts.fPrototype:


DEFINE a filepath string parameter for the request handler. (See the solution at the end
of this set of steps if you’d like an example.) RUN the method, and inspect the
fPrototype feature to verify its results.

□ 8. EDIT GetContacts.Execute():

• After the function declaration, DECLARE an Assoc variable in which to store contacts
information.

• CALL the ReadContacts() utility method you created.

• READ the filepath argument that is passed to the request handler (remember how to use
the r parameter?), and PASS it to ReadContacts().

• ASSIGN the return value of ReadContacts() to the contacts variable.

Livelink Builder Fundamentals Course Page 6-21


Section 6: Making a Request Handler

• If the file was read successfully, ASSIGN the value of the contacts variable to the
fContacts feature you created earlier. If the file was not read successfully, SET
GetContacts.fError to an error string that should be displayed.

□ 9. COMPILE and SAVE the Execute() method.

6.10.2 Example solutions to Section 6

SetPrototype() method:

.fPrototype = { \
{ "filepath", StringType, "the name of the file to read", FALSE }}

Example Execute() method:


function Dynamic Execute( Dynamic ctxIn, Dynamic ctxOut, Record r )

recArray contacts

String filepath = r.filepath

If IsDefined(filepath)
contacts = $Contact.ContactUtils.ReadContacts(filepath)
end
If Length(contacts) > 0
.fcontacts = contacts
else
.fError = "No contacts or Error reading contacts file."
end

return Undefined
end

6.10.3 Part B: Tying in the HTML

Create an HTML file to show the results of your request handler.

□ 1. CHOOSE one of these options for specifying the name of the HTML file which will
display the request handler results:

• You can set the fHTMLFile feature of your GetContacts request handler to be the name
of the HTML file you want called after your request is completed (consider
contacts.html).

• You can set the fHTMLLetter feature of your GetContacts request handler to be the first
part of the name of your HTML file and Livelink will automatically append the request
handler object name (GetContacts) to this prefix when searching for the HTML file.
Again, a good option for fHTMLLetter is the name of your module—so if you set

Page 6-22 Open Text Corporation


Section 6: Making a Request Handler

fHTMLLetter to contacts, the HTML file name would be


contactsgetcontacts.html.

□ 2. Using the Script Editor or another text editor, CREATE the WebLingo file that will
display the results of your request handler.

• Use a table to OUTPUT the results of your request handler. Remember, you stored the
results (a RecArray) in a feature called fContacts.

• The first row of the table should be your column headings, and each row after the
heading should be a contact record.

Here is a very basic example of what the code could look like:
;RecArray contactsArray = .fcontacts
;record contact

<html>
<body>
<table border=1>
<tr>
<td><b>Name</b></td>
<td><b>Email</b></td>
<td><b>Phone Number</b></td>
<td><b>Customer Number</b></td>
</tr>
;for contact in contactsArray
<tr>
<td>`contact.lastName`, `contact.FirstName`</td>
<td>`contact.email`</td>
<td>`contact.phoneNumber`</td>
<td>`Str.String( contact.customerNumber)`</td>
</tr>
;end
</table>
</body>
</html>

□ 3. SAVE the WebLingo file in your module’s HTML directory, and give it a name
according to the option you selected above (1a or 1b).

□ 4. SAVE and EXPORT your OSpace, and STOP and START the Builder.

□ 5. TEST your work: From your web browser, ENTER the Livelink URL that calls your new
request handler. Remember, you’ll have to include a parameter for the path of the file
your request handler is going to read. Use a + in place of any spaces in the file path.
For example:
http://localhost/Livelink/livelink.exe?func=contact.GetContacts
&filepath=c:\Builder+Course+Files\contacts.txt

Livelink Builder Fundamentals Course Page 6-23


Section 6: Making a Request Handler

The results should look something like this:

Page 6-24 Open Text Corporation


Section 7: Taking Advantage of WebLingo
Overview:

WebLingo gives you infinite possibilities for creating a user interface that is based on
Livelink content and graced with Livelink’s look and feel. You’ve had an introduction to
how WebLingo files are called by request handlers—now it’s time to show you the details.

Objectives:

By the end of this section, you’ll be able to write and call


“WebScripts” in your WebLingo files. In the process,
you’ll learn how to:

• Read the webscripts and webscript calls in the off-the-


shelf WebLingo files

• Understand and use special characters in your


WebLingo files

• Compile and debug WebLingo files

• Override Livelink pages

Livelink Builder Fundamentals Course 92-300 04Feb11 Page 7-1


Section 7: Taking Advantage of WebLingo

commonheader.html
infoproperties.html displays header
is the “driving” page
Another HTML page
infotabs.html drives each tab—for
displays tabs example,
infoaudit.html displays
audit tab
menufoot.html
displays footer

Figure 7-1: How Info pages are built

browseheader.html sets up
args and calls browsesearch.html displays
browse.html commonheader.html search bar if appropriate
is the “driving” page

commonheader.html
displays header and
calls other webscripts dashboards.html displays
navigation dropdowns

browseimages.html displays
any images (named in
Presentation tab)

looks for customview.html in folder and


displays if there (not a webscript)

browsecatalogs.html displays
catalog items if appropriate

browseview.html displays
list of items if appropriate

menufoot.html
displays footer

Figure 7-2: How browser pages are built

Page 7-2 Open Text Corporation


Section 7: Taking Advantage of WebLingo

7.2 Example Livelink Pages

Livelink makes extensive use of webscripts to build its


interface. Figure 7-1 and Figure 7-2 illustrate how some of Some of the webscript
Livelink’s key pages are built. files that the developers have
created contain
Most Livelink pages displayed generate a header that documentation describing
what the file does as well as
displays the current location, the Livelink logo, and the the arguments that can be
Help icon. This is all accomplished via a call to the passed in.
commonheader.html file. Commonheader.html also calls Commonheader.html is a
good example of this.
many other webscript files to display things like the Search
Bar, the news ticker, and the Navigation menus.

Commonheader.html accepts arguments specifying settings


such as the color of the header, the titles to be displayed
within the header, and the icon to display at the far left. When creating your own
HTML pages ensure the body
Most Livelink pages also display a footer containing tag contains the onLoad
Livelink version information and a copyright boilerplate. function:
This footer is generated by a call to the menufoot.html <BODY ONLOAD=
"onLoadFunction()"> This
webscript. allow the navigation menus to
operate correctly

Livelink Builder Fundamentals Course Page 7-3


Section 7: Taking Advantage of WebLingo

;;webscript IMasthead( string title1, string title2, boolean adminHelp =


FALSE, String gif = 'icon_info.gif', boolean noSearchDate = Undefined,
boolean noGlobalMenu = Undefined, boolean noFunctionPopup = Undefined,
boolean noTicker = TRUE )
Two string input arguments
<!-- File: webnode/imasthead.html --> must be passed to the
webscript
;Assoc args

;args.ImageURL = .IMG() + gif


;args.ImageAlt = [WebNode_HTMLLabel.InfoAltImage] ;;webscript
directive used to
;args.Title1 = title1
define a “function
;args.Title2 = title2 header”
;args.BGColor = "#666666"
;args.search = Assoc.CreateAssoc()
;args.search.fromHere = FALSE
;args.search.ID = .fResponse.data.nodeRec.DataID
;args.search.Name = .fResponse.data.nodeRec.Name

;if IsDefined( noSearchDate )


;args.noSearchDate = noSearchDate
;end

;if IsDefined( noGlobalMenu )


;args.noGlobalMenu = noGlobalMenu
;end

;if IsDefined( noFunctionPopup )


;args.noFunctionPopup = noFunctionPopup
;end

;args.noTicker = noTicker
This webscript
;if adminHelp calls another
;args.HelpParams = "&adminHelp" webscript
;end

;;call <.HTMLPrefix() + 'commonheader.html'>( args )


;;end directive to end the webscript (required, just like the end keyword in a function)
;;end

Figure 7-3: The imasthead.html file, which contains the webscript used for the header on
most Livelink Info pages

Page 7-4 Open Text Corporation


Section 7: Taking Advantage of WebLingo

7.1 Writing WebScripts

Most Livelink pages use the same header and footer, with a
few variations. For this and many other aspects of the
All Webscript
interface, Livelink uses webscripts. A webscript is a
directives are case-
WebLingo file which you can call from other WebLingo
files and to which you can pass input arguments—in other
words, a webscript is a WebLingo function.

There are three WebLingo directives for creating and An Xlate is a placeholder
for a localized string that is part
calling webscripts: of the text of the user interface.
This allows the same WebLingo
• ;;webscript indicates the start of a webscript. The file or other script to be used for
Livelink in English, French,
webscript directive is analogous to the Function header Japanese and other languages.
of a script feature.
If you want to see the text
stored for an Xlate, select its
• ;;end indicates the end of a webscript. text from the Script Editor, then
choose Open Xlate from the
• ;;call is used to direct Livelink to insert the “processed” Script menu.
contents of a webscript at the point of the call.

The two other directives


7.1.1 Defining a Webscript used in Livelink include:

;;oscript, used to denote a


A webscript declaration begins with the syntax: block of OScript within a block
of HTML.
;;webscript name ( datatype p1, datatype p2, … )
Syntax:
You can specify the datatype for each input argument, as in ;;oscript {oscript statements;;}
the example in Figure 7-3 (optional). Input arguments can ;;html, used to denote a block
also be defaulted. of html within a block of OScript.

Syntax:
;;html{html statements;;}

Livelink Builder Fundamentals Course Page 7-5


Section 7: Taking Advantage of WebLingo

<HTML>
<!-- File: webnode/info.html --> HTMLPrefix() returns
<!-- RequestHandler: ll --> the path to this file’s
html directory
;Assoc element

;String htmlPrefix = .HTMLPrefix()


;String superHTMLPrefix = .Module( 'webnode').HTMLPrefix()
;String img = .Img()
;Dynamic request = .fRequest
Module() returns the
;Assoc response = .fResponse
Module object for the
;String url = .URL() specified module

;Assoc data = response.data


;Record nodeRec = data.nodeRec
;Object webNode = request.webNode

;String title = Str.Format( [WebNode_HTMLLabel.SpecificInfoFor1_],


nodeRec.name )

<HEAD>
<TITLE>`title`</TITLE>
…snip
<BODY BGCOLOR="#FFFFFF" BACKGROUND="`img`pattern.gif"
ONLOAD="resetPopup()">

;;call <superHTMLPrefix + 'imasthead.html'>(


[WebNode_HTMLLabel.SpecificInfoFor_], nodeRec.name )
Xlate containing a string
Figure 7-4: The info.html page’s call to imasthead.html with the page’s title in
the proper language. (In
English, the string is
“Specific Info For”.)

Page 7-6 Open Text Corporation


Section 7: Taking Advantage of WebLingo

7.1.2 Calling a Webscript


;;call < pathToFile + nameOfFile >( arguments )

The HTMLPrefix() method of the calling request handler


returns the path to the request handler’s module’s html
directory, and this is often used to define the path to the
file. See Figure 7-4 for an example.

Livelink Builder Fundamentals Course Page 7-7


Section 7: Taking Advantage of WebLingo

<TD NOWRAP ALIGN="LEFT" VALIGN="MIDDLE">


<FONT COLOR="`titleColor`" FACE="`[WebDsp_Font.SansSerif]`">
`%Lspacer``%Largs.Title1``%Lspacer`
</FONT>
</TD>

These variables may contain HTML tags, for


example, “<B>”—%L prevents them from being
“escaped”, for example, to “&lt;B&gt;”

Figure 7-5: Example of using %L in commonheader.html

Page 7-8 Open Text Corporation


Section 7: Taking Advantage of WebLingo

7.2 Special Characters

In addition to using:

• A semi-colon (;) to define OScript statements

• Back-ticks (`) to delimit expressions, segments of


OScript within a line of HTML

You can also use:

• %L to define special HTML characters that you do not


want Livelink to process as OScript. (L stands for
“literal”.) This is case sensitive.

• % to delimit a line of HTML within a block of OScript

Livelink Builder Fundamentals Course Page 7-9


Section 7: Taking Advantage of WebLingo

Figure 7-6: Debugger debugging a WebLingo file

Page 7-10 Open Text Corporation


Section 7: Taking Advantage of WebLingo

7.3 Compiling and Debugging WebLingo Files

Once you’ve saved a WebLingo file with an HTML


xtension, you can compile its OScript (but not its HTML)
from the Script Editor. When you compile a
WebLingo file it saves the file
regardless of compiler errors.
Use the Debugger to help you debug WebLingo files. To When you compile an
debug a WebLingo file: external script, you must
manually save it.
• Open the WebLingo file from the Script Editor and
choose Break on Entry from the Script menu.

• Enter the line Scheduler.DebugBreak() anywhere in


the WebLingo file.

Trigger the execution of the file by calling its request


handler. When the call to the WebLingo file is made, the
Debugger opens to display the file and allows you to step
through it.

Livelink Builder Fundamentals Course Page 7-11


Section 7: Taking Advantage of WebLingo

Figure 7-7: Excerpt from a CSS

A call to .Styles()

The class attribute (note cascade)

Figure 7-8 A weblingo file using CSSs

Page 7-12 Open Text Corporation


Section 7: Taking Advantage of WebLingo

7.4 Cascading Style Sheets (CSS)

Version 9.2 of Livelink introduces the use of CSSs.

• CSS provide for design flexibility and


customizability. CSSs, when supported by correct
classification of elements, enables GUI developers a
fast and easy way to experiment and make changes
to the look and feel of Livelink.

• Cascading style sheets also aids GUI


standardization. Consistency will no longer be
managed through the 'cut-and-paste' method.

CSS allow you to specify formatting information in two


ways: (see Figure 7.7)

1. For specific HTML Tags and

2. For CLASSES

Livelink Builder Fundamentals Course Page 7-13


Section 7: Taking Advantage of WebLingo

Figure 7-9A: Modified CSS showing the @import statement

Figure 7-10: The Configure RH’s DoCustomSetup method

Figure 7-11: The DoSubclassUninstall method

Page 7-14 Open Text Corporation


Section 7: Taking Advantage of WebLingo

7.5 Overriding Cascading Style Sheets

You can override existing HTML formatting as well as


create new HTML formatting.

7.5.1 To override and/or add module-specific formatting:

1. Create a new CSS file in your module’s support


The feature
directory with the formatting you want. fModuleStyleSheetFiles is found
only in request handlers. If you
2. Modify the fModuleStylesheetFiles feature of your wish to specify a module-specific
request handler to include the name of the CSS. CSS from a webNode or
webNodeAction object you must
use the feature fStyleSheetFiles.
3. Ensure all new weblingo files include the line: Note that you need to specify only
`%L.Styles()` the name of the CSS and not the
path to it. (see the method
.StyleSheetFiles().)
in the <head></head> region.

7.5.2 To override and/or add system-wide existing formatting:

Step set 7.1: To add a new CSS when your module is installed. And remove it again
when your module is uninstalled.

1. Create a new folder in your module called css and


create a new css file in that folder.

2. Add your new formatting instructions and the


import statement to the new css file
@import url("livelink.css");

3. Update the fFilesToCopy feature of the Webmodule


object to copy your css file to the support directory
{{'%3css%1','%4%1'},{'%3support%1','%4%5%1'}}

4. Modify the DoCustomSetup method in the


Configure RH to rename the files. See figure 7.10.

5. Edit the WebModule’s DoSubclassUninstall method


to remove your custom css when your module is
uninstalled. See figure 7.11.

Livelink Builder Fundamentals Course Page 7-15


Section 7: Taking Advantage of WebLingo

Figure 7-12: Livelink header before and after commonheader.html file change

;;webscript CommonHeader( Assoc args )


<!-- File: commonheader.html -->
<A NAME="top"></A>

<TD ALIGN="RIGHT" VALIGN="MIDDLE">

<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="0" WIDTH="100%" HEIGHT="20"


BGCOLOR="ORANGE"><TR>
<TD><FONT SIZE=2><A HREF="http://www.opentext.com"><FONT COLOR="#000000"
FACE="ARIAL"><B>Open Text</B></FONT></A></FONT></TD>
<TD><FONT SIZE=2><A HREF="http://www.thomascook.com"><FONT COLOR="#000000"
FACE="ARIAL"><B>Travel Agent</B></FONT></A></FONT></TD>
<TD><FONT SIZE=2><A HREF="http://www.cnn.com"><FONT COLOR="#000000"
FACE="ARIAL"><B>Headlines</B></FONT></A></FONT></TD>
<TD><FONT SIZE=2><A href="http://www.shoponline.com"><FONT COLOR="#000000"
FACE="ARIAL"><B>Go Shopping</B></FONT></A></FONT></TD>
</TR></TABLE>

</TD>
;;end

Figure 7-13: WebLingo file change example: commonheader.html

Page 7-16 Open Text Corporation


Section 7: Taking Advantage of WebLingo

7.6 Overriding Livelink Pages

Changing Livelink’s HTML pages is not a supported


customization, but we know many of you may need to do
this in order to achieve the results you desire. If you make a
change to one of Livelink’s source WebLingo pages, even a
minor one, it is imperative that you keep a log of all your
You can also change the
changes and back up the original WebLingo file. It is also GIFs used in the interface—
important to understand that you may have to redo some or with the same cautions we
all of your changes when installing a future release of mention at left
Livelink.

To locate the HTML file, display the file in your web


browser and then use your web browser command to view
the page source. Most Livelink HTML pages contain a
comment at the top that specifies the name and the module
for the file. Locate the module’s html directory and look for
the file there.

Remember that you can make significant customizations to


any folder’s interface (including the root folder of the
Enterprise, Personal, and Project workspaces) without
using the Builder at all. You can add a file called
customview.html to the folder, and Livelink will
automatically use the content as a “header” for the folder’s
browser page.

Livelink Builder Fundamentals Course Page 7-17


Section 7: Taking Advantage of WebLingo

7.7 Summary

• You can use the ;;webscript directive to create a


WebLingo file that can be called by other WebLingo
files via the ;;call directive. The ;;webscript directive
allows you to define input arguments, making the
webscript into a sort of function.

• Livelink uses webscripts extensively for the parts of its


interface that are re-used—such as page headers and
footers, the tabs on the Info page, and more.

• In addition to the ; character for statements and the `


operator for expressions, you can use the %L for literal
expressions and the % character to delimit fragments of
HTML in a line of OScript.

• You can compile and debug the OScript in WebLingo


files once the file is saved with an HTML extension.

• Many Livelink customers want to add their own


touches to the interface. You can edit the HTML files
that form the Livelink interface—but you’re tampering
with the “source code” of the interface, so track your
changes and be prepared to do them again in the next
version of Livelink.

Page 7-18 Open Text Corporation


Section 7: Taking Advantage of WebLingo

7.8 Section 7 exercise

7.8.1 Part A: Adding the Common Elements of a Livelink Page

Modify the WebLingo file you created in the previous exercise to output the standard Livelink
header and footer with your contacts in between. Feel free to experiment and exercise your
HTML skills here.

□ 1. In the Builder, OPEN the WebLingo file you created in the last exercise.
How: File menu → Open, navigate to your module’s html directory and double-click
the file name. (Or if you created it from the Builder in the first place, you’ll see it in the
File menu → Recent submenu.)

• ADD the required code in the appropriate spot to call the commonheader.html WebLingo
file, passing it arguments to define the title and background color.

To learn what arguments can be used, open the LLHOME/HTML/commonheader.html


file and read the documentation near the top of the file. If you would like to look at
an example, see the sample solution on the next page.

• Near the end of your new WebLingo file, CALL the menufoot.html webscript to display
a standard Livelink footer at the bottom of the Contacts page. The menufoot WebScript
is in the same directory as commonheader.html and requires no arguments.

□ 2. COMPILE and SAVE the WebLingo file.

□ 3. Now GO to your web browser and ENTER the Livelink URL that will call your request
handler. The results should look something like this:

Livelink Builder Fundamentals Course Page 7-19


Section 7: Taking Advantage of WebLingo

Example Solution—Your Weblingo file, calling commonheader and menufoot:


;recarray contacts = .fcontacts
;record contact

<html>
<head>
`%L.Styles()`
</head>
;string htmlPrefix = .HTMLPrefix()
;assoc args
; args.Title1 = "CONTACTS"
; args.BGcolor = "pink"

;;call <htmlPrefix + "commonheader.html">( args)


<BODY ONLOAD="onLoadFunction()"> // Because this line is Javascript
// it is case sensitive
<table border = 1>
<tr>
<td><b>Name</b></td>
<td><b>Email</b></td>
<td><b>Phone Number</b></td>
<td><b>Customer Number</b></td>
</tr>
;for contact in contacts
<tr>
<td>`contact.lastName`, `contact.FirstName`</td>
<td>`contact.email`</td>
<td>`contact.phoneNumber`</td>
<td>`contact.customerNumber`</td>
</tr>
;end
</table>
;;call <htmlPrefix + "menufoot.html">()
</body>
</html>

7.8.2 Part B: Modifying Existing HTML Pages

Back up and then edit the commonheader.html file. Add some extra code to
commonheader.html that will give this page a unique company look (like our class example).

□ 1. NAVIGATE to your Livelink installation’s main HTML directory and MAKE A BACKUP
copy of commonheader.html.

□ 2. From the Builder, OPEN the commonheader.html file and ADD CODE to display a
corporate banner.
If you would like to base your code on the class example, the banner from the lecture is
on the CD in \student solutions\section7\banner.txt.

Page 7-20 Open Text Corporation


Section 7: Taking Advantage of WebLingo

□ 3. COMPILE the file (Builder will auto save it on successful compilation).

□ 4. GO to your web browser and OPEN a Livelink page to see your changes. How do they
look?

7.8.3 Part C: Creating your own CSS

Create a new CSS to customise your table column headings.

□ 1. EDIT the livelink.css file in the support directory and copy the lines for the label class.
Create a new CSS file in your module’s support directory called contacts.css and
paste the copied label class.
/*
The style to use for the label part of the label/value pair.

Use with:
<TD>
*/
.label {
width: 15%;
white-space: nowrap;
color: #434343;
background-color: #e2e2e2;
border-left: 1px solid #ffffff;
border-top: 1px solid #ffffff;
border-right: 1px solid #999999;
font-family: Tahoma, Verdana, Geneva, Arial,
Helvetica, sans-serif;
text-align: left;
font-weight: bold;
font-size: 11px;
}

□ 2. Edit the .fModuleStyleSheetFiles feature in your GetContacts request handler to


include the name of your new CSS.
{'contacts.css'}

□ 3. Modify your weblingo file to include the label class for the table column headings.
<tr class="label">

□ 4. Save all your work. Now GO to your web browser and ENTER the Livelink URL that
will call your request handler. How does your table look?

□ 5. Experiment with different colors, etc.

Livelink Builder Fundamentals Course Page 7-21


Section 7: Taking Advantage of WebLingo

Notes:

Page 7-22 Open Text Corporation


Section 8: Plugging into the Livelink Interface
Overview:

Now that you have a working request handler, you can type its URL to run it—but you are
not going to want to ask your users to do that. There are a number of ways to plug your
request handler into the Livelink interface; we’re going to start by showing you how to add
items to the Enterprise menu, which is an example of a navigation menu.

Objectives:

By the end of this section, you will be able to add module-related commands to the
Enterprise, Personal, and other navigation menus.

Livelink Builder Fundamentals Course 92-300 04Feb11 Page 8- 1


0 Section 8: Plugging into the Livelink Interface

Figure 8-1: A Livelink page showing the navigation menus designed to be easily enhanced

Page 8-2 Open Text Corporation


0 Section 8: Plugging into the Livelink Interface

8.1 Ways to Hook Your Work into Livelink

Some aspects of Livelink were designed to make it easy for


you to hook in your own work. With very little work, you
can add:

• Commands to the navigation menus


• Sections to the About Livelink page
• New types of nodes
• New commands to existing types of nodes
• Store and update additional data in the database

In this section, we will show you an example of this sort of


customization by adding commands to the navigation
menus.

8.2 The Navigation Menus

The navigation menus that appear near the top of each


Livelink page are used to navigate to the main areas of
Livelink. You can add commands to these menus by
orphaning and setting features of the WebLL: WebLL Root:
NavigationCallback: LivelinkNavigationCallback object.
Descendants of this object control the contents of these menus.
The enabled descendants of this object are registered with
the Livelink Navigation Callback Subsystem.

Step set 8.1: Subclassing and Enabling the


NavigationCallback Object Reminder: The Startup()
method of an OSpace’s Root
object is automatically
1. Make an orphan of the WebLL: WebLL Root: executed whenever the
NavigationCallback: LivelinkNavigationCallback OSpace is opened, and this
object in your OSpace. The naming convention is method processes the
.f_InitObjects feature of your
ospaceNameNavigationCallback. Globals object to run the
_Init() method of each object
2. Set the orphan’s fEnabled feature to TRUE, then that requires initialization—
such as the
run the BuildOSpace() method of your NavigationCallback object.
OSpace’s Globals object.

Livelink Builder Fundamentals Course Page 8-3


0 Section 8: Plugging into the Livelink Interface

The first two letters in the


key indicate the menu the
item will appear in:
09 – project
10 – personal
11 – Enterprise
12 – Tools
xx – Others

All letters after the


The third letter in the key third and before
indicates the section of the “.” in the key
the menu the item indicate where,
belongs: within the order of
1 – first the section, the
2 – second item will appear.
3 – third
y – others

Figure 8-2: How the key indicates where items will appear in the navigation menus

Menu Label Key

Personal Workspace 10110.0

Enterprise Workspace 11110.0

Projects 09110.0

Workflow Status 102300.0

Users and Groups 11120.0

Figure 8-3: Keys for some of the items that populate the navigation menus

Page 8-4 Open Text Corporation


0 Section 8: Plugging into the Livelink Interface

8.3 How the Menu Commands are Identified

Items in the navigation menus are each assigned a key. This


key is used to determine which menu, and where in that
menu the new menu item will appear (see Figure 8-2).

All new navigational item keys should be in the following


string format:

xxyzzzz.0

Key Controls Rules

xx The navigation You can add your new item to


menu in which existing menus by using their
the item appropriate value: These hooks allow you to add
appears 09 – Project menu items as your module is
installed, including items that map
10 – Personal to new request handlers you have
11 – Enterprise created.
12 – Tools
Without any customization on
xx – Others your part, your system
administrators can add static,
y The section of Use an existing section’s numeric fixed, per-Livelink-installation links
the chosen key or create your own section in to the Enterprise menu by using
menu in which that navigation menu by using an commands on the Administration
the item unused section key. pages.
appears

zzzz Where in the Use an alpha key in


section the item customizations. Numeric keys are
appears reserved for developers, and
there is a risk of colliding with
Open Text menu items if you use
a numeric key.

0 Indicator for 0 indicates no subitems.


subitems Currently used for function
menus only.

Livelink Builder Fundamentals Course Page 8-5


0 Section 8: Plugging into the Livelink Interface

These URLs have no dynamic arguments and can be used in the navigation menus:

http://www.opentext.com/training

http://myserver/livelink/livelink?func=ll&objId=2126&objAction=browse
&sort=name

This URL cannot be used in the navigation menus because its nextURL argument
normally changes each time the URL is called:

?func=ll&objId=2126&objAction=properties&nexturl=%2FLLV8%2Flivelink%3
Ffunc%3Dll%26objId%3D2126%26objAction%3Dbrowse%26sort%3Dname

Figure 8-4: Examples of URLs that can and cannot be added to the navigation menus

Page 8-6 Open Text Corporation


0 Section 8: Plugging into the Livelink Interface

8.4 Navigation Menu Caching and URLs

Livelink’s navigation menus are built by the Livelink The items added to the
Navigation Callback Subsystem’s Items() method the first Enterprise menu by system
administrators are also
time a Livelink page is accessed after startup. For stored in fItems. The
performance reasons, the Items() method caches the menus administrator is required to
in the fItems feature of the same object. This includes each stop and restart Livelink to
see the changes take
menu item’s URL. The fItems feature is not rebuilt until the effect.
server is restarted. As a result of this caching, the URLs
used in the Navigation menus must be constant and cannot
require any dynamic arguments.

Livelink Builder Fundamentals Course Page 8-7


0 Section 8: Plugging into the Livelink Interface

function Assoc Execute( Object prgCtx, Record request )


This assoc is populated with
an assoc for each item to
Dynamic apiError add to the navigation menus.
String errMsg
Assoc items This code returns the base
Assoc retVal URL for the Livelink site.
Boolean ok = TRUE
String scriptName = request.SCRIPT_NAME
Use the _NewItem() method to
Assoc item_sugg = ._NewItem() declare and pre-populate the assoc
for the new menu command.
item_sugg.url = \
Str.Format("%1?func=suggestions.GetSuggestions&filepath=%2",\
scriptName, Web.Escape("C:\Builder Course Files\suggestions.txt") )
item_sugg.name = "Suggestions"
items.( '11' + .mSectionOne + "Suggestions" + ".0" ) = item_sugg

//items = Undefined Set an assoc element named “url” to


the URL for the new command.
if ( IsUndefined( retVal.ok ) )
retVal.ok = ok Set an assoc element named “name” to the text
retVal.apiError = apiError to be displayed in the menu for the command.
retVal.errMsg = errMsg
retVal.items = items Add a new assoc to the items assoc, naming it
end using the key as described in the previous pages.

return retVal
(The inherited script contains this line—you may
end want to delete it.)

Figure 8-5: Modified Livelink NavigationCallback.Execute() script

Menu Label URL Key

Personal Workspace '?func=ll&objtype=142&objaction=browse' 10110.0

Enterprise Workspace '?func=ll&objtype=141&objaction=browse' 11110.0

Projects ?func=personal.projects 09110.0

Workflow Status ?func=work.status 102300.0

Users and Groups ?func=user.listusers 11120.0

Figure 8-6: Some of the items that populate the navigation menus

Page 8-8 Open Text Corporation


0 Section 8: Plugging into the Livelink Interface

8.5 Defining the Menu Command’s Result

The LivelinkNavigationCallback.Execute() method adds


elements to a data structure that is returned to the Livelink
Navigation Callback Subsystem to build the navigation
menus. This structure, called the items assoc, contains an
assoc for each of the commands in the navigation menus.

For each menu command:

• The name of the assoc in the items assoc is the key The Web.Escape()
discussed in section 8.3. built-in function converts a
string to URL format by
“escaping” non-alphabetic
• The assoc has two elements: name to store the menu characters into URL
command name, and url to store the command to hexadecimal sequences and
by converting spaces to the
execute. “+” sign. You will want to use
this function when you need
Step set 8.2: Edit the NavigationCallback.Execute() to include strings as
Method arguments in a URL.

1. In the NavigationCallback.Execute() method, call


the _NewItem() method to declare an assoc for the
menu item name and URL. (This method returns an To make your coding
easier, if the URL does not
assoc with the proper format for adding menu start with “http” or “https”,
items.) Livelink will automatically
prefix the URL with the server
“base” URL (such as
2. Add the code necessary to declare and set the values http://x.x.com/Live
for the name and url elements of the assoc. (See link).
Figure 8-5 for an example.)

3. Write the code to add the new assoc to the items


assoc. Name the assoc according to where you want
it to appear in the navigation menus. In the example
in Figure 8-5, the new item will appear at the
bottom of the first section of the Enterprise menu.

4. Exit and restart the Builder to see the new command


in the navigation menus. Don’t forget to save and
export your OSpace.

Livelink Builder Fundamentals Course Page 8-9


0 Section 8: Plugging into the Livelink Interface

8.6 Summary

• There are a number of supported ways to hook your


new request handlers into the interface, including
adding to the navigation menus, adding new types of
nodes, and more.

• The navigation menus are created by the


LivelinkNavigationCallback descendent objects and its
corresponding subsystem. When you want to add items
to the navigation menus, you can orphan this object and
edit its Execute() method.

• The Execute() method of the


LivelinkNavigationCallback orphan builds an assoc for
each new menu command and then adds it to an “assoc
of assocs”. The “inner” assocs have “name” and “url”
elements. The “outer” assoc has an element for each
“inner” assoc, and the keys of the outer assoc dictate
where the new menu item will go within the navigation
menus.

• Orphaning the LivelinkNavigationCallback object is an


example of a time when you need to enable an object in
order to turn on its functionality. This object also has an
_Init() method that needs to be run during the startup of
the system (to build the navigation menus and their
contents). By setting the fEnabled feature to true and
then running the Globals object’s BuildOSpace()
method, you enable the object and set up the system to
initialize it whenever the system starts.

Page 8-10 Open Text Corporation


0 Section 8: Plugging into the Livelink Interface

8.7 Section 8 Exercises

8.7.1 Make it easy for your end-users to run your new


“GetContacts” request handler by allowing them to chose the
command from the Navigation menus.

□ 1. In the Builder, ORPHAN WEBLL : WebLL Root : NavigationCallback :


LivelinkNavigationCallback and call it ContactNavigationCallback.

□ 2. SET ContactNavigationCallback.fEnabled = True.

□ 3. RUN your OSpace’s Globals.BuildOSpace().

□ 4. EDIT the ContactNavigationCallback.Execute()to CREATE an assoc to store the


new menu item specifications:

• CREATE an assoc to store the new menu item specifications:

//After this line


String scriptName = request.SCRIPT_NAME

//Add the following to define an assoc of the correct format:


Assoc item_contacts = ._NewItem()

/* Add this line to define the URL that is sent when a user
clicks your new Navigation menu item. */
item_contacts.name = "Get Contacts"
item_contacts.url = \
str.format("%1?func=contact.GetContacts&filepath=%2", \
scriptName, Web.Escape("c:\Builder Course Files\contacts.txt"))

• COMMENT OUT (or delete) the line:

// Items = undefined

• Instead of leaving the items assoc Undefined, ADD the items_contact assoc as a new
element of the items assoc, have the “key” of the new element be set so the new item
will appear in the first section of the Enterprise menu :
items.('11' + .mSectionOne + "Contacts" + ".0") = item_contacts

□ 5. COMPILE and SAVE ContactNavigationCallback.Execute().

□ 6. SAVE and EXPORT your OSpace.

□ 7. STOP and RESTART the Builder.

Livelink Builder Fundamentals Course Page 8-11


0 Section 8: Plugging into the Livelink Interface

□ 8. TEST your work by looking for your new command on the Enterprise Workspace
navigation menu. Is it there? Does it work?

8.7.2 Food for Thought:

Will your users require a link to get to any areas of Livelink from the Navigation menus?
Will you need to modify any other Livelink pages?

Page 8-12 Open Text Corporation


Section 9: Overview of Livelink Node Objects
Overview:

The LLIAPI OSpace contains a base set of LLNode objects that manage the different
types of Livelink items, also referred to as node types. The WebNode OSpace contains
the WebNode objects that provide the interface and commands for LLNodes. Together
these objects are used to implement a commonly desired customization: the addition of
new types of items to be stored and managed by Livelink.

Objectives:

By the end of this section, you will be able to create a new


type of “Livelink item”, also called a node. In the process,
you will learn about:

• How items are stored in Livelink

• The infamous LL request handler

• How ApplTypes, LLNode Objects, WebNode objects,


and WebNodeCmd objects work together to implement
a new node type

Livelink Builder Fundamentals Course 92-300 04Feb11 Page 9-1


Section 9: Overview of Livelink Node Objects

DTree table:
DATAID NAME PERMID
DTreeACL table:
1290 Marketing 1290
DataID ACLType RightID Permissions
1923 OutdoorGear News 1923
1290 1 124 65670
2340 Get your T-shirt 1923
1290 2 349 284938
1290 3 -1 36995
DVersData table: 1290 0 138 584923
DocID VersionID ProviderID FileName 1290 4 -2 293948
1382 3 2384 Jan23.xls 1923 2 458 394923
2383 8 3483 jobs.html 1923 1 124 675765
2383 7 3429 jobs.html 1923 3 -1 39492
3848 1 5994 ann.doc 1923 0 138 393949
1923 0 349 494994
ProviderData table:
ProviderID ProviderData RefCnt
2383 22393 1
BlobData table:
2389 22838 1
OwnerID LongID SegmentID Segment
2034 24293 2
0 22838 1
2342 28223 1
0 24293 1
0 24293 2
DAudit table: 0 24293 3
DataID UserID Event 0 28223 1
124 2934 DELETE
138 2838 VIEW llAttrData table:
349 4554 FETCH ID Vernum AttrType
458 2332 RESERVE 124 1 -10
138 5 7
1382 2 6
3848 2 6

Figure 9-1: The principal tables involved in storing a Livelink item


(NOTE: This figure displays only a subset of the table columns)

Page 9-2 Open Text Corporation


Section 9: Overview of Livelink Node Objects

9.1 How Items are Stored in Livelink

A set of tables in the underlying database schema store the


data for Livelink items:

• The DTree table stores one record for each item, with a
DataID column that uniquely identifies each item and a
Subtype column that identifies the node type (folder,
query, document, etc.) of the item.

• There is one record in the DTreeACL table for each


user or group listed on the Permissions page for the
item.

• The DVersData table contains one record for each


version of the items that are versioned.

• The ProviderData table contains one record for each


unique BLOB (Binary Large OBject— in other words,
an electronic file) stored in Livelink, specifying the
information needed to locate it, whether it is internally
or externally stored.

• The BlobData table contains one or more records for


each BLOB (Binary Large OBject) stored in the
system. (This table is used for internal document
storage.)

• The llAttrData table stores a record for each attribute


stored with a version of an item.

• The DAudit table stores one record for each action


performed against an item.

Because there is so much involved in the creation and


maintenance of a single item, we strongly discourage you
from trying to (and do not support attempts to) insert,
modify, or delete records from these tables with SQL
statements you create on your own. Instead, we recommend
you use the DAPI package of built-in functions—or better
yet, use the objects Open Text has already created to
manage items. This is the topic of the next few sections.

Livelink Builder Fundamentals Course Page 9-3


Section 9: Overview of Livelink Node Objects

newnode = DAPI.AllocNode()

pName pComment pType pParentID pCreatedBy

newnode.pName = 'Get Your Bonus'


newnode.pComment = 'bonus plan announcement'
etc.

pName pComment pType pParentID pCreatedBy


Get Your Bonus bonus plan… 208 2992 8049

newnode = DAPI.CreateNode( newnode,... )

DAudit table
DTree table

DVersData Etc.
table

Figure 9-2: Creating a DAPINode

LLNode objects The objects which store the basic information and code for the
underlying functionality for the different types of nodes. There is
one LLNode object for each type of node.

WebNode The objects which store the information and code for driving the
objects web representation of the types of nodes. There is one
WebNode object for each type of node.

The ll request The request handler which processes almost all functions
handler object against nodes. There is one ll request handler object.

Figure 9-3: The base objects involved in creating and managing Livelink nodes

Page 9-4 Open Text Corporation


Section 9: Overview of Livelink Node Objects

9.2 DAPI and the Node Objects

In the context of the Builder, Livelink items are called


DAPINodes because they are created with the OScript
DAPI package and the DAPINode datatype. When a new
DAPINode is created:

• The DAPI.AllocNode() function is used to create a


variable of datatype DAPINode. A new DAPINode is
an empty structure with a fixed set of elements. These
elements correspond to the columns in the DTree table.

• DAPI functions and simple assignment statements fill


in the DAPINode structure, both with other DAPI
functions and with simple assignment statements.

• The DAPI.CreateNode() function stores the data in the


(DAPI-related) tables.

• If the DAPINode includes a version, the version is


created using a similar process but different DAPI
functions and the DAPIVersion datatype.

There are many types of DAPINodes—documents, folders,


workflow maps, etc. Each type of DAPINode has its own
behavior and interface, implemented via a set of objects,
including LLNodes, WebNodes, and more (see Figure 9-3).
You can learn all of the functions and make DAPINodes
this way, but it is much easier to use the objects in the
LLIAPI, WebNode, and WebDoc OSpaces, which already
handle all the details and make it simple to plug into the
Livelink interface.

By orphaning the LLNode and WebNode objects and


overriding their features, you provide a basic interface for a
new type of node with virtually no programming.

Livelink Builder Fundamentals Course Page 9-5


Section 9: Overview of Livelink Node Objects

?func=ll&objId=2402&objAction=browse&sort=name

DTREE Table
DATAID NAME SUBTYPE (etc.)
2401 Erg.doc 144
ll Request Handler 2402 Budgets 0
Object
2403 Find the… 208
Features:
2404 Time.xls 144
Execute() method Get the subtype
(etc.)
Find the web
node object
Get the action
to perform

Folder LLNode Object Folder WebNode Object


Features: Features:
fSubType integer --- 0 fSubType integer -----0
Action-Browse() method
Action-Delete() method
Action-Move() method

Figure 9-4: The LL request handler's work

Page 9-6 Open Text Corporation


Section 9: Overview of Livelink Node Objects

9.3 How Item Commands Are Processed:


The LL Request Handler

Most of the URLs for performing functions on Livelink


nodes contain a call to the LL request handler. The LL The display of
commands for Livelink Nodes
request handler resides in the WebNode Ospace and is is controlled by objects called
designed to handle most of the functions/actions performed WebNodeCmd objects. We
on many of the different node types available in Livelink. will cover these in more detail
in a later section.
The URLs that invoke the LL request handler include an
objId parameter, an objAction parameter, and other
optional parameters. In the example in Figure 9-4 , the
URL passes an object ID of a node, specifies the “browse”
action, and asks to sort by name.

• The LL RequestHandler’s Execute() method calls the


InArgsToRequest () method that retrieves the
DAPINode’s data from the DTree table using the objId
parameter. It can then determine the type of node by When performing a
command, the LL request
looking at the DAPINode’s subtype, which in this handler finds the Webnode
example is for a folder. object. Then, if necessary,
the Action- script being called
finds the LLNode object and
• InArgsToRequest() then uses the subtype to locate the calls the appropriate
WebNode objects for the folder node type. method(s) to perform the
underlying functionality. For
example, the
• Using the objAction parameter passed in the URL , the WebNode.Action-Delete()
Execute() method then locates and executes the folder method calls
WebNode’s Action-Browse() method. It uses the sort LLNode.NodeDelete() to do
the actual deletion.
parameter to sort the results.

Livelink Builder Fundamentals Course Page 9-7


Section 9: Overview of Livelink Node Objects

$TypeAlias $TypeEditWorkflow $TypeNotesExtractor

$TypeChannel $TypeFolder $TypeOTCIndexObj

$TypeChannelVol $TypeGeneration $TypeProcess

$TypeCompoundDoc $TypeIndexUpdate $TypeProject

$TypeDirWalker $TypeIPool $TypeProjectVol

$TypeDiscussion $TypeLibraryExtractor $TypeProjectVolsVirtual

$TypeDocument $TypeLibraryObj $TypeRelease

$TypeReply $TypeReservedItems $TypeRevision

$TypeReport $TypeRevision $TypeSearchObjectFolder

$TypeSearchReport $TypeSearchBroker $TypeVolRelease

$TypeSliceFolder $TypeTaskListVol $TypeVolReports

$TypeSpider $TypeTopic $TypeVolRootsVirtual

$TypeSupSearch $TypeURL $TypeVolSystem

$TypeTask $TypeVolDiscussion $TypeVolWorkbin

$TypeTaskList $TypeVolLibrary $TypeVolWorkbinsVirtual

$TypeVolWorkflow $TypeVolProjects $TypeWFStatus

$TypeWFInbox $TypeWFMap $TypeWFStatusItem

$TypeWorkflowAttachment

Figure 9-5: Some of the LLNode SubType Globals

Page 9-8 Open Text Corporation


Section 9: Overview of Livelink Node Objects

9.4 Identifying the Item Type:


Global Variables for SubTypes

Each node type is identified by a subtype. When adding a


new type of node to Livelink, you assign it a unique
subtype.

The subtype is stored in LLNode and WebNode objects’


fSubType feature as an integer. Open Text has reserved
the integers up to 1999 for internal use. When you create a
new type of node, you should assign your node a subtype
value greater than 1999.

For your real-life customizations, you can log on to the


Knowledge center and obtain your subtype integer from the
OScript Registry system.

During the initialization of each node type’s LLNode


object, Livelink creates a global variable to represent the
node type. (This includes any new node types you create.)
The format of the global variable is
$Type[LLNodeName]. The value of this global is the
node type’s subtype. It is recommended, whenever
possible, to use this global variable when referring to a
node type, since the subtype integers may change with
future releases. With very few exceptions (which you will
see in later sections), you should never use the node’s
subtype integer directly.

Livelink Builder Fundamentals Course Page 9-9


Section 9: Overview of Livelink Node Objects

$ApplTypeAttachment

$ApplTypeChannel You can use the


$LLIAPI.LLNodeSubsystem.GetSubTypesbyApplType
$ApplTypeChannelVol method to list node types by ApplType. (If you pass th
method an ApplType, it will return a list of subtype
numbers that belong to that ApplType.).
$ApplTypeCompoundDoc

$ApplTypeDiscussion

$ApplTypeDiscussionItem

$ApplTypeDocument

$ApplTypeFolder

$ApplTypeNews

$ApplTypeProject

$ApplTypeProjectVol

$ApplTypeReport

$ApplTypeSystem

$ApplTypeTask

$ApplTypeTaskList

$ApplTypeTaskListVol

$ApplTypeUserWorkbin

$ApplTypeVolReports

Figure 9-6: LLNode ApplType Globals

Page 9-10 Open Text Corporation


Section 9: Overview of Livelink Node Objects

9.5 Extend Without Overriding: ApplTypes

Node types can be further categorized using ApplTypes.


ApplTypes, identified by global variables (see Figure 9-6),
are used to define groups of node types to be used in
various situations. For example:

• The volume library (Enterprise Workspace), folder,


workflow attachments and project node types all belong
to $ApplTypeFolder.

• Many node types in Livelink specify that they are “add-


able” to any node type belonging to $ApplTypeFolder.

• If you specify that your node type belongs to


$ApplTypeFolder, Livelink will allow many node types
to be “add-able” to it.
Like SubType integers,
ApplType integers 1999 or
Node types can belong to more than one ApplType. For less are reserved for Open
example, the document node type belongs to Text developers.
$ApplTypeDocument and $ApplTypeAttachment. The
ApplTypes to which a node type belongs is stored as a list
of integers in its LLNode object’s fApplTypes feature.

ApplTypes were designed to allow developers of node


types to extend Livelink without having to override existing
nodes. As you create new nodes, you can define a new
ApplType just by declaring a new $ApplType global
variable and giving it a unique integer value—but often,
you will use existing ApplTypes .

For your real-life customizations, you can log on to the


Knowledge center and obtain your appltype integer from
the OScript Registry system.

Livelink Builder Fundamentals Course Page 9-11


Section 9: Overview of Livelink Node Objects

"?func=ll&objId=2402&objAction=browse"

DTREE Table
DATAID NAME SUBTYPE (etc.)
2401 Erg.doc 144
ll Request Handler 2402 Budgets 0
Object
2403 Find the… 208
Features:
2404 Time.xls 144
Execute() method Get the subtype
(etc.)
Find the node
objects (ll & web)
Get the action to
perform

Folder WebNode Object


Features:
fSubType integer-----0
Action-Browse() method
Folder LLNode Object
Action-Delete() method
Features:
Action-Move() method
fAliased----------------True
fApplType-------------{0}
fContainer ------------True
fGenerationed -------False
fName -----------------‘Folder’
fObjectFactory -------True
fReservable ----------False
fSubType integer----0
fVersioned ------------False

Figure 9-7: Focusing on the LLNode object

Page 9-12 Open Text Corporation


Section 9: Overview of Livelink Node Objects

9.6 Item Type “Engine”: LLNode Object

The first step in creating a new node type in Livelink is by


creating a new LLNode object. A node’s core functionality
is managed by its LLNode object.

Key LLNode features include:

• The fSubType feature, which uniquely identifies the


type of node (and contains the same value as the
corresponding WebNode’s fSubType feature).

• The fName feature, which “labels” the type of node and


is used in the “Add New Item” menu.

• The fApplTypes feature, which helps to categorize the


type of node (see Section 9.5).

• A series of boolean features for enabling and disabling


basic node functionality, such as fContainer, fAliased,
fVersioned, fGenerationed, and fReservable.

• A set of methods for performing customized data and


other transactions as a node is created, updated, and
deleted—such as NodeCreateSubclassPre(),
NodeUpdateSubclassPost(), and
NodeDeleteSubclassPre() (see Section 11).

Livelink Builder Fundamentals Course Page 9-13


Section 9: Overview of Livelink Node Objects

Folder LLNode Object


Features:

fAliased TRUE This type of node can be aliased.


fAttrInheritance TRUE This node inherits attributes and values from its
parent.
fAttrUsage TRUE Users are allowed to assign categories to this
type of item
Users can force a value to be assigned to an attribute
fAttrValueRequired TRUE

fAuditable TRUE This type of node can be audited.


fContainer TRUE Our Suggestion Box is intended to be a container
for Suggestions. (The next new kind of node we’ll
create.) If your node was orphaned from LLNode
this feature will already be set correctly.
fGenerationed FALSE This type of node cannot be generationed (which
would imply it had versions).
fName “Suggestion This is the display name of the node that is used i
Box” the Add Items popup.
fObjectFactory TRUE The privilege to create this type of node can be
restricted.
fReservable FALSE This type of node cannot be reserved.
fSubType 2001 This feature should be a number above 2000. (Se
the list of subtypes earlier in this section.)
fVersioned FALSE This type of node cannot be versioned.

Figure 9-8: An example LLNode object

Page 9-14 Open Text Corporation


Section 9: Overview of Livelink Node Objects

Step set 9.1: Implement a new LLNode

1. In the context of this course example, we will create a new


ApplType. Edit the Root.Startup() method in your OSpace to
include a line of code to create the global variable for the new
ApplType, then run the method in preparation for step 7.

$ApplTypeSuggestion = 2001

In this example, the ApplType will be used for


Suggestion Box nodes.

2. Orphan LLIAPI:LLIAPI Root:LLNode in your OSpace.


This orphan will serve as the class object for the LLNodes in
your OSpace.

3. Name the class object after the types of nodes you will create—
for example, Suggestions LLNodes.

4. Create a child of the Nodes class object, and name the child
after your new first node type, for example, SuggestionBox.

5. Set fEnabled to TRUE, then run the BuildOSpace() method of


your OSpace’s Globals object.
Reminder: This step enables the object for initialization.
LLNodes are registered with the LLNode Subsystem during
initialization.

6. Set the features of the object, following the example in


Figure 9-8.

7. Create and run a setup script to set the value of the


fApplTypes feature. For example:
.fApplTypes = {$ApplTypeSuggestion}
This adds this node type to the Suggestion ApplType.

Livelink Builder Fundamentals Course Page 9-15


Section 9: Overview of Livelink Node Objects

"?func=ll&objId=2402&objAction=browse"

DTREE Table
DATAID NAME SUBTYPE (etc.)
2401 Erg.doc 144
ll Request Handler 2402 Budgets 0
Object
2403 Find the… 208
Features:
2404 Time.xls 144
Execute() method Get the subtype
(etc.)
Find the node
type objects
Get the action
to perform

Folder LLNode Object Folder WebNode Object


Features: Features:
fSubType integer----0 Action-Browse() method
Action-Delete() method
Action-Move() method
fCmdNames -----------{‘Browse’, ‘Delete’, ‘Move’ }
fGif ----------------------“folder.gif”
fSubType integer -----0

Figure 9-9 Focusing on the WebNode object

Page 9-16 Open Text Corporation


Section 9: Overview of Livelink Node Objects

9.7 Item Type Interface “Driver”: WebNode Objects

Each LLNode object may have (and most all of them do) a
corresponding WebNode object. The LLNode and
WebNode objects are linked by subtype. WebNodes
implement the web interface for a node.

Key WebNode features include:

• The fSubType feature, an integer which must contain


the same value as the corresponding LLNode’s
fSubType feature.

• The fGif feature, which contains the filename of the


icon associated with the node.

• The fParentApplTypes feature, which contains a list of


ApplTypes under which this type of node can be added.

• The fParentSubTypes feature, which contains a list of


node types under which this type of node can be
created.

• The fCmdNames feature, which contains a list of


strings that represent the commands that can be
performed on the node (e.g., “Browse”, “View”,
“Delete”).

• “Action-commandName()” methods, which contain the


script for each command.

Livelink Builder Fundamentals Course Page 9-17


Section 9: Overview of Livelink Node Objects

Figure 9-10: WebNode with overridden features

Page 9-18 Open Text Corporation


Section 9: Overview of Livelink Node Objects

Step set 9.2: Implement a WebNode Object

1. Orphan WebNode: WebNode Root: WebNode in your


OSpace.
This orphan will serve as the class object for the
WebNodes in your OSpace.

2. Name the class object after the types of nodes you’ll be To compare
fParentApplTypes to
creating—for example, Suggestions WebNodes. fParentSubTypes, here’s an
example: When
3. Create a child of the WebNodes class object. Name the fParentApplTypes includes
child object after your node—for example, $ApplTypeFolder, a
suggestion box can be added
SuggestionBoxWebNode. to any node that belongs to
the $ApplTypeFolder family.
4. Set fEnabled to TRUE, then run the BuildOSpace() When fParentSubtypes
includes $TypeFolder, a
method of your OSpace’s Globals object. suggestion box can be added
(This object must also be initialized so that it is only to folder nodes.
registered with a subsystem at startup.)

5. Set the fSubType feature to match the subtype set in the


LLNode object (in this example, 2001).

6. To specify where users can add items of your new node


type, create and run a script to set the fParentApplTypes
or fParentSubtypes features. In this example, we set
fParentSubtypes to {$TypeFolder} to specify that
suggestion boxes can be added to folders.

7. Set the fGif feature to the name of the file containing


the icon used to represent your node.
Use a 16x16 GIF file.

8. Add the GIF file to your module’s support directory


and to your module’s directory in LLHOME\support.

9. Test: Save, export, exit, restart, and create a new node Did you notice that we
of your new type in the Enterprise Workspace. didn’t write any code to make
(Livelink finds and uses a “default” html template the nodes “do” anything yet
our new node type already
for entering a new item of your type.) has some of functionality?
That’s because Action objects
and WebNodeCmds already
present in Livelink add
functionality to our new node
type. You’ll see how to create
new ones as the course
progresses.

Livelink Builder Fundamentals Course Page 9-19


Section 9: Overview of Livelink Node Objects

9.8 Summary

• Many Builder users want to create new types of nodes,


so Livelink was designed with many hooks for making
this an easy task.

• The data for nodes is stored in the DTree, DVersData,


ProviderData, and other tables in the Livelink schema.
You should not try to add to or modify these tables
using SQL—instead, use the DAPI package of built-in
functions, or better yet, use the objects that already
exist which call the DAPI functions.

• Each type of Livelink node has an LLNode for its base


functionality and a WebNode for its interface.

• Each node is identified with a unique subtype. The


subtype links the LLNode and WebNode objects.

• ApplTypes define a group of node types. You can use


ApplTypes to control certain aspects of the system’s
behavior. For example, you can use ApplTypes to
specify which objects can serve as “parents” or
“children” of a given node type.

Page 9-20 Open Text Corporation


Section 9: Overview of Livelink Node Objects

9.9 Section 9 exercises

Create a new “Contact” node type for containing contact records added by your sales staff.
The contact records will include a customer name, ID number, phone number, and e-mail
address, much like the data stored in the contacts.txt file. After adding the basic information
for a contact, sales staff will be able to add documents and other types of nodes as
“children” of a contact node, in order to record notes of meetings, conference calls, and
other information regarding the contact.

9.9.1 Part A: Create a New ApplType and a New LLNode

Create a new “Contact” ApplType, create a new LLNode object for a Contact, then register
and initialize it.

□ 1. ADD the following code to your Root.Startup() method to create a Contact


ApplType:
$ApplTypeContact = 2002

□ 2. RUN Root.Startup() (to define the global variable in preparation for step 8).

□ 3. ORPHAN LLIAPI : LLIApi Root : LLNode object, calling it Contact LLNodes. This
new object will be a class object for all LLNodes in your OSpace.

□ 4. CREATE a child of the Contact LLNodes object and call it Contact.

□ 5. Now REGISTER your new Contact object (your LLNode for the new Contact
nodetype):

• Set fEnabled = True.

• RUN your Globals.BuildOSpace().

□ 6. To define the name of the node type for the Add Items menu, SET Contact.fName =
Contact.

□ 7. SELECT and ASSIGN a number to fSubtype of 2000 or greater. (For this exercise,
please use 2002 to make it easier for you and the instructor when debugging).

□ 8. CREATE a setup script in the CONTACT object (your LLNode):

• In it, SET .fApplTypes = { $ApplTypeContact }.

• (And don’t forget to COMPILE and RUN this setup script).

Livelink Builder Fundamentals Course Page 9-21


Section 9: Overview of Livelink Node Objects

□ 9. If you orphaned this node from LLNode, fContainer is already set to True. (You want
your new node type to be a container).

□ 10.Finally, SET (or verify the setting of) some of the other inherited booleans:

□ a. fAliased = True – Why?

□ b. fAttrInheritance = True – Why?

□ c. fAttrUsage = True – Why?

□ d. fAttrValueRequired = True – Why?

□ e. fAuditable = True – Why?

□ f. fGenerationed = False – Why?

□ g. fObjectfactory = True – Why?

□ h. fReservable = False – Why?

□ i. fVersioned = False – Why?

□ 1. SAVE and EXPORT your OSpace.

9.9.2 Food for thought:

What other Boolean features are there for this node? Which would you want set to True,
which would you want set to False?

9.9.3 Part B: Making a Web Node

Create a corresponding WebNode for your new “contact” nodetype.

□ 1. ORPHAN WEBNODE : WebNode Root : WebNode, calling it Contact WebNodes. This


new object will serve as a class object for all WebNodes in your OSpace.

□ 2. CREATE a child of the class object Contact WebNodes, called ContactWebNode.

□ 3. Now REGISTER your new ContactWebNode:

• SET fEnabled = True.

• RUN your Globals.BuildOSpace().

Page 9-22 Open Text Corporation


Section 9: Overview of Livelink Node Objects

□ 4. SET ContactWebNode.fSubType to match the subtype set in the corresponding Contact


LLNode (step 7 in part A, 2002 for this exercise).

□ 5. DECIDE where your contact records can be added in the Livelink hierarchy, then do one
or both of the following in a setup script (and DON’T FORGET to RUN the setup script):

□ a. CREATE a setup script to set fParentApplTypes feature to a list of the


appropriate Appltypes.

□ b. Optionally, CREATE a setup script to SET fParentSubTypes to a list of the


appropriate node types.

Don’t forget to COMPILE and RUN the setup script!

Note: We recommend that you allow contacts to be added at least to folders.

□ 6. CHANGE the type of fGif to a string (in which object will you make this change?).
Then SET fGif to the name of the 16 x 16 GIF file provided for contacts, contact.gif.
Look in c:\Builder Course Files\ for contact.gif.

□ 7. PLACE the GIF file named in the previous step in the LLHOME\support\contact
directory, as well as in your module’s support directory.

□ 8. SAVE and EXPORT your OSpace, then EXIT and RESTART the Builder.

□ 9. TEST your work: LAUNCH a web browser and GO to the Enterprise Workspace (or a
place where contacts can be added). CLICK the Add New Item menu.

9.9.4 Questions

Is your node type listed?

When you choose your node type, can you enter a new node?

Does its GIF display in the browser page?

Livelink Builder Fundamentals Course Page 9-23


Section 9: Overview of Livelink Node Objects

Notes:

Page 9-24 Open Text Corporation


Section 10: Controlling the Commands for a Node Type
Overview:

WebNode objects maintain lists of commands that can be performed against nodes of their
type. A WebNodeCmd object builds the URL, display name and other GUI aspects for each
of the WebNode’s commands. There are existing WebNodeCmd objects that your node uses
to generate its commands.

Objectives:

By the end of this section, you will be able to:

• Specify which of the “off-the-shelf” commands for manipulating Livelink items you want
to use with a new node type

• Control the tabs on your node type’s Info page

• Control what appears on the Add New Item menu for your node type

Livelink Builder Fundamentals Course 92-300 04Feb11 Page 10-1


Section 10: Controlling the Commands for a Node Type

Folder WebNode Object


Features:
fSubType integer----- 0
fGif ---------------------- “folder.gif”
fCmdNames----------- {‘Browse’, ‘View’, ‘Delete’ }
Action-Browse() method
Delete
Action-Delete() method WebNodeCmd Object
Action-Move() method

View
WebNodeCmd Object
Browse
WebNodeCmd Object

Figure 10-1: WebNode.fCmdNames, WebNode.Action-[CommandName]() scripts and


WebNodeCmd objects

Page 10-2 Open Text Corporation


Section 10: Controlling the Commands for a Node Type

10.1 Node Commands

In working with Livelink, you have seen how Livelink


exposes a node’s functions (or commands) in the interface:

• Node commands appear on the node’s Functions menu


( ), both on browser pages and beside the node’s
name on Info pages.

• A command is associated with clicking the node name:


For example, clicking a folder name invokes the
“browse” command and displays the contents of the
folder.

• Some of the functionality of a node is implemented as


tabs on the node’s Info page: For example, clicking the
Audit tab on the Info page displays the audit trail for the
current node.

The URLS (and all other display aspects) for commands


are built by WebNodeCmd objects. Many of these
commands invoke
WebNode.Action-[CommandName]() methods when they
are executed. The name of a WebNodeCmd object
corresponds to the action to be performed—for example,
“Browse”, “View”, or “Delete”.

The fCmdNames feature of a WebNode object is a list of


the basic commands that should be available to it.

Livelink Builder Fundamentals Course Page 10-3


Section 10: Controlling the Commands for a Node Type

The
Functions
menu

The open
“placeholder” is used
when clicking the
Figure 10-2: Portion of a “browser” page name of the item

;for nodeRec in contents

;if nodeRec.Catalog == 0
The Cmd() method gets
;rowfactor ^= 1 the WebNodeCmd object
corresponding to the
;webNode = webNodes.GetItem( nodeRec.subtype ) open “placeholder”…
;open = webNode.Cmd( "open" )

<TR `%Lstyles.( Str.Format( 'Row%1', rowfactor


+ 1 ) )`> …Then features of that
<TD NOWRAP WIDTH="1%"> WebNodeCmd object are
`%Lopen.DisabledUnescapedLink( prgCtx, called to create the
request, nodeRec, webNode.IMG( nodeRec ), hyperlink for the item
Undefined, data.NextURL )`</TD> name on the browser
<TD NOWRAP> page.
&nbsp;`%Lopen.DisabledLink( prgCtx, request,
nodeRec, nodeRec.name )`

Figure 10-3: Excerpt from the browseview.html WebLingo file

.fCmdNames =\
{\
{ "Open", "Browse" },\
\ The WebNodeCmd
{ "Browse" },\ object’s registered
{ "Copy" },\ name
{ "CreateAlias" },\
{ "CreateChild" },\
The “placeholder”
{ "Delete" },\
{ "EditConfig" },\
{ "Move" },\
{ "Properties" },\ Properties required for
{ "Permissions" }\ non-java menus only
}

Figure 10-4: Excerpt from the WebNode.0SetUp() script for a Folder, setting fCmdNames

Page 10-4 Open Text Corporation


Section 10: Controlling the Commands for a Node Type

10.2 Using Existing Commands with Your Node

When you create a subclass of the WebNode: WebNode


Root: WebNode object, you inherit the 0Setup() method. When you populate the
fCmdNames feature, you
This method contains code for populating various features should specify the
of the WebNode object—but much of the code is WebNodeCmd object’s name
commented out. for the “open” placeholder.
For example, for a folder
item, “open” in
You can uncomment the portion of the script that populates browseview.html corresponds
the fCmdNames feature, edit that part of the code to suit to “browse”, and “open” for a
document corresponds to
your WebNode, then run the script (see Figure 10-4). “view” (see Figure 10-4). If
However, most Builder users find it easier to create a you like, you can also map a
separate setup method (such as “1Setup()”), cutting code command to the “Run”,
“Original”, and “View”
from the 0Setup() method and pasting it into the new placeholders. There are some
method. commands that cannot be
used with these placeholders
The fCmdNames feature is a list of lists, and part of its (for example, Delete and
Move).
structure is designed for use with the browseview.html
WebLingo file (part of the WebNode module). This file is
the principal file for creating folder browser pages. For
each node the browseview.html displays, it looks for the
command to be called when users click the name of the
node. The browseview.html file uses an open placeholder In the Macintosh view
there are still four
to which you can map the desired command. This placeholders (carried over
command will run when a user clicks on the name of the from Livelink version 8).
node (see Figure 10-3). These are “Open”, “Run”,
“Original”, and “View”
placeholders.

Livelink Builder Fundamentals Course Page 10-5


Section 10: Controlling the Commands for a Node Type

Figure 10-5: Before—no new commands available for the node

Figure 10-6: After—commands available, based on the WebNode’s fCmdNames

Page 10-6 Open Text Corporation


Section 10: Controlling the Commands for a Node Type

Step set 10.1: Adding Commands to a Node

1. In your WebNode, create your own setup method, We seemed to have the
called 1Setup(). Open the 0Setup() method and “Make Favorite”, “Make
copy the portion that defines the fCmdNames News”, and “Set Notification
commands appear without
feature . asking for them. Later we’ll
(The 0Setup() method also has the basic code for see how these are
creating prototypes for the various commands, as automatically set for custom
nodes like Suggestion Box.
you will see later in the course.)

2. Paste the fCmdNames definition into your 1Setup()


feature. Then edit it to include these command
names:
.fCmdNames = \
{ \
{ "Open", "Browse" }, \
\
{ "Copy" }, \ Did you notice that
{ "CreateAlias" }, \ “Browse” appears by itself
and as the second element of
{ "Delete" },
the “Open” list? The {“Open”,
{ "Move" }, \ “Browse”} list maps the
{ "Permissions" }\ clicking of an item’s name to
} the “Browse” function. The
{“Browse”} list is necessary
3. Compile and run the 1SetUp() method. for the “up one level” icon in a
browser page and for the Info
page’s Browse function.
4. Exit, restart and return to Livelink in your browser
to browse a Suggestion Box.

Quiz: Will these commands really work with the


new node type just by setting this feature?

Livelink Builder Fundamentals Course Page 10-7


Section 10: Controlling the Commands for a Node Type

Figure 10-7: The Function Dropdown With the Info Submenu

Figure 10-8: Info Page With Tabs

Page 10-8 Open Text Corporation


Section 10: Controlling the Commands for a Node Type

10.3 Controlling Tabs On Your Node Type’s Info Page

Causing the Info submenu to appear in the Functions menu


is much like implementing any other function for a node:

The WebNode.fCmdNamesInfo feature maintains the list


of Commands that appear in the Info submenu as well as
the Tabs within the Info page. The feature is used to define
the WebNodeCmd objects that define the display names
and links for the Info submenu and the Info page tabs.

The Info page (which is generated by selecting any of the


commands in the Info submenu) displays tabs for every
command listed in fCmdNamesInfo feature. This includes
tabs for Specific, Audit, References, Versions and other
node information.

You can edit fCmdNamesInfo in the same way that you


edited fCmdNames—normally copying from the 0SetUp()
method and pasting into your 1Setup() method.
The “properties”
command generates the
“General” tab, and the “info”
command generates the
“Specific” tab. The specific
tab is empty right now for our
Suggestion Boxes, but the
Step set 10.2: Adding Tabs to the Info Page next section is going to use
the Specific tab to display
some custom information.
1. Copy the portion of the WebNode’s 0Setup()
method that defines fCmdNamesInfo and paste it
into the 1Setup() method.

2. Edit, compile and run the 1SetUp() method to set


the WebNode.fCmdNamesInfo list to contain these For the
command names. “General” tab

.fCmdNamesInfo = {{'Properties'},{'Audit'},\
{'References'},{'Info'}}

For the
“Specific” tab
3. Save, export, exit, restart, and return to Livelink to
view the tabs on the node’s Info page.

Livelink Builder Fundamentals Course Page 10-9


Section 10: Controlling the Commands for a Node Type

Figure 10-9: The Add Items Popup for a Node with fChildSubTypes of $TypeContact,
$TypeFolder and $TypeDocument

Page 10-10 Open Text Corporation


Section 10: Controlling the Commands for a Node Type

10.4 Controlling the Add New Item Menu for a Node Type

Container node types specify the types of LLNodes they


can contain. WebNode objects inherit fChildSubtypes and
fChildApplTypes features that define the list of node
subtypes and ApplTypes that can be its children. These
node types are listed in the Add New Item menu on the
Livelink browser page.

Step set 10.3: Adding Items to the Add New Item Menu

1. Edit the 1Setup() method, setting the


WebNode.fChildSubTypes feature to the list of
subtypes that can be a child of this node.
Use this feature to define the particular node types
that can be added as a child of your node. For
example, a node with the following list in its
fChildSubTypes feature could contain suggestion
boxes, documents, and folders.
.fChildSubTypes = {\
$TypeSuggestionBox, $TypeDocument,\
$TypeFolder }

-AND/OR-

2. Edit the 1Setup() method, setting the


WebNode.fChildApplTypes to the list of node
ApplTypes that can be children of a node.
Use this feature to include groups of nodes that can
be added as a child of your node. For example, a
node with the following list in its fChildApplTypes
feature could contain suggestion boxes, documents
and any other nodes with these ApplTypes.
.fChildApplTypes = { \
$ApplTypeSuggestion, $ApplTypeDocument }

3. Compile and run the 1Setup() method.

4. Save, export, exit and restart to test: Browse your


nodes.

Livelink Builder Fundamentals Course Page 10-11


Section 10: Controlling the Commands for a Node Type

10.5 Summary

• WebNode commands are displayed in the Functions


menu and as tabs on the Info Page for Livelink nodes.

• The items that appear in the Info submenu within the


Functions menu and as tabs in the Info page are defined
in the WebNode.fCmdNamesInfo feature. (In Section
12, you will learn about other ways to add commands to
the Function menu.)

• The items that appear in the Functions menu are


defined in the WebNode.fCmdNames feature. (In
Section 12, you will learn about other ways to add
commands to the Function menu.)

• WebNodeCmd objects create the URLs and display


names for node commands (discussed in more detail in
Section 12).

• WebNode.Action-[CommandName]() scripts perform


node commands.

• The items that appear in the Add New Item menu for a
given type of “container” are defined by the values in
the WebNode.fChildApplTypes and
WebNode.fChildSubTypes features. (As well as by the
values in other webnode object’s
WebNode.fParentApplTypes and
WebNode.fParentSubtypes features.)

Page 10-12 Open Text Corporation


Section 10: Controlling the Commands for a Node Type

10.6 Section 10 exercises

Add functionality to your new “contact” node, including commands, Info page tabs, and the
ability to add new items to a contact.

10.6.1 Part A: Commands for Working with Contacts

Add commands for working with your new node. Start by writing code to allow users to click
the name of the contact record and “browse”. Add other basic commands as well.

□ 1. The WebNodes.fCmdNames feature holds all command names for the node. A
convenient method for setting the value of fCmdNames is to copy from the 0SetUp()
method:

• COPY the fCmdNames section from the 0Setup() method into your 1Setup() method
and MODIFY it to reflect the operations you wish end users to perform on contacts. (See
the example below.)
.fCmdNames = \
{ \
{ "Open", "Browse" }, \
{ "Copy" }, \
{ "CreateAlias" }, \
{ "Delete" }, \
{ "Move" }, \
{ "Permissions" }\
}

Reminder: Each list element of fCmdNames can contain two strings (for example,
{"Open","Browse"}). This allows you to “map” a label to the command.

Reminder: include “Properties” in this list if your users will use the non-Java interface.

Note: The line continuation character “\” cannot span blank lines. That is, if you
delete a line from the file, be sure that you do not leave a blank line.

□ 2. COMPILE, SAVE and RUN 1Setup().

□ 3. TEST your work: STOP and START the Builder, RETURN to the web browser, and
BROWSE a contact to test your work.

Are there new functions available on the Functions drop down menu?

Livelink Builder Fundamentals Course Page 10-13


Section 10: Controlling the Commands for a Node Type

10.6.2 Part B: Adding Info Commands

□ 1. OPEN 0SetUp()and COPY the fCmdNamesInfo section into your 1SetUp() script.

□ 2. EDIT the code which sets fCmdNamesInfo to DEFINE the Info commands (and tabs in
the Info page) for your contact. It should look something like this:
.fCmdNamesInfo = \
{ \
{ 'Properties' }, \
{ 'Audit' }, \
{ 'References' }, \
{ 'Info' } \
}

□ 3. COMPILE, SAVE and RUN the script.

□ 4. TEST your work: EXIT and RESTART the Builder, then RETURN to Livelink via your web
browser to view the Function dropdown and tabs on a contact’s Info page.

10.6.3 Part C: Items in the Add Items Menu

Allow other objects to be added to Contacts.

□ 1. Sales staff should be able to add documents and perhaps other types of nodes to
contacts, in order to record information about conference calls, meetings, and other
transactions with the customer.

□ a. EDIT 1Setup() to SET fChildSubTypes to a list of subtypes that can be a child


of this node. For example, if you wanted contacts and documents to be children:
.fChildSubTypes = { $TypeContact, $TypeDocument }

□ b. And/or EDIT 1Setup()to SET fChildApplTypes to a list of ApplTypes that can


be children of this node.
.fChildApplTypes = \
{ \
$ApplTypeContact, \
$ApplTypeDocument \
}

□ 2. RUN the script(s), SAVE your work, and EXPORT your OSpace.

□ 3. TEST your work: EXIT and RESTART the Builder, and browse a contact from your web
browser. What Livelink objects can you now add to contact nodes?

Curious? What happens when you add $ApplTypeFolder to the fChildApplTypes


list? Does this look correct?

Page 10-14 Open Text Corporation


Section 11: Storing Additional Node Data
Overview:

All of the standard Livelink system attributes (name, comments, modified date, etc.) are
automatically maintained for each type of node, including the new ones you create. If you
want to store additional data, specific to your new node type, Livelink provides several
storage options. In this section we’ll briefly discuss the various storage options and explore
one option, using the DTree’s ExtendedData column, in detail.

Objectives:

By the end of this section, you will be able to use the


DTree.ExtendedData column in the database to store
additional node data. In the process, you will learn:

• How data is passed from request to output

• How an Add Item page is created

• How to get data from an HTML form and into the


database

Livelink Builder Fundamentals Course 92-300 04Feb11 Page 11-1


Section 11: Storing Additional Node Data

OWNERID CREATEDBY MINOR

PARENTID CREATEDATE RELEASEREF

DATAID MODIFYDATE CHILDCOUNT

NAME MAXVERS ASSIGNEDTO

ORIGINOWNERID RESERVED DATEASSIGNED

ORIGINDATAID RESERVEDBY DATEEFFECTIVE

USERID RESERVEDDATE DATEEXPIRATION

GROUPID VERSIONNUM DATEDUE

UPERMISSIONS DCOMMENT DATESTARTED

GPERMISSIONS DCATEGORY DATECOMPLETED

WPERMISSIONS SUBTYPE STATUS

SPERMISSIONS EXATT1 PRIORITY

ACLCOUNT EXATT2 GIF

PERMID ORDERING EXTENDEDDATA

DATATYPE MAJOR CATALOG

Figure 11-1: Livelink Node Attributes – Columns in the DTree table

Page 11-2 Open Text Corporation


Section 11: Storing Additional Node Data

11.1 Storage Options

Livelink stores a basic set of information for all node types.


If you want to store additional data for your node type, you
can use:
• A Livelink category with custom attributes.
• Additional tables in the Livelink schema.
• The ExtendedData column in the DTree table.
If you want to store data
in additional tables, you can
cause the tables to be
created when your module is
There are pros and cons to each of these storage methods. installed and removed when
For the class example, we have decided to use the your module is uninstalled.
The Configure request
ExtendedData column in the DTree table, since this is the handler object (see Section 4
method most strongly encouraged by Open Text for more details) has a
developers. See the Modules that Manage Tables course feature called
fHasDbSchema, a boolean
for more information about using additional tables, and the that can be set to TRUE if
Livelink Administrator’s Guide for more information about your module requires the
defining categories and attributes. installation of additional
tables or columns. (See the
Modules that Manage Tables
course for more information.).

Livelink Builder Fundamentals Course Page 11-3


Section 11: Storing Additional Node Data

Figure 11-2: The Add page for suggestion boxes, with additional attributes

Page 11-4 Open Text Corporation


Section 11: Storing Additional Node Data

11.2 Using the DTree ExtendedData Column to Store Node Data

The ExtendedData column is a LONG text type that is


indexed automatically by Livelink and searchable. It The assoc stored in the
contains an assoc with elements that store the node’s ExtendedData column can
“extended data”. You can populate the column via contain elements of any
OScript datatypes. However,
OScript, using the syntax: only the string, integer and
date elements will be indexed
Node.pExtendedData.[theElementName] and searchable. Each of the
elements automatically
The advantages of using the ExtendedData column to store becomes a search region.
additional data include: Integer and date elements
stored in the ExtendedData
• The ability to search against the additional node column are converted to
data: The data in the ExtendedData column is strings and will sort
indexed. accordingly. For example,
Acct NO 11 would appear in a
• The ability to take advantage of existing list before Acct NO 2.
Livelink code: The ExtendedData column was
created specifically for storing additional node
data.
• No schema changes: The ExtendedData column
is in the DTree table.

11.2.1 The Format of the ExtendedData Column

The ExtendedData column must contain an assoc, because


this is the datatype expected by all of the DAPI calls used
to manipulate this column.

In order to store the assoc value in the underlying database,


the assoc is converted to a string. If you perform a SQL
select statement on this column, your data will be returned
in the following string format:
A<1,?,'dept'='3455','subject'='Training New Trainers'>

In the above example, the ExtendedData column contains


an assoc with two elements, dept and subject.

Livelink Builder Fundamentals Course Page 11-5


Section 11: Storing Additional Node Data

ExecuteHandler() gets a
request, including an assoc of
data, and passes it to Execute().

Execute() calls the Action


object’s Execute() method or
the Webnode’s Action()
method, passing it the
request data.

The Action method creates an assoc


containing the results needed for
output— error string, URL to switch to,
data for HTML page, or other results.
The assoc is returned to ll.Execute().

Execute() takes the results


assoc and populates fRequest,
fResponse, fError, fLocation,
etc. as appropriate, then
passes control back to
ExecuteHandler().

ExecuteHandler() calls
GenerateOutput().

GenerateOutput() uses the


“result” features to determine
whether to display an error
page, to process a WebLingo
file with result data, or to
generate other output.

Figure 11-3: The thread of execution for the ll request handler

Page 11-6 Open Text Corporation


Section 11: Storing Additional Node Data

11.3 Passing Data from Request to Output

As you write a page to add new data, Livelink needs to


send data from the request handler to an HTML form. How
does this work? See Figure 11-3.

When the LL request handler processes the user’s request


to open a page, it receives a record of data from the request,
including items such as the node the request concerns, the
arguments passed to the URL, and more. This data is
eventually stored in the LL request handler’s fRequest
feature. As the Action method is executed, an assoc is
created and populated to store the results of the transaction,
and this is stored in the LL request handler’s fResponse
feature.

As you will see, the code you write will use information
stored in fRequest and save information in fResponse. The
LL request handler looks for certain elements in these
features. See Section 12 for more information.

In many of the script features of our LLNode and


WebNode objects, references to the fRequest and
fResponse features are passed in directly, or as subelements
of another variable (usually named request and response).
This means we can access and modify the information in
these features even though we don’t have direct access to
the LL request handler.

Livelink Builder Fundamentals Course Page 11-7


Section 11: Storing Additional Node Data

?func=ll&objType=2001&objaction=create&parentID=2402

ll Request Handler
Object
Features:
Execute() method Get the subtype

fResponse assoc Find the node


type objects
Get the action
to perform

Suggestion Box WebNode


Suggestion Box LLNode Object
Object
Features:
Features:
fSubType integer ---- 2001
fSubType integer --- 2001
Action-Create() method
Action-Delete() method
Action-Move() method

Set Create.html to be the “createbase”, store


in ll.fResponse
Set the file whose name is stored in fHTMLfile
as the “create” webscript, store in
ll.fResponse.data.webscript

Create.html
1. Create the top of the Add page
2. If ll.fResponse.data.webscript is defined, call the
named webscript
3. If ll.fResponse.data.attributes is defined, display the
attributes for the page
4. Display the Submit/Reset buttons and the footer.

Figure 11-4: The path of execution for the creation of a new type of node

Page 11-8 Open Text Corporation


Section 11: Storing Additional Node Data

11.4 How the Add Item Page is Created

When the LL request handler receives a request to create a


node, it locates the WebNode’s Action-Create() method:

1. The WebNode’s fHTMLCreateBase feature stores the


name of the base html file used to create new nodes.
The Action-Create() method sets Response.webscript
(which is a reference to ll.fResponse.webscript) to the
value of fHTMLCreateBase, usually “create.html”.
This is the webscript called to build the base of the Add
Item page.

2. The Action-Create() method then stores the name of the


WebLingo file that is called for adding extra info
during creation of a node. The name is stored in
Response.data.webscript. Action-Create() gets the
name of the file from the WebNode’s fHTMLCreate
feature.

3. When the create.html page is executed, it calls a


“masthead” webscript to display the header, then
creates a form and displays the Name and Description
fields for the new node.

4. Create.html then has a conditional call of the webscript


file that was named in Response.data.webscript(or
fResponse.Data.Webscript)

When you create a new type of node, you can create a


WebLingo file to be inserted into the form on the Add New
Item page and set the node type’s WebNode.fHTMLCreate
feature to the name of the file.

This same model is used for the Info page for an item:
There’s an Action-Info() method that passes the WebLingo
filenames stored in fHTMLInfoBase and fHTMLInfo to
the LL request handler.

Livelink Builder Fundamentals Course Page 11-9


Section 11: Storing Additional Node Data

;;webscript suggbox
;string img = .img()
<tr>
<td class="label">Department:</td>
<td class="labelverticaldividerright"
background="`img`tbl-divider-ver.gif"
style="background-repeat: repeat-y;">
<img height="1" alt="" src="`img`spacer.gif" width="2" border="0">
</td>
<td><input class="valueeditable" type="text" name="dept" size=5 ></td>
<tr class="horizontalcelldivider">
<td class="labelhorizontaldivider">
<img height="1" alt="" src="`img`spacer.gif" width="1"
border="0">
</td>
<td class="valuehorizontaldivider" colspan="2">
<img height="1" alt="" src="`img`tbl-divider-hor.gif" width="3"
border="0">
</td>
</tr>
</tr>
<tr>
<td class="label" valign="top" nowrap>Subject:</td>
<td class="labelverticaldividerright"
background="`.img()`tbl-divider-ver.gif"
style="background-repeat: repeat-y;">
<img height="1" alt="" src="`.img()`spacer.gif" width="2"
border="0">
</td>
<td>
<input class="valueeditable" type="text" name="subject" size=40 >
</td>
<tr class="horizontalcelldivider">
<td class="labelhorizontaldivider">
<img height="1" alt="" src="`img`spacer.gif" width="1"
border="0">
</td>
<td class="valuehorizontaldivider" colspan="2">
<img height="1" alt="" src="`img`tbl-divider-hor.gif" width="3"
border="0">
</td>
</tr>
</tr>
;;end

Figure 11-5: Example webscript for adding fields to the Add Item page

For the sake of formatting, the


lines of code have been broken up
in figure 11.5. You may not have any
characters (eg space, tab, CR)
before the </td> tag or unpredictable
results will occur.

Page 11-10 Open Text Corporation


Section 11: Storing Additional Node Data

Step set 11.1: Write a WebLingo File for Entering


Additional Node Attributes

1. Create a WebLingo file whose contents can be


inserted in between HTML <FORM> and
</FORM> tags, using the example in Figure 11-5
and the standard Livelink Add Item pages as your
guide.
(Now’s your chance to show off and have fun with
your HTML and CSS skills.)

Every input field you add to the page (whether it is


a text field, dropdown list, or other input) will be
part of the request passed to the ll request handler—
see Section 11.5.

2. Save the webscript in your module’s html folder.

3. Edit the fHTMLCreate feature of the WebNode to


store the name of the WebLingo file for the Create
action.

Livelink Builder Fundamentals Course Page 11-11


Section 11: Storing Additional Node Data

Linked to the Add Suggestion menu item:


"?func=ll&objId=2402&objAction=create"

WebNode Object
Features:
fSubType integer Add Item Page (create.html)
Displays Add Page
fCmdNames list
Calls Action-Create2() on Submit
Action-Create() method
Action-Create2() method
fPrototypeCreate2 list

Uses fPrototypeCreate2 to verify the


input arguments and convert them
to the proper datatype

Enters data from the page to the


RDBMS

Figure 11-6: Action- Create()/Create2() method Sequence when creating a new node

{ "parentID", IntegerType, "parent ID number", FALSE, 2000, FALSE }

The name of the A description of the A default value


argument (a string) argument (a string) (optional)

The datatype of Whether the Whether the


the argument (an argument is optional argument is a
integer) (a boolean) list (boolean—
optional)

Figure 11-7: Reminder—the elements of an element of the fPrototype feature

Page 11-12 Open Text Corporation


Section 11: Storing Additional Node Data

11.5 Getting the Additional Data Off the Form

The WebNode.Action-Create2() method is called by the


create.html WebLingo file (via a WebNodeCmd) to store
the data on the Add page into the RDBMS. Each input
field on the page becomes an argument in the URL passed
to the Action-Create2() method. The Action-Create2
method’s prototype, fPrototypeCreate2, should be
updated to reflect the new parameters (the additional node
data elements) it must store. As you might remember from
Section 6, the fPrototype features both verify input
arguments and convert them to the required datatype.

Step set 11.2: Override the WebNode.fPrototypeCreate2 Feature

1. Create and run a setup script to set the


WebNode.fPrototypeCreate2 feature to include
the new arguments that will be passed to the
Action-Create2() method. For example:

.fPrototypeCreate2 = \
{ \
{ "parentId", IntegerType, [WebNode_RHParams.ParentID], FALSE }, \
{ "name", StringType, [WebNode_RHParams.Name], FALSE }, \
{ "comment", StringType, [WebNode_RHParams.Comment], TRUE }, \
{ "nextURL", StringType, [WebNode_RHParams.URLToReturnTo], FALSE},\
{ "dept", IntegerType, "department concerned" , FALSE },\
{ "subject", StringType, "general subject", TRUE } \
}

2. You can exit and restart the Builder to test whether


the new fields are displayed and can be used—but
the data isn’t being sent to the database yet…

Livelink Builder Fundamentals Course Page 11-13


Section 11: Storing Additional Node Data

Edit to set additional


attributes, such as
The LLNode.NodeCreate() Method: pExtendedData

Node has been allocated with DAPI.AllocNode()

LLNode.NodeCreateSubclassPre
Alias, generation
LLNode.NodeCreateSubclass code here

Node is saved here with DAPI.CreateNode()


Edit if you want to
LLNode.NodeCreateSubclassPost
store additional data
in a separate table

Figure 11-8: The LLNode.NodeCreateSubclass Methods as called by LLNode.NodeCreate()

Page 11-14 Open Text Corporation


Section 11: Storing Additional Node Data

11.6 Getting the Additional Data into the Database

LLNode objects do the work of calling the DAPI built-in


package functions to create, populate, and store the new
DAPINode. They inherit a set of methods that are meant to
be overridden (if necessary) when customizing a node.

Method (feature) Name When Called/Purpose

C NodeCreateSubclassPre This method is called before a


R node is created and can be used
E to set the values of additional
A node attributes and to perform
T data validation.
I
O NodeCreateSubclass This method is called between
N SubclassPre and SubclassPost
and is usually overwritten if you’re
creating a root node.

NodeCreateSubclassPost This method is called after a node


is created and can be used for
storing node data in a secondary
table. For example, after a project
is created its project ACL list is
updated by this method.

U NodeUpdateSubclassPre This method is called before a


P node is updated and can be used
D in a manner similar to
A CreateSubClassPre.
T
E NodeUpdateSubclassPost This method is called after a node
is updated and can be used in a
manner similar to
CreateSubclassPost.

D NodeDeleteSubclassPre This method is called before a


E node is deleted.
L
E NodeDeleteSubclassPost This method is called after a node
T is deleted.
E

Livelink Builder Fundamentals Course Page 11-15


Section 11: Storing Additional Node Data

// Private method
//
// Override this method to perform specific attributes
// assignment to the node.
//
// Parameters:
// node The DAPI node to be created.
// createInfo Additional information for the node.
// context Custom parameter.
//
// Return an assoc:
// OK TRUE if ok.
// ErrMsg Application error message if not ok.
// ApiError Error returned by API if not ok.

function Assoc NodeCreateSubclassPre(\ The createInfo parameter is an


DAPINODE node,\ assoc containing a reference to
Dynamic createInfo,\ the parent node of the new
Dynamic context ) node and the Request data.
The fields on the Add page are
included in the assoc’s Request
Assoc rtnval
element.
Dynamic apiError
String errMsg
The “additional” data must be
Boolean ok = TRUE stored in the ExtendedData
Object dapiCtx = createInfo.DapiCtx property as an assoc—so declare
an assoc and set its elements with
dynamic request = createInfo.request the data passed to the method.
assoc suggbox
suggbox.dept = request.dept
suggbox.subject = request.subject

If IsDefined(node.pExtendedData) \
&& Type(node.pExtendedData) == Assoc.AssocType
//merge data assoc with existing pExtendedData assoc
node.pExtendedData = Assoc.Merge(node.pExtendedData, suggbox)
else
If pExtendedData already contains
//store data assoc in PExtenedData info (check, just in case), then add
node.pExtendedData = suggbox our info to it (using Assoc.Merge).
end

if IsUndefined( rtnval.OK )
If pExtendedData is undefined
rtnval.OK = ok
(nothing stored), then add our
rtnval.ErrMsg = errMsg assoc to it.
rtnval.ApiError = apiError
end

return( rtnval )
end

Figure 11-9: The LLNode.NodeCreateSubclassPre() Method (Overridden)

Page 11-16 Open Text Corporation


Section 11: Storing Additional Node Data

Step set 11.3: Override the LLNode.NodeCreateSubClassPre Method to Store


Additional Node Data

1. Edit the SuggestionBoxNodeCreateSubClassPre()


method, creating a suggbox assoc. Store the Dept
and Subject passed in with CreateInfo.request into
dept and subject elements in the new suggbox
assoc. (See the example in Figure 11-9.)
Remember, you can store elements of various
datatypes in this assoc, and the fPrototypeCreate2
feature you defined has already converted the It’s a good idea to check
information to the correct datatype. to see if extended data
already contains an assoc
and add your elements to that
assoc. Developers may start
2. Continuing in the LLNode.NodeCreateSubclassPre() using pEntendedData to store
other information in.
method, assign the suggbox assoc to the
node.pExtendedData property.
The value in the node’s pExtendedData property
will be stored in the DTree ExtendedData column.

3. Exit and restart to test your work.

Livelink Builder Fundamentals Course Page 11-17


Section 11: Storing Additional Node Data

11.7 Summary

• There are several options for storing additional node


data. One of them is to use the ExtendedData column in
the DTree table. This column can contain any kind of
data, but in order for it to be indexed and searchable
through Livelink, it must contain an assoc.

• There are four steps to storing additional node data in


the ExtendedData column:

1. Writing a webscript to present the new attributes,

2. Setting the WebNode.fHTMLCreate feature to


contain the name of this webscript,

3. Setting the fPrototypeCreate feature with an


appropriate prototype for the new create action, and

4. Overriding the LLNode.NodeCreateSubclass


methods to fill in the DAPINode’s pExtendedData
property.

Page 11-18 Open Text Corporation


Section 11: Storing Additional Node Data

11.8 Section 11 exercise

Perform the necessary steps to add new metadata, “customer number” and “phone
number”, to your contact node type, using the pExtendedData provision. Display the
attributes on the “Add a New Contact” page. Also, make the changes needed for updating
these attributes on the “Specific” tab of the “Info” page.

11.8.1 Part A: Add New Attributes

Create the functionality to add new attributes to your Contact.

□ 1. SET Contact WebNode.fHTMLCreate = contactcreate.html.

□ 2. CREATE a new WebLingo file in your module’s html directory called


contactcreate.html. Your file should look something like this:

;;webscript contactcreate
;string img = .img()
<tr>
<td class="label">Customer No.:</td>
<td class="labelverticaldividerright" background="`img`tbl-divider-
ver.gif" style="background-repeat: repeat-y;">
<img height="1" alt="" src="`img`spacer.gif" width="2"
border="0">
</td>
<td>
<input class="valueeditable" type="text" name="custno" size=5>
</td>
<tr class="horizontalcelldivider">
<td class="labelhorizontaldivider">
<img height="1" alt="" src="`img`spacer.gif" width="1"
border="0">
</td>
<td class="valuehorizontaldivider" colspan="2">
<img height="1" alt="" src="`img`tbl-divider-hor.gif"
width="3" border="0">
</td>
</tr>
</tr>
<tr>
<td class="label" valign="top" nowrap>Phone No.:</td>
<td class="labelverticaldividerright" background="`.img()`tbl-
divider-ver.gif" style="background-repeat: repeat-y;">
<img height="1" alt="" src="`.img()`spacer.gif" width="2"
border="0">
</td>
<td>
<input class="valueeditable" type="text" name="phoneno" size=40>
</td>
<tr class="horizontalcelldivider">

Livelink Builder Fundamentals Course Page 11-19


Section 11: Storing Additional Node Data

<td class="labelhorizontaldivider">
<img height="1" alt="" src="`img`spacer.gif" width="1"
border="0">
</td>
<td class="valuehorizontaldivider" colspan="2">
<img height="1" alt="" src="`img`tbl-divider-hor.gif"
width="3" border="0">
</td>
</tr>
</tr>
;;end

□ 3. COPY the code for defining fPrototypeCreate2 from the 0 Setup() method to your
1Setup() method in your Contact WebNode object. Set fPrototypeCreate2 to look
like this:
.fPrototypeCreate2 = { \
{ "parentId", IntegerType, [WebNode_RHParams.ParentID], FALSE }, \
{ "name", StringType, [WebNode_RHParams.Name], FALSE }, \
{ "comment", StringType, [WebNode_RHParams.Comment], TRUE }, \
{ "nextURL", StringType, [WebNode_RHParams.URLToReturnTo], FALSE },\
{ "custno", IntegerType, "customer number", FALSE },\
{ "phoneno", StringType, "phone number", TRUE } }

□ 4. COMPILE and RUN 1Setup().

□ 5. EDIT the NodeCreateSubClassPre() method in your Contact (LLNode) object:

• DECLARE an assoc.

After:
Object dapiCtx = createInfo.DapiCtx

Insert:
assoc contact

• GET the form data from the request element

dynamic request = createInfo.request

• PUT the form data in the new assoc

//populate contact
contact.custno = request.custno
contact.phoneno = request.phoneno

• UPDATE the DAPINode’s ExtendedData property with the assoc

If IsDefined(node.pExtendedData) \
&& Type(node.pExtendedData) == Assoc.AssocType
//merge data assoc with existing pExtendedData assoc

Page 11-20 Open Text Corporation


Section 11: Storing Additional Node Data

node.pExtendedData = Assoc.Merge(node.pExtendedData,
contact)
else
//store data assoc in PExtenedData
node.pExtendedData = contact
end

□ 6. Don’t forget to SAVE and COMPILE NodeCreateSubClassPre().

□ 7. TEST your work: SAVE and EXPORT your OSpace, STOP and RESTART the Builder, and
ADD a new contact to see the prompt for customer number and phone number.

11.8.2 Part B: Updating

Create the functionality to update the attributes you just added. While we haven’t discussed
this step in class, you should be able to implement this functionality on your own; however,
we provide the following steps and hints, plus a sample solution at the end of the exercise.

□ 1. SET Contact WebNode.fHTMLInfo = contactupdate.html (changing the feature to a


string). Why?

□ 2. CREATE a new HTML file in your module’s html directory called


contactupdate.html. What should it do?

Hint: Use fRequest.node.pExtendedData to access the extended data for the node
from the contactupdate.html page.

□ 3. EDIT Contact.NodeUpdateSubClassPre(). (Why? What should it do? )

□ 4. EDIT Contact WebNode.1Setup()to MODIFY the list in the fPrototypeInfo2 feature.


(Why? What should it do?)

□ 5. COMPILE and RUN this script, SAVE and EXPORT your OSpace, and STOP and RESTART
the Builder.

□ 6. TEST your work: GO to the Info page of an existing contact and SELECT the tab labeled
“Specific”. You should now be able to change the values for the Customer Number
and Phone Number attributes.

Bonus:

OPEN the Info page on a contact that has a defined customer number and phone number.
CLICK the Update button at the bottom of the General tab. Then VISIT the Specific tab in the
Info page of that same contact. Are the customer number and phone number still there? If
not, see if you can figure out why, and add some code so the customer number and phone
number values do not get cleared? (Hint: What methods does the General page’s Update
button call?)

Livelink Builder Fundamentals Course Page 11-21


Section 11: Storing Additional Node Data

contactupdate.html page:
;;webscript contactupdate
; dynamic custno, phoneno, extendeddata = .frequest.node.pExtendedData
; if IsDefined( extendeddata )
; custno = extendeddata.custno
; phoneno = extendeddata.phoneno
; else
; custno = ""
; phoneno = ""
; end
;string img = .img()
<tr>
<td class="label">Customer No.:</td>
<td class="labelverticaldividerright"
background="`img`tbl-divider-ver.gif"
style="background-repeat: repeat-y;">
<img height="1" alt="" src="`img`spacer.gif" width="2" border="0">
</td>
<td><input class="valueeditable" type="text" name="custno"
size=5 value="`custno`"></td>
<tr class="horizontalcelldivider">
<td class="labelhorizontaldivider">
<img height="1" alt="" src="`img`spacer.gif" width="1"
border="0">
</td>
<td class="valuehorizontaldivider" colspan="2">
<img height="1" alt="" src="`img`tbl-divider-hor.gif"
width="3" border="0">
</td>
</tr>
</tr>
<tr>
<td class="label" valign="top" nowrap>Phone No.:</td>
<td class="labelverticaldividerright"
background="`.img()`tbl-divider-ver.gif"
style="background-repeat: repeat-y;">
<img height="1" alt="" src="`.img()`spacer.gif" width="2"
border="0">
</td>
<td><input class="valueeditable" type="text" name="phoneno"
size=40 value="`phoneno`"></td>
<tr class="horizontalcelldivider">
<td class="labelhorizontaldivider">
<img height="1" alt="" src="`img`spacer.gif" width="1"
border="0">
</td>
<td class="valuehorizontaldivider" colspan="2">
<img height="1" alt="" src="`img`tbl-divider-hor.gif"
width="3" border="0">
</td>
</tr>
</tr>
;;end

Page 11-22 Open Text Corporation


Section 11: Storing Additional Node Data

NodeUpdateSubClassPre() method:
// Private method
// Override this method to perform specific attrbutes assignment to the
node
// or preforming checking before actual updating.
//
// Parameters:
//
// node The DAPI node to be updated.
// updateInfo Attribute information in order to assign values.
// context Custom parameter.
//
// Return an assoc:
//
// OK TRUE if ok.
// ErrMsg Application error message if not ok.
// ApiError Error returned by API if not ok.

function Assoc NodeUpdateSubclassPre(\


DAPINODE node,\
Dynamic updateInfo,\
Dynamic context )

Assoc result
Assoc rtnval
Dynamic apiError
String errMsg

Boolean ok = TRUE
Object dapiCtx = updateInfo.DapiCtx

dynamic request = updateInfo.request

assoc contact
contact.custno = request.custno
contact.phoneno = request.phoneno

If IsDefined(node.pExtendedData) \
&& Type(node.pExtendedData) == Assoc.AssocType
//merge data assoc with existing pExtendedData assoc
node.pExtendedData = Assoc.Merge(node.pExtendedData, contact)
else
//store data assoc in PExtenedData
node.pExtendedData = contact
end

if IsUndefined( rtnval.OK )
rtnval.OK = ok
rtnval.ErrMsg = errMsg
rtnval.ApiError = apiError
end

return( rtnval )
end

Livelink Builder Fundamentals Course Page 11-23


Section 11: Storing Additional Node Data

Notes:

Page 11-24 Open Text Corporation


Section 12: Adding a New Node Command
Overview:

Thus far, you’ve been using existing Livelink node commands to create and manipulate a
new node type. But how do you implement new types of node commands? Creating new
commands and plugging them into the interface is the topic of this section.

Objectives:

By the end of this section, you will be able to add new


commands to the Function menu for Livelink nodes, using
Action objects and WebNodeCmd objects.

Livelink Builder Fundamentals Course 92-300 04Feb11 Page 12-1


Section 12: Adding a New Node Command

Browse
WebNodeCmd Object

"?func=ll&objId=2402&objAction=browse"

DTREE Table
DATAID NAME SUBTYPE (etc.)
2401 Erg.doc 144
ll Request Handler 2402 Budgets 0
Object
2403 Find the… 208
Features:
2404 Time.xls 144
Execute() method Get the subtype
(etc.)
Find the node
type objects
Get the action
to perform

Search for an
Folder LLNode Object Action object for
Features: that objAction and Reserve
Action Object
fSubType integer----0
Features:
_NodeTypes() method
_SubclassExecute() method
_ProtoType() method
If no Action object exists, search fWebScript
for a method of the WebNode
named Action-objActionValue fErrorPrefix

Folder WebNode Object


Features:
fSubType integer -----0
Action-Browse() method
Action-Delete() method
Action-Move() method

Figure 12-1: How Action objects fit into the ll request handler picture

Page 12-2 Open Text Corporation


Section 12: Adding a New Node Command

12.1 Details: How Commands Are Called

After the LL request handler locates the WebNode object


for a node type, it uses the objAction parameter specified
in the URL to find the method to execute for the requested
action. For most of the node types implemented in the off-
the-shelf Livelink system, the method is a feature of the
WebNode object, named in the format Action-
actionName(). However: When searching for the action to
execute, the LL request handler looks for an actionName
Action object before it looks for an Action-actionName
method (see Figure 12-1).

An Action object encapsulates the code for one particular


command. It stores:

• the _SubclassExecute() method, which makes the calls


to perform the action

• the WebLingo file name for the interface response to


the action

• a list of the node types for which this Action object


should be used

You should use Action objects:

• to add new types of commands to a new node type

• to add new types of commands to existing node types

• to override Action() methods of existing node types

Livelink Builder Fundamentals Course Page 12-3


Section 12: Adding a New Node Command

Action Object
Features:
_NodeTypes() method-------------Returns the list of node types to which the Action object
should be applied.
_SubclassExecute() method -----Performs the action.
_Prototype() method ---------------Defines the prototype for the action, validating and
converting inputs (optional).
fWebScript string -------------------Names the WebLingo file for the action (optional).
fErrorPrefix string -------------------Error message, to define if an error should be returned
instead of a WebLingo file.
fEnabled boolean -------------------Enables the object for initialization.

Figure 12-2: Key Action object features

// Returns the List of nodetypes (a.k.a. subtypes) to which this


// WebNodeAction applies.
//
// NOTE: Do not use "$Type" globals here because they may not be
// defined until AFTER the WebNodeAction has been initialized!
//
// A value of { Undefined } indicates that this WebNodeAction applies
// to all nodetypes. This should be used with EXTREME caution!

function List _Nodetypes() Have new action


available for suggestion
boxes, folder, and
return { 2001, 0, 136 }
compound documents.
end

Figure 12-3: Example WebNodeAction._NodeTypes() method

Page 12-4 Open Text Corporation


Section 12: Adding a New Node Command

Step set 12.1: Creating an Action Object

1. Orphan Webnode: WebNode Root: WebNodeAction


in your OSpace and name it NodeActions.
This will serve as the superclass for Action objects in
your OSpace.

2. Create a child of NodeActions and name it


according to the command you are creating. (In our
example, we’ll create an ItemsAndAuthor
command.)
The name of the object (its OSName feature) will
be the string used to identify the command, just as
is the “xxx” in an Action-xxx() method.

3. Set fEnabled to True, and run the BuildOSpace()


method in your Globals object to prepare the Action
object for initialization.
When an Action object is initialized, it is added to a
sort of subsystem that is searched when it’s time to
perform an action against a node. Remember that we used
the WebNode’s fCmdNames
4. Edit the _NodeTypes() method to return a list of the feature to define a basic list of
commands that should be
node types to which this Action Object should apply available to the node type?
(see Figure 12-3). Well, fCmdNames is not the
As you can see, an Action object can apply to more definitive list. Livelink regards
both the fCmdNames list and
than one node type. Livelink uses this method the results of Action objects’
during the initialization of the Action object. _NodeTypes() methods to
determine which commands
should be available.
5. If you like, set the fWebScript feature to the name
of the WebLingo file you create to produce the
interface response for the new action.
If you do not define the fWebScript feature,
Livelink will automatically look for a WebLingo
file of the name actionName.html, for example, If the _NodeTypes()
“ItemsAndAuthor.html.” method returns UNDEFINED,
this command will be
available for all webnodes.
6. Edit the _SubClassExecute() method and create a Use with caution.
WebLingo file for the new command— see Section
12.3).

Livelink Builder Fundamentals Course Page 12-5


Section 12: Adding a New Node Command

Element Description
node A DAPINode containing the item (node) referred to by the request.
PrgCtx The program session information, containing subelements such as
fUSession, with the requesting user’s information, and fDbConnect,
with all the database connection information.
objectId The ID of the item (node) the user’s request is about.
PrgCtx.fUSession The requesting user’s information (userid, username, etc.).
PrgCtx.fDbConnect The database connection information (tablespace, userid, password,
etc.).
query_string The URL request string.

Figure 12-4: Key elements of the Request record

LL Request
Element Handler feature Description
populated
response.error.message fError If defined (with a string), contains an error string and
triggers the display of an Error page containing this
string, prefixed with the contents of fErrorPrefix.
response.error.prefix fErrorPrefix If fError is set and fErrorPrefix contains a string, the
error page will show this string at the top of the
page, followed by the contents of fErrorMessage.
(“Error processing request” is the default.)
response.error.detail fErrorDetail If fError is set and fErrorDetail contains a string, the
error page will display a “Show Details” button,
which when clicked shows the string in a dialog box.
response.filename fDownloadFile If defined, contains the name of a file on the server
to download and triggers the action of downloading
the file.
response.mimeType fDownloadFile If defined, contains the MIME type of the file named
MimeType in fDownloadFile.
response.location fLocation If defined, contains a URL string and triggers a call
to that URL once the request is complete.
response.webscript fHTMLFile If defined, contains the name of a WebLingo file and
triggers the generation of an HTML page based on
this file once the request is complete.
response.data fResponse.data Stores data retrieved during the execution of the
_SubclassExecute() method, for use in the
WebLingo file named in fHTMLfile.

Figure 12-5: Key elements of the Response assoc

Page 12-6 Open Text Corporation


Section 12: Adding a New Node Command

12.2 Passing Data from Request to Output

Before you edit the _SubclassExecute() method and create


the WebLingo file, you need to know more about how the
request and response information is structured.

As you learned in Section 11, the LL request handler is


passed a request record that contains all the information
passed from the web browser. Figure 12-4 describes some
of the key elements of this request.

As you also learned in Section 11, the LL request handler


looks for a response assoc to store in its fResponse feature,
and this assoc contains all the information you wish to pass
back to the web browser. Livelink expects certain elements
in the response assoc to be set as it is passed from
LL.Execute() to Action methods and back. You are not
required to define all the elements of the response assoc,
and in fact, you should not define them all in most cases.
Figure 12-5 names the response assoc’s elements and the
LL features to which they are assigned.

Livelink Builder Fundamentals Course Page 12-7


Section 12: Adding a New Node Command

Define a “response”
function Assoc _SubclassExecute( \ assoc for storing results
Object webNode, \
Record request )
Pull elements from the
Assoc response = ._NewResponse() request record that are
Object node = request.node needed for performing
the data transactions
List contents = DAPI.ListSubNodes( node )
Add elements to the
If IsNotError(contents) response.data assoc to
response.data.contents = contents store the data to be used
else in the WebLingo file
response.error.prefix = "Error getting contents"
response.error.message = "Container is empty"
end
Add elements to define
return response response.error.prefix and
end response.error.message
if there is a problem

Figure 12-6: Example _SubclassExecute() method for an Action object

<!-- File: suggestions/itemsandauthor.html -->


<HTML><BODY><TABLE>
;Dynamic request = .fRequest
;Dynamic response = .fResponse
;Dynamic contents = response.data.contents
;DAPINode item
;Object open, webnode
;Object webNodes = $WebNode.WebNodes
Gather data from ll request and
response features
<TR BGCOLOR="#CCCCCC">
<TD nowrap>Type</TD>
<TD nowrap>Name</TD>
<TD nowrap>User Name</TD> Get the User information
</TR> for the user who authored
this node (creator)
;for item in contents
;record result = $WebNode.WebNodeUtils.NodeToWebNode(item)
;RecArray UserRecs = UAPI.GetUserById( \ Display the item’s icon,
request.prgCtx.USession().fSession, item.pUserID ) name, and the authors
;webNode = webNodes.GetItem( item.pSubtype ) username
;open = webNode.Cmd( "open" )
<TR>
<TD NOWRAP WIDTH="1%">`%Lopen.DisabledUnescapedLink( \
request.prgCtx, request, result, webNode.IMG( result ) )`</TD>
<TD NOWRAP>&nbsp;`%Lopen.DisabledLink( request.prgCtx, request, result, \
item.pName )`</TD>
<TD NOWRAP ALIGN="center" WIDTH="1%">`userRecs[1].name`</TD>
</TR>
;end
</TABLE></BODY></HTML>

Figure 12-7: Example WebLingo file for an Action object (see Figure 12-11 for results)

Page 12-8 Open Text Corporation


Section 12: Adding a New Node Command

12.3 Doing the Work: The Action Object’s _SubclassExecute()


Method and WebLingo File

The _SubclassExecute() method of the Action object is the


method you should modify to perform the action. This
method is passed the request argument, which is a
reference to the fRequest feature in the LL request handler.
See Figure 12-4 for a list of the record’s key fields, and
Figure 12-6 for an example of getting data from the request WebNodeCmd objects
inherit methods for assisting in
argument. displaying an item with or
without an HTML ANCHOR tag.
In the example in Figure 12-7),
The method must populate and return the response assoc we use DisabledLink() and
DisabledUnescapedLink().
described in Section 12.2, as in the example in Figure 12-6.
The LL request handler processes the response assoc just The methods may build a URL
for the ANCHOR tag using the
as it does for other action methods and objects. You can use first three arguments passed to
the elements of the assoc in the WebLingo file you create the method. The fourth
for the action object, as in the example in Figure 12-7. argument is the text or image to
display for the link. The
methods return a string in the
format “<A HREF=
The WebLingo file you create for the Action object, if any, ’URLBuiltFromArgs123’>Arg4</
must be stored in your module’s html directory. You have A>
Depending on the arguments
three options for identifying it to the LL request handler: passed to the methods, they
may decide that there should be
• It can be named after the Action object name—for no ANCHOR tag (meaning, the
example, itemsandauthor.html, or link should be “disabled”), in
which case the return value is
simply the fourth argument.
• you can edit the fWebScript feature of the Action object “Escaped” and “Unescaped”
to specify the WebLingo file name, or refers to whether to “escape” a
string for use in HTML. For
example, the string “<Sigh>”
• you can set response.webscript within
_SubClassExecute() to the file name.

Livelink Builder Fundamentals Course Page 12-9


Section 12: Adding a New Node Command

Browse WebNodeCmd Object


Features:
fEnabled -------------True
fQueryString ------ ?func=ll&objId=%1&objAction=browse
fIncludeNextURL --False

"?func=ll&objId=2402&objAction=browse"

DTREE Table
DATAID NAME SUBTYPE (etc.)
2401 Erg.doc 144
ll Request Handler 2402 Budgets 0
Object
2403 Find the… 208
Features:
2404 Time.xls 144
Execute() method Get the subtype
(etc.)
Find the web
node object
Get the action
to perform
Checkout
Search for an
Action Object
Folder LLNode Object Action object for Features:
Features: that objAction and Reserve
_NodeTypes() method
Action Object
fSubType integer--- 0
_SubclassExecute() method
Features:
_ProtoType() method
_NodeTypes() method
fWebScript
_SubclassExecute() method
fErrorPrefix method
_ProtoType()
If no Action object exists, search fWebScript
for a method of the WebNode
named Action-objActionValue fErrorPrefix

Folder WebNode Object


Features:
fSubType integer ---- 0
Action-Browse() method
Action-Delete() method
Action-Move() method

Figure 12-8: How WebNodeCmd objects fit into the ll request handler picture

Page 12-10 Open Text Corporation


Section 12: Adding a New Node Command

12.4 Tying the Action Object to the Interface with a


WebNodeCmd Object

Whether commands are implemented using Action-


[commandName] scripts or WebNodeAction Objects, a
Livelink does not require that
WebNodeCmd object is still necessary to control and the Action object and
output the display aspects of the command. This includes WebNodeCmd objects have the
the URL for the command, the display name, and the same name, but it does make it
easier to debug your work later.
minimum permissions needed to see the command. See the Signature() method of
your WebNodeCmd object for
Step set 12.2: Creating a New WebNodeCmd Object using a different object name.

1. Orphan WebNode:WebNodeRoot:WebNodeCmd ,
and name it to be a class object for all
WebNodeCmd objects in your OSpace. (In our By default, the command is
example, we’re using SuggestionsCommands.) listed under the Function menu of
the node types specified with the
_NodeTypes() method. You can
2. Create a child of the orphan. Give it the same name edit the _CmdTypes() method of
you gave your Action object. the WebNodeCmd object to
specify a different display location
for the command. For example, if
3. Set the new object’s fEnabled feature to True and the method returns { ‘info’ }, the
run your OSpace’s Globals.BuildOSpace() method command displays as a tab on the
to prepare the object for initialization. Info page for the applicable
nodes.
4. Set the following features of the new object:

Feature Example Value Notes


fName Browse by Author This string will appear in the Function
menu. It is the display name for the
command.
fQueryString func=ll&objid=%1& %1 will be automatically filled in with the
objAction=itemsandAuthor node’s unique object id. The objAction
string will be mapped to a script in the
WebNode named “Action-
ItemsandAuthor”. The fQueryString
feature defines the URL to be executed
for this command.
fIncludeNextURL TRUE Livelink will use the calling page’s URL as
the next URL (the page to visit after this
action is complete) if this feature is set to
TRUE.

(continued)

Livelink Builder Fundamentals Course Page 12-11


Section 12: Adding a New Node Command

.fPerms = $PSeeContents

Figure 12-9: Example 0 Setup() code for setting fPerms

During startup, Livelink defines a set of global


variables starting with the letter “P” to represent various
permissions. Examples: $PSee, $PCheckout, $PDelete.
Use the Application Globals command under the Tools
menu to list all global variables—you will find all the
“permissions” global variables in this list.

Figure 12-10: New command on the Function menu

Figure 12-11: Result of the “List Items and Author” example command

Page 12-12 Open Text Corporation


Section 12: Adding a New Node Command

(Creating a WebNodeCmd, continued)

5. Edit the WebNodeCmd’s _Nodetypes() method to


return a list of node types for which this command
should be available, just as you did with the Action
object’s _NodeTypes() method.

6. Edit and run the 0 Setup() method to define fPerms


as an integer representing the minimum permissions
the current user must have in order to see the
command. See Figure 12-9 and its corresponding
note for more information.

7. Edit the _ SubClassIsEnabled() method so you can


easily enable or disable a command by having this
method return a true (enable) or false (disable). You
can put whatever code you want in it for the
enable/disable logic. Always look at features
when the name includes
8. Exit and restart, then test your work by looking for ‘subclass’ as potential
features to override.
a new command on the node type’s Function menu.

Livelink Builder Fundamentals Course Page 12-13


Section 12: Adding a New Node Command

Browse
WebNodeCmd Object

"?func=ll&objId=2440&objAction=browse"

DTREE Table
DATAID NAME SUBTYPE (etc.)
2401 Erg.doc 144
ll Request Handler 2440 Manual 136
Object
2403 Find the… 208
Features:
2404 Time.xls 144
Execute() method Get the subtype
(etc.)
Find the web
node object
Get the action
to perform
Checkout
Search for an
Action Object
Compound Doc Action object for Features:
LLNode Object that objAction and Browse
node type. _NodeTypes() method
Action Object
Features:
_SubclassExecute() method
Features:
fSubType integer ---0
_ProtoType() method
_NodeTypes() method
fWebScript
_SubclassExecute() method
fErrorPrefix method
_ProtoType()
Since an action object was fWebScript
found, the existing Action-
Browse() method is not used. fErrorPrefix

Compound Doc
WebNode Object
Features:
fSubType integer-----0
Action-Browse() method
Action-Delete() method
Action-Move() method

Figure 12-12: Overriding an action by creating an Action object

Page 12-14 Open Text Corporation


Section 12: Adding a New Node Command

12.5 Using Action Objects to Override Existing Commands

Remember, the LL request handler looks first for an Action


object, then for an Action-actionName method of a
Webnode. So if you want to override, for example, the
Browse command for a compound document, you can:

• Create an Action object, naming it “Browse”.

• Set its _NodeTypes() method to return a list containing


the subtype number for the compound document (which
is 136) .

• Set the other features of the Action object to perform


the action you want it to perform.

The folder and other node type objects will continue to use
the off-the-shelf “browse” functionality, but the compound
document will use the Browse functionality you defined.

Livelink Builder Fundamentals Course Page 12-15


Section 12: Adding a New Node Command

12.6 Summary

• After the LL request handler has located the WebNode


object for the request it is processing, it looks for the
action to perform against the object. Livelink first looks
for an Action object whose name matches the objAction
parameter of the URL and which has been initialized to
be available for the node’s node type. If there isn’t an
Action object, Livelink looks for an “Action-” method
of the WebNode object whose name matches the
objAction parameter.

• While most of the off-the-shelf actions are currently


implemented using Action- methods as opposed to
Action objects, when you do customization, you can
and should create Action objects to implement new
commands and to override existing Action- methods.
This gives you a way to enhance the functionality of
existing node types without modifying their WebNodes.

• Creating a new Action object is just like creating other


types of Livelink objects—you orphan the right object
and set its features. Two of the key features of Action
objects are its _NodeTypes() method, which defines the
node types to which the Action object should apply, and
its _SubClassExecute() method, which defines the
action to perform.

• When you create an Action object for a new command,


you need to create a new WebNodeCmd object to go
with it. The WebNodeCmd object’s fQueryString
feature defines the URL which calls the LL request
handler with the correct objAction and other
parameters.

• Overriding an existing Action-method is as simple as


creating an Action object of the same name as the
method and specifying the node types to which it
should apply.

Page 12-16 Open Text Corporation


Section 12: Adding a New Node Command

12.7 Section 12 exercise

Create a new command for the new contact node. The new command should list the name,
the created date and last modified date of the items within a contact. Have the command
appear in the Function menu of the Info page. Also have this command work for folder nodes
and compound document nodes. When you select the command,

the resulting page should look similar to this one:

12.7.1 Part A: Create the Action Script

□ 1. ORPHAN WEBNODE : WebNode Root : WebNodeAction in your OSpace and name it


NodeActions.

□ 2. CREATE a child of NodeActions and call it ItemsInfo.

□ 3. SET fEnabled to True, then RUN the BUILDOSPACE() method of your Globals object.

□ 4. If you wish to name your WebLingo file (the one that will display the results of your
new command) anything other than itemsinfo.html, you must STORE that name in the
fWebScript feature.

□ 5. CHANGE the data type of fErrorPrefix to String (in which object will you do this?).
Then SET fErrorPrefix = Error Listing Contents.

□ 6. EDIT _Nodetypes() to return {0, 2002} (the subtypes for folders and contacts).
Include other subtypes if you want this command to be available to them.

□ 7. EDIT _SubclassExecute() to get the contents of the item that the user was viewing
when selecting this command, using the DAPI.ListSubNodes() built-in function.
Example:
dynamic node = request.node
dynamic contents = DAPI.ListSubNodes( node )

Livelink Builder Fundamentals Course Page 12-17


Section 12: Adding a New Node Command

□ 8. In _SubClassExecute(), set response.data.contents to the contents of the item


the user was viewing if no error occurred.
If there was an error, set response.error.message to the string you want to appear on
the error page:
if length(contents) > 0
response.data.contents = contents
else
response.error.message = "Container is empty."
end
return response

□ 9. COMPILE and SAVE _SubClassExecute(), and then SAVE and EXPORT your OSpace.

12.7.2 Part B: Create a WebNodeCmd Object

□ 1. ORPHAN WEBNODE : WebNode Root : WebNodeCmd and call it ContactCmds.

□ 2. CREATE a child of ContactCmds and call it ItemsInfo.

□ 3. Set ItemsInfo.fEnabled = True.

□ 4. RUN the BuildOSpace() script in your Globals object.

□ 5. SET ItemsInfo.fName to a String datatype.


SET fName = Browse Content Info. (Why?)

□ 6. SET fQueryString = func=ll&objid=%1&objAction=ItemsInfo


(What does this accomplish?)

□ 7. SET fIncludeNextUrl = True. (What does this accomplish?)

□ 8. EDIT _Nodetypes()to return {0, 2002} (the subtypes for folders and contacts).
Include other subtypes if you want this command to be available to them.

□ 9. EDIT 0Setup()to contain


.fPerms = $PSeeContents
(Why?)

□ 10.RUN the setup script. (Note: By default, the 0Setup() method’s code is commented
out—be sure to remove the comments.)

□ 11.SAVE and EXPORT your work.

Page 12-18 Open Text Corporation


Section 12: Adding a New Node Command

12.7.3 Part C: Create the HTML File

□ 1. CREATE an itemsinfo.html file in your module’s html directory. (If you set the
fWebScript feature of your action object, make sure the filename matches.)

□ 2. EDIT the itemsinfo.html file to contain a table that lists the name, creation date, and
modify date of each child of the item. (Hint: Look at the online help for the DAPI
package to see a list of DAPINode attributes. There is an example itemsinfo.html file
at the end of this exercise.)

□ 3. After successfully compiling and saving the WebLingo file, EXIT the Builder and
RESTART it.

□ 4. TEST your work: VISIT the Info page of a folder or a contact that contains children. Is
the “Browse Content Info” command available from the Function menu? Does it work?

12.7.4 Example Solution

itemsinfo.html File:

<html>
<title>Content Information</title>`%L.Styles()`
<body ONLOAD="onLoadFunction()">
;string htmlPrefix = .HTMLPrefix()
;assoc args
; args.Title1 = "<B>Contents Information</B>"
; args.BGColor = "blue"
;;call <htmlPrefix + "commonheader.html">( args )

<table>
;dynamic request = .fRequest
;dynamic contents = .fResponse.data.contents
;DAPInode item
<TR BGCOLOR="#CCCCCC">
<TD>Name</TD>
<TD>Created</TD>
<TD>Last Modified</TD>
</TR>
;for item in contents
<tr>
<td>`item.pName`</td>
<td>`item.pCreateDate`</td>
<td>`item.pModifyDate`</td>
</tr>
;end
</table>

;;call <htmlPrefix + "menufoot.html">


</body>
</html>

Livelink Builder Fundamentals Course Page 12-19


Section 12: Adding a New Node Command

Notes:

Page 12-20 Open Text Corporation


Section 13: The Chain of Events in Servicing a Request
Overview:

These next sections will use two examples to illustrate how and where to begin your
modifications and how to locate methods and built-in functions to override existing Livelink
functionality.

In this section we look at building a recycle-bin or garbage can for deleted documents. This
example shows how to trace through the chain of events of a request handler from beginning
to end.

Section 14 looks at modifying the navigation menus. Here, a different approach is used,
starting with an HTML page and tracing the operations from how the menu is created to
how it is displayed to the user.

You need to see the chain of events Livelink takes in servicing a request. Once you see this,
you want to find the appropriate place(s) to break into that chain.

The head of the chain is always ServerCallback in the APIServer object in the APISRV
OSpace. The other end of the chain is typically the generation of an HTML page.

Livelink Builder Fundamentals Course 92-300 04Mar05 Page 13-1


Section 13: The Chain of Events in Servicing a Request

Figure 13-1: The Debugger window

Figure 13-2: The ‘Running Documents’ window of the MS Script Debugger

Page 13-2 Open Text Corporation


Section 13: The Chain of Events in Servicing a Request

13.1 The Start of the Chain

The programming objective is to implement a recycle bin


in Livelink similar to the recycle bin of an MS-Windows
desktop.

Setting the break on entry toggle for any method in


Livelink shows the calling stack (or chain of events) for
that method. You can see (and go to) each method in the
stack right back to the beginning (see Figure 13-1).

You ultimately want to break into the chain and insert your
own code in one or more places, so you must find the
appropriate links to break.

You already know one link of the chain: the method where
you set the break on entry. Now you must find the ends of
the chain and the other links between.

Implementing the recycle bin requires overriding the Delete


function. To find the URL the function menu generates,
execute the function in IE and select View-
Script Debugger-Open and then View-Running Documents
(see Figure 13-2). Observe that “delete” is an objAction to
LL. Recall the LL request handler from the Builder course,
and then find the execute method in
WEBNODE:NodeRequestHandler:LL:Execute() and set
break on entry.

1. Setting break on entry and executing any function that


calls LL shows the calling stack. The first entry in the
stack is called: ServerCallback:ServerCallback.

2. You can select ServerCallback:ServerCallback then


right click the <this> variable and browse it.

3. You can zoom out to see the object and OSpace in


which ServerCallback:ServerCallback lives.

You can now begin the journey along the chain.

Livelink Builder Fundamentals Course Page 13-3


Section 13: The Chain of Events in Servicing a Request

Figure 13-3: The APISRV OSpace

Page 13-4 Open Text Corporation


Section 13: The Chain of Events in Servicing a Request

13.2 The APISRV OSpace (The Start of the Chain)

Purpose: This OSpace creates a new thread and a socket to


that thread. It then calls the dispatcher and when the Livelink is multithreaded
dispatcher returns, the socket is closed and the thread is and non-blocking, so don’t fall
destroyed. into the trap of having a
request handler calling a
request handler.

…Especially as the Builder is


single threaded, so you will
not find your error until you go
“live”.

There are two methods of interest in the APIServer object:

ServerCallback Creates a new temporary object of APIServer and then


calls its …

ThreadStartup (the new Creates a socket and calls the method DispatchLLServer in
temporary one) the RequestHandlerSubsystem object, which is in the
WEBDSP OSpace. Once complete, it closes the socket and
deletes the thread.

Q. Should you break the chain here for your Delete


modifications or any other purposes?

A. No. Clearly this is not a suitable place, as Livelink has


just begun processing the request. Livelink has yet to
determine some fundamental things like:

• Is the user logged in?

• What function does the user wish to perform?

• Where in Livelink is the user?

• Does the user have permission to perform this function?

Let’s move down into to the WEBDSP OSpace and look at


DispatchLLServer.

Livelink Builder Fundamentals Course Page 13-5


Section 13: The Chain of Events in Servicing a Request

Figure 13-4: The WEBDSP OSpace

Figure 13-5: Searching for the LL request handler

Page 13-6 Open Text Corporation


Section 13: The Chain of Events in Servicing a Request

13.3 The WEBDSP OSpace

Purpose: There are three main objects in this OSpace:

Root:RequestHandler This is the prototype of all request handlers in Livelink.

Root:RequestHandlerGroup This is the prototype of all request handler groups in


Livelink.

RequestHandlerSubsystem This is one of the many subsystems in Livelink. It manages


all request handlers and it also dispatches HTTP requests to
request handlers.

There are four features of interest in the


RequestHandlerSubsystem:

DispatchLLServer Performs some checking such as whether this is a request from


the web or from LAPI. It then it calls …

Dispatch Creates a temporary instance of the request handler and calls


its ExecuteHandler method. Dispatch finds the appropriate
request handler by calling …

GetItem Uses a simple caching technique where all the request handler
name and pointer pairs are stored in …

fRegistry An assoc containing the names and pointers to all the enabled
request handlers.

Q: Should you break the chain here for your delete


modifications?

A: Again the answer is probably no, as all you know so far


is the name of the request handler but nothing about the
user or about the object the user wishes to delete.

You know you are calling the LL request handler, so you


inspect fRegistry to find its name and then search to find
the object. You ultimately find it in the WEBNODE
OSpace.

Livelink Builder Fundamentals Course Page 13-7


Section 13: The Chain of Events in Servicing a Request

Figure 13-6: The WEBNODE OSpace

Page 13-8 Open Text Corporation


Section 13: The Chain of Events in Servicing a Request

13.4 The WEBNODE OSpace

Purpose: There are five objects of interest in this OSpace:

Root:WebNode This is the parent for all WebNode objects in Livelink.


Recall that the WebNode object controls the GUI
functionality for Livelink items.

Root:WebNodeAction This is the parent of all WebNodeAction objects in


Livelink. Recall that request handlers always run a
WebNodeAction object’s execute method if it exists,
otherwise they run the Action method in the WebNode
object.

Root:WebNodeCmd This is the parent of all WebNodeCmd objects in


Livelink. Recall that the WebNodeCmd object supplies
the name, permissions, and URL for the command.

WebNodeCmdRegistry This is the subsystem that registers all webNodeCmd


objects.

LL The request handler that deals primarily with documents.

Let’s look in detail at the LL object.

Livelink Builder Fundamentals Course Page 13-9


Section 13: The Chain of Events in Servicing a Request

Figure 13-7: The LL Object

Page 13-10 Open Text Corporation


Section 13: The Chain of Events in Servicing a Request

13.4.1 The LL Object

There are eight methods to investigate in the LL object. As


you saw in the WEBDSP OSpace, the Dispatch method of
the RequestHandlerSubsystem object makes a temporary
child object of the request handler and calls its
ExecuteHandler method.

The first five methods of interest:

ExecuteHandler This is the main routine of the request handler. It calls the
following methods as required.

Setup Initializes some local features, most notably fHTMLFile.

CheckArgs If a prototype exists (.fPrototype) for this request handler then


call CheckArgsUtil which validates the URL string against the
prototype.

ExecuteRequest Has only one line of code where it calls …

ExecuteWithLogin If there is no cookie then redirect the user to the login page
telling it to come back here once the user logs in. If the user has a
cookie, ensure it is valid and then call …

Livelink Builder Fundamentals Course Page 13-11


Section 13: The Chain of Events in Servicing a Request

Your functionality without


modifying existing Livelink
code

Run existing (or


overridden) Action-
method

Here is how your


data gets to the
WebLingo file

If there is a prototype
then ensure the
parameters are okay

Build parm. Do you recall


the contents of parm?

Figure 13-8: The LL Execute method

Page 13-12 Open Text Corporation


Section 13: The Chain of Events in Servicing a Request

The other three methods of interest:


Execute This is where you put your code if you are creating a new request
handler.

In the LL request handler you see the hook provided to create a


WebNodeAction object to override the Action- method of the
WebNode object. This is the recommended way to override this
functionality.

Sometimes the wholesale replacement of the Action- method is not


required, and instead only the addition of functionality is needed. To
add functionality you would still create your WebNodeAction
object, but you would copy the code from the request handler to
force a call to the Action- method either before or after your new
code.

GenerateOutput Decides upon the type of output to generate and calls the
appropriate method.

GenerateHTML The most-called method from GenerateOutput: It passes the name


of the HTML file to WebLingo.WebScript.RunFileWithArglist()
where the HTML file is interpreted.

Other features of LL:

1. SetPrototype – a method that sets …

2. fPrototype – a feature for validating the URL.

3. fResponse – a feature for passing data to the HTML


page (WebLingo file)

Q. Should you break the chain here for your Delete


modifications?

A. In this case you are overriding the Delete method so the


answer is no. However, now that you understand the
operation, you can see how you might add a new request
handler of your own. You also see a number of methods
that could be modified, but you know that LL is called from
many places. The official word from Open Text is to make
either a new request handler or a new WebNodeAction
object. First though we all remember those Action-
methods, do you recall where their parent object lives?

Livelink Builder Fundamentals Course Page 13-13


Section 13: The Chain of Events in Servicing a Request

Figure 13-9: The WEBNODE Object

Page 13-14 Open Text Corporation


Section 13: The Chain of Events in Servicing a Request

13.4.2 The WebNode Object

Purpose: Recall from the Builder course how the WebNode


object controls the GUI functions. This is one of the objects
you orphaned for your suggestion box. Of course, LL will
call one of the Action- methods inside the WebNode object.

Notice that in the Execute method of LL the code checks


for a prototype for the function, and if one exists it runs
checkArgsUtil before running the Action- method. It also
sets up the parm variable to send to the Action- method.

We want to override the Action-Delete method. Rather than


orphaning the WebNode object and modifying the method,
the recommended strategy is to orphan the
WebNodeAction object and modify its features.

Writing the code for the recycle bin is not really the point
of this example, finding out where to write the code is, and
so we have met our objective.

Livelink Builder Fundamentals Course Page 13-15


Section 13: The Chain of Events in Servicing a Request

13.5 Summary

• You have traveled the chain of events from the


beginning to almost the end.

• You have seen a number of places to consider


overriding and inserting code.

• You have determined the exact place to put your new


code.

• You have stared into the abyss of creating a new


request handler and have turned away instead to
implement an Action object.

Page 13-16 Open Text Corporation


Section 13: The Chain of Events in Servicing a Request

13.6 Section 13 exercise

Select one of the following exercises. If you have time, do


the other.

Exercise 1 [Approximate time: 1 hour]

Using the techniques presented in class, implement the


ItemInfo function as a replacement for the Browse function
for Folders and Contacts. That is, when the user selects the
Browse command for Folders and Contacts the ItemInfo
function is performed.

Exercise 2 [Approximate time: 1 hour]

Using the techniques presented in class, implement the


Outline function for folders. Note that in off-the-shelf
Livelink this function is only available for Compound
Documents.

Livelink Builder Fundamentals Course Page 13-17


Section 13: The Chain of Events in Servicing a Request

13.7 Section 13: Exercise Solutions

13.7.1 Exercise 1

1) Observe that the Browse function calls the LL request


handler. As we did in class, set a breakpoint in this
request handler and execute a browse function on a
folder or contact and trace the operation.

2) A successful trace of the stack should lead you to the


Action-Browse method of the appropriate webnode
object.

3) You now know how to override the functionality of an


Action-x method by creating a WebNodeAction object
and overriding its _subclassExecute method.

13.7.2 Exercise 2

1) Use an existing compound document or create a new


one. From the function menu select Outline and observe
the resulting URL. Note that it calls the LL request
handler. As we did in class, set a breakpoint in this
request handler and execute the Outline function again
and trace the operation.

2) A successful trace of the stack should lead you to the


Action-Outline method of the Compound Document
webnode object.

3) You now know how to create new, and override


existing, functionality of an Action-x method by
creating a WebNodeAction object and overriding its
_subclassExecute method. In this case you want to
create a new function for folders.

4) Create a WebNodeAction object and copy the code


from the Action-Outline method of the Compound
Document Webnode to the _subclassExecute method.

5) What changes will you need to make?

Page 13-18 Open Text Corporation


Section 14: Modifying the Navigation Menus
Overview:

Previously, the search started through the chain of events at


a request handler. In this section we will start from a web
page.

This section illustrates how you can modify the navigation


menus. We will guide you through the chain of events that
generate and execute the navigation menus and their
components.

Livelink Builder Fundamentals Course 92-300 04Mar05 Page 14-1


Section 14: Modifying the Navigation Menus

Figure 14-1: The Navigation menus

Page 14-2 Open Text Corporation


Section 14: Modifying the Navigation Menus

16.1 The Navigation Menus

As discussed in the Builder course, the navigation menus


are cached when Livelink starts up. This means that no
matter which Livelink page is in the user’s browser, it is
assured that the navigation menus will be consistent.

Also recall that in the Builder course one of the things


discussed and modified was the
LivelinkNavigationCallback.Execute() method, which was
orphaned from the WEBLL OSpace.

What is required now is to trace through the chain of events


that creates and displays the navigation menus and find
suitable places to modify that chain.

Livelink Builder Fundamentals Course Page 14-3


Section 14: Modifying the Navigation Menus

Weblingo file comment

Code removed for clarity


Personal Menu Items

Figure 14-2: Part of the HTML source code

Page 14-4 Open Text Corporation


Section 14: Modifying the Navigation Menus

14.2 Let the Hunt Begin

Start at any page that has the navigation menus and view
the source.

Scroll through the code until you find something that looks
like it has something to do with the navigation menus. In
this case the JavaScript function looks like a definite
candidate.

Just above the JavaScript function you can see an HTML


comment
<!-- File: GlobalMenu.html -->

File comments like these without any directory prefix mean


the files are usually found in the $LLHOME/HTML
directory.

So open the GlobalMenu.html file in your favorite text


editor, and you can begin tracing the chain of events.

Livelink Builder Fundamentals Course Page 14-5


Section 14: Modifying the Navigation Menus

;;webscript globalmenu( Assoc Args )


<!-- File: GlobalMenu.html -->

;Integer iItemNum
;List menuNames

;Assoc item
;String img = .Img()
;Boolean NetscapeOnMac = $WebLL.WebUtils.MacClient( .fArgs ) &&
!$WebLL.WebUtils.MSIEclient( .fArgs )
;Boolean MSIE = $WebLL.WebUtils.MSIEclient( .fArgs )
;String myLeavePage = ''
;Boolean targetParent = FALSE
;Boolean MacPlatform = $WebLL.WebUtils.MacClient( .fArgs )
;Object sysPrefs = $Kernel.SystemPreferences
;Integer startStaticMenu = 0
;Dynamic leftMenu = undefined
;String lastMenuName = ""
;Integer tdWidth = 4
;Integer width = 100

// if leftMenu
;if ( IsFeature( args, 'LeftMenu' ) && IsDefined( args.LeftMenu ) )
;tdWidth += 1
;end

---Javascript code removed ---

<TD VALIGN="TOP" WIDTH="`tdWidth*width `" ROWSPAN="2" CLASS="pagebody">


<TABLE CELLSPACING="0" CELLPADDING="0" WIDTH="100%" BORDER="0">
<TBODY>
<TR>
// Left Menu Name Generation
//////////////////////////////
;if IsFeature( args, 'LeftMenu' )
;leftMenu = args.LeftMenu
;end
;if Isdefined( leftMenu )
;for item in leftMenu
;if ( IsFeature( item, 'Order' ) )
;if IsUndefined( Str.Locate( item.Order, "." ) )
<TD ROWSPAN="2"><IMG HEIGHT="27" ALT="" …
<TD ID="`item.label`" HEIGHT="24" …
&nbsp;&nbsp;&nbsp;<A CLASS="globalMenu" …
</TD>
;end
;end
;end
;end

Figure 14-3: A section of GlobalMenu.html

Page 14-6 Open Text Corporation


Section 14: Modifying the Navigation Menus

14.3 The GlobalMenu.html File

At the top of the file you can see that GlobalMenu gets the
contents of fArgs to use to determine the type of browser
the user has.

Looking closely you can see that GlobalMenu .html is a


webscript with embedded JavaScript. But look even closer,
the JavaScript is actually writing a Java Applet! It is now
apparent why it needs to know what type of browser the
user has.

The first part of the code sets up the header information.

The next part (shown opposite) builds any extra navigation


menus to the left of the permanent navigation menus. For
example, when inside a project there is an extra “Project”
menu.

Livelink Builder Fundamentals Course Page 14-7


Section 14: Modifying the Navigation Menus

/////////////////////////////
// Main Menu Name Generation
/////////////////////////////

;String theURL
;Integer pos
;String nMenu
;Assoc allMenuItems = $WebLL.LivelinkNavigationCallbackSubsystem.Items( Undefined,
.fArgs )
;Integer lastMenu = 0

;for item in allMenuItems.menu


;if IsUndefined( Str.Locate( item.menu, "." ) )
<TD ROWSPAN="2"><IMG HEIGHT="27" ALT="" SRC="`img`global-menu-divider.gif" …
<TD HEIGHT="24" BACKGROUND="`img`global-menu-bg.gif">
&nbsp;&nbsp;&nbsp;<A CLASS="globalMenu" HREF="" …
</A>
</TD>
;end
;end

--- some code omitted ---

///////////////////////////////////////
// Main Menu Generation
////////////////////////////////////////

;for item in allMenuItems.menu

;if startStaticMenu > 0


;pos = Str.Locate( item.menu, "." )
;if pos > 0
;nMenu = Str.ValueToString( Str.StringToInteger( item.menu[ : pos - 1 ] ) + …
;nMenu += item.menu[ pos : ]
;else
;nMenu = Str.ValueToString( Str.StringToInteger( item.menu ) + startStaticMenu )
;end
;else
;nMenu = item.menu
;end

;if Isundefined( Str.Locate( nMenu, "." ) )

Figure 14-4: Another section of GlobalMenu.html

Page 14-8 Open Text Corporation


Section 14: Modifying the Navigation Menus

GlobalMenu.html Continued…

We see that the main menu generation is based upon the


variable allMenuItems which has a sub-component called
menu. Looking back up the code we see a call to

$WebLL.LivelinkNavigationCallbackSubsystem.Items()

…and the results are put into allMenuItems.

Once it has allMenuItems, the script builds the menus with


sections and separators.

The most important point is that allMenuItems itself has


already been populated and divided into multiple menus
and these divided into multiple parts. This means that to
modify the navigation menus you will have to trace back
into

$WebLL.LivelinkNavigationCallbackSubsystem.Items()

That is, there is nothing here that you should be modifying.

Livelink Builder Fundamentals Course Page 14-9


Section 14: Modifying the Navigation Menus

Figure 14-5: The Items method

Figure 14-6: The GetItems Method

Page 14-10 Open Text Corporation


Section 14: Modifying the Navigation Menus

14.4 The LivelinkNavigationCallbackSubsystem

14.4.1 The Items Method

1. The method first tests to see if fItems is defined. So Take a look at the
it’s really true that the navigation menus are cached, .ForceSetup() method.
as fItems is the cache.

So if fItems is undefined (there are no cached menus)


then call GetItems().

14.4.2 The GetItems Method

2. If keys is undefined (which it always is when


GetItems is called by items), GetItems returns the
previously constructed fRegistry, which is a list of
the LivelinkNavigationCallback objects.

How did the LivelinkNavigationCallback objects get


registered with fRegistry? It doesn’t really matter for the
moment, as long as you realise that you can register your
own LivelinkNavigationCallback object. You will do this
shortly.

3. Back in items, it runs the execute method of each of


the LivelinkNavigationCallback objects (the for
loop). After this is complete it builds the menus and
their sections and returns them to GlobalMenu.html,
where they are displayed in the GUI.

Now turn your attention to the LivelinkNavigationCallback


objects and their execute methods. You can inspect
fRegistry to find these easily.

Livelink Builder Fundamentals Course Page 14-11


Section 14: Modifying the Navigation Menus

Figure 14-7: Execute method of Home LivelinkNavigationCallback

Figure 14-8 Comments of the Items method

Page 14-12 Open Text Corporation


Section 14: Modifying the Navigation Menus

14.5 The Execute Method of Home LivelinkNavigationCallback

The method first declares item_1 as an assoc and pre-


populates it with ._NewItem(). (Is this starting to sound
familiar? If not, review Section 8 of the Builder
Fundamentals course.)

It next sets two elements to the URL and name of this menu
item.

It then sets the items assoc to contain the item_1 assoc, but
notice where inside items it is stored.

item_1.func_url = "?func=personal.settings"
item_1.name = [Home_Label.Settings]
items.( '12' + .NextToolsSection() + Str.ValueToString( 40 ) + ".0" ) = item_1

Reading the comments at the top of the items method you


can learn how the “key” into the items assoc is generated.

The key is of the format xxyzz.0 where:

xx is a 2 integer (character representation) key indicating to


which navigation menu this item belongs. The
following are reserved for system use:
09. Project
10. Personal
11. Enterprise
12. Tools

y is a single integer (character representation) indicating to


which section of the specific menu this item
belongs:
1. first section, 2. second section, etc.

zz is any number of integers (character representation)


Recall from the Builder
indicating the order of the menu item in the section. course that Open Text will
starts at 10, increments of 10 not support the use of integer
keys by you for the navigation
As you work your way through the entries in fRegistry you menus. Open Text will
support only the use of
can make a note of all the keys already used. Once you do alphabetic keys.
this you can see which integers have not been used.

Livelink Builder Fundamentals Course Page 14-13


Section 14: Modifying the Navigation Menus

Figure 14-9: fRegistry

Figure 14-10: Searching for callbacks

Page 14-14 Open Text Corporation


Section 14: Modifying the Navigation Menus

14.6 A New Orphan

Inspecting fRegistry. Home LivelinkNavigationCallback.


OSParent.OSParent shows the grandparent of this object. In
fact if you inspect all the objects in fRegistry you will see
that they all share the same grandparent.

How do you find grandpa? Searching all OSpaces for the


object will do it. Notice that you will find a few of them.
Which one is the real grandpa of yours?

Here is where those hexadecimal pointers really come in


handy. Notice that the search found only one that has the
same hex number as the one in fRegistry and it lives in
WEBLL.

Double-clicking the item in question in the search results


will open a new OSpace browser.

Livelink Builder Fundamentals Course Page 14-15


Section 14: Modifying the Navigation Menus

Figure 14-11: GRANDPA

Figure 14-12: The __Init method

Page 14-16 Open Text Corporation


Section 14: Modifying the Navigation Menus

14.7 WEBLL and LivelinkNavigationCallback

You have found the grandparent of all your registered


callbacks. Now you need to see how they are registered so
you can register your own.

Remember all the times you set fEnabled = true and ran
BuildOSpace? When did you have to do it? Only when
your object had an __Init method.

You can see now what is happening in the __Init:

1) A new temporary object is being created.

2) RegisterItem() is being called in


$WebLL.LivelinkNavigationCallbackSubsystem which
will put this object’s name and pointer into fRegistry.

It seems clear then that this is the object you should orphan
in your OSpace if you want to add items to the navigation
menus. That is, the object gets registered by the __Init
method when you run BuildOSpace. The Execute method
is run when the navigation menus are built by the
Subsystem items method.

Livelink Builder Fundamentals Course Page 14-17


Section 14: Modifying the Navigation Menus

Figure 14-13: The Documentation feature

Figure 14-14: The Execute method

Page 14-18 Open Text Corporation


Section 14: Modifying the Navigation Menus

14.8 Your Orphan

The Execute method calls _NewItem (as you did in the


Builder class), but a closer inspection shows that _NewItem
creates an assoc with an element called url and
func_url. Read the Documentation feature.

So now you can modify your orphan’s Execute method to


create your own navigation menu entries.

14.9 A Final Word on Navigation Menu Items – Removing Them

As Open Text does not formally support this operation, this


document will not investigate this any further than to list
the following steps.

To remove an existing entry from a navigation menu


requires the following:

1) Identify the LivelinkNavigationCallback object that


contains the item to be removed.

2) Orphan that object in your OSpace.

3) Override the execute method to comment out the


item(s) to be removed.

4) Check that fEnabled is TRUE.


As with adding items into
5) Run BuildOSpace to register the object. the menus with integer keys,
Open Text will not support the
deletion of existing items from
the navigation menus.

Livelink Builder Fundamentals Course Page 14-19


Section 14: Modifying the Navigation Menus

14.10 Summary

• To find the appropriate place to modify Livelink code,


you viewed an HTML page to find the name of the
Weblingo file that was called.

• By tracing through the Weblingo file, called webscripts


can be found and then also traced.

• Orphaning the appropriate objects can allow you to


modify the behavior of the navigation menus.

Page 14-20 Open Text Corporation


Section 14: Modifying the Navigation Menus

14.11 Section 14 exercises

Select one of the following exercises. If you have time, do the other.

Exercise 1 [Approximate time: 1 hour]

Using the techniques presented in class discover how the Administration pages are
constructed and create a new Suggestion (or Contacts) Administration section as is shown
below:

The Get Suggestions (Get Contacts) link should work, the Clear Suggestions (Clear
Contacts) can point to your favourite web site.

Extra credit:

Experiment with the placement of your section on the Administration page. Can you put it at
the top of the Administration page? At the bottom?

Exercise 2 [Approximate time: 1 hour]

Modify the Enterprise Workspace pages to add a new column entitled Owner. Then for each
Livelink item in the list view, display the name of the item’s owner in that new column. Do
not sort this column.

Extra credit:

Allow the user to click on the owner’s name and see the information page of that user.

Livelink Builder Fundamentals Course Page 14-21


Section 14: Modifying the Navigation Menus

14.12 Section 14 Exercise Solutions

14.12.1 Exercise 1

1) Use the exact same methodology that was just presented.

14.12.2 Exercise 2

1) Navigate through Livelink to the Enterprise Workspace.

2) View the source of this page and search for the name of a Livelink object on the page.
Scroll up and note the HTML comment <!-- File: webnode/browseview.html -->

3) In the Builder, open the file browseview.html and review the code to see how it sets up
the table with column headings and then displays one row for each Livelink item. Set a
break-on-entry.

4) Return to the web browser, then reload the page.

5) Return to the Builder to the debugger and step through the code noticing how the
contents variable is set and then used in the for loop. Notice that the information you
wish to display is contained in this variable

6) Stop the debugger and make a copy of the browseview.html file before modifying it.

7) Find the code that creates the column headings for the list area of the display and add a
new column with the appropriate name.

8) Find the code in the for loop that creates the row entry for each Livelink item and add a
new column with the appropriate information.

14.12.3 Extra Credit Solution

1) Go to any page that allows you to click on a user’s name, for example, the general page
of a document.

2) View the source and note the comment at the top of the file <!-- File:
webnode/infoproperties.html -->

3) Scroll down to the section marked <!-- Created By / Owner --> and review the code.
Notice the ;;call statements to <htmlPrefix + 'douserdialog.html'>

4) Back in the webnode/browseview.html file, include this ;;call.

Page 14-22 Open Text Corporation


Section 14: Modifying the Navigation Menus

Some points to ponder:

• How does webnode/infoproperties.html set the htmlPrefix variable?

• What is passed into usersPkg.UserDisplayNameGet( .fPrgCtx, data.Owner) and what


gets passed back?

Livelink Builder Fundamentals Course Page 14-23


Section 14: Modifying the Navigation Menus

Notes:

Page 14-24 Open Text Corporation


Appendix A: Internationalization
Overview:

At the time of writing, Open Text provides Livelink in US English, French, and German.
This optional section is devoted to explaining how the off-the-shelf Livelink interface is
translated, as well as how to translate your customizations of Livelink. We investigate the
tools available for translation and the methods for using those tools.

Objectives:

By the end of this appendix, you will be able to use XLates to prepare your module for
translation into another language.

Livelink Builder Fundamentals Course 92-300 04Feb11 Page A-1


Appendix A: Internationalization

Figure A-1: The same page from the German and US English versions of Livelink (Livelink
8.1.5 example)

Page A-2 Open Text Corporation


Appendix A: Internationalization

A.1 Internationalization Q & A

A.1.1 What is internationalization? What is localization?

The translation of a software program is just what you might think: the conversion of its
words, phrases, and sentences in one language to the words, phrases and sentences of another
language. Internationalization is the process of preparing code for translation/localization.
Internationalization is performed only once, whereas localization is performed for every
locale.

Localization includes translation from one language to another, but also includes the
conversion of date formats, monetary units, measurement units and any other changes that
are necessary to conform to the standards of a given locale. Livelink’s off-the-shelf OSpaces
have been internationalized, and Livelink is currently being localized into German and
French, with other languages on the way. Livelink also provides commands and other
functionality for internationalizing your own OSpace objects.

As a Builder user, what do I absolutely need to know about internationalization and


localization?

You need to know that it’s there and generally how it works, because it’s an integral part of
the code that you are enhancing and modifying.

Even if you do not need to translate Livelink to another language, you can still make good
use of the internationalization functionality if your task is to change the overall nomenclature
in the Livelink interface to the lexicon of your organization — this is another form of
localization.

My Livelink system will be used by people speaking <language here>. What languages
are available for Livelink?

Livelink 8 has been translated to German, French, and Japanese, and Livelink 9 is in the
process of being translated into these languages.

Can I translate my custom code into one of the languages that Livelink supports?

Yes. This section explains the details. You will also find helpful information in the chapter
concerning Internationalization in the Livelink Builder Developer’s Guide.

Can I translate Livelink into another language?

Not without help from Open Text. In order to create a Livelink version in another language,
you must acquire special code. If you have a strong need to have Livelink translated to
another language, please contact your Open Text account manager, who can start the ball
rolling for you.

Livelink Builder Fundamentals Course Page A-3


Appendix A: Internationalization

Translated

Figure A-2: Example of a dialog box containing a translated message and buttons

Translated

Figure A-3: Example of a page of the Livelink interface containing translated prompts

Figure A-4: The webwork module directory for a US English installation, showing two
OSpaces and their corresponding XDBs

Page A-4 Open Text Corporation


Appendix A: Internationalization

A.2 Translating the Code — the Big Picture

What can I translate?

Livelink provides several tools for facilitating the translation of its interface into other
languages.

You can translate:


• user messages in scripts
• user messages in string features
• prompts and other text on HTML pages

How does Livelink manage to use one set of OSpaces for all of the languages to which
it's translated?

Each OSpace has an XDB File for each language into which it is translated. For example, for
the Projects OSpace, “project.oll”, there is a corresponding XDB file for each language,
called “projectUSA.xdb”, “projectFRN.xdb”, etc. (The format of the file name is important
— see A.3.)

What’s an XDB file?

XDB stands for “Xlate DataBase” OSpace. An XDB file stores the information required to
translate each string of user text in its OSpace and corresponding HTML files. For each
string, the XDB stores:
• a key identifying the string. This is a component of what you actually see in the script or
HTML file (see Figure A-6).
• the actual text to display, in the correct language
• a comment about the intention of the user text, for the benefit of the translators

This set of information forms an Xlate. The Xlates are organized into groups for easier
management, and the groups in an XDB are given names that become part of the Xlate’s key.

To display the XDB files that are part of your Livelink installation in the Builder, choose
Show XDBs from the Browser menu.

Livelink Builder Fundamentals Course Page A-5


Appendix A: Internationalization

Figure A-5: Portion of the Add New User page

<TR>
<TD NOWRAP COLSPAN="2" BGCOLOR="#CCCCCC">
<FONT SIZE="2" FACE="`[WebDsp_Font.SansSerif]`">&nbsp;
`[WebUser_HTMLLabel.EnterPassword_]`</FONT></TD>
<TD NOWRAP COLSPAN="2"><INPUT TYPE="PASSWORD" NAME="password"
MAXLENGTH="64"></TD>
</TR> XDB Xlate group Xlate key

<TR>
<TD NOWRAP COLSPAN="2" BGCOLOR="#CCCCCC" NOAP>
<FONT SIZE="2" FACE="`[WebDsp_Font.SansSerif]`">&nbsp;
`[WebUser_HTMLLabel.VerifyPassword_]`</FONT></TD>
<TD NOWRAP COLSPAN="2"><INPUT TYPE="PASSWORD" NAME="verify_pw"
MAXLENGTH="64"></TD>
</TR>

Figure A-6: Portion of the HTML file which generates the Add New User page, with Xlates
highlighted

Page A-6 Open Text Corporation


Appendix A: Internationalization

A.2.2 Show me how Livelink does this off the shelf.

For each page of the Livelink interface, the corresponding HTML file contains not only the
OScript for dynamically generating portions of the page, but also the Xlate keys. XLate keys
are also found in object methods and other features of objects which contribute to the text of
the interface.

When the Open Text developers created the Livelink interface, they first created it in
English. They then used Builder tools to locate all of the strings in the HTML files, scripts,
and features and replace them with Xlates. They even replaced the HTML code for
indicating the fonts and styles to use, because they might need to be changed when
translating (especially into a character set like Kanji).

X?
The letter “x” is an accepted shorthand notation for many things:
• an unknown quantity, for example, x = 2 πr.
• the Greek letter ‘Χ’ (Chi), for example, when it is used as a prefix for Xmas.
• the prefix “trans”, as in Xmitter, Xport, and Xaction — hence Xlate.

Livelink Builder Fundamentals Course Page A-7


Appendix A: Internationalization

Figure A-7: XDB opened in a Builder Object Browser window

Page A-8 Open Text Corporation


Appendix A: Internationalization

A.2.3 Hey, this XDB looks like an OSpace!

Yes it does. Each Xlate group is represented by an object. The Xlate’s “key” is the name of
the feature of an object. The actual translated string is the content of the feature.

You should never attempt to modify Xlate “objects” and “features” through the Browser.
Always use the Edit Xlate window (see Section A.5).

Livelink Builder Fundamentals Course Page A-9


Appendix A: Internationalization

Figure A-8: Dialog box for creating an XDB file

Page A-10 Open Text Corporation


Appendix A: Internationalization

A.3 So how do I do all of this for the user text in my


customizations?

To simplify the process: For the modules you create, you use the Internationalization
Window in the Builder to create XDBs and replace all of your user text with Xlates. Export
each XDB to a text file, give the text file to a translator to translate (or do it yourself), then
import the XDB text file containing the translated Xlates to a new XDB using the Livelink
server for that language. Et voilà!

Step set A.1: Make an XDB

You need to create an XDB file for each OSpace you are translating. To create an XDB file:

1. Choose Internationalization from the Tools menu.


This opens the Internationalization window, which is the principal tool for translating
code.

2. Choose New XDB from the Internationalization menu.


Livelink opens a dialog box for specifying the name and location of the XDB file. Place
the XDB in the same directory as the OSpace which you are translating. There is a
required naming convention for XDBs:
OSpaceNameLanguageCode.xdb

for example, webworkUSA.xdb or webworkGER.xdb

This requirement allows XDBs to be opened automatically.

(Of course, if you replace all your user strings with Xlates, you’ll need to create an XDB for
the language you used to create the interface, in addition to XDBs for the languages to which
you want to translate your code.)

Step set A.2: Verify that your OSpaces are unlocked.

You will be replacing portions of your scripts and other code — so the OSpaces you are
changing must be unlocked.

Livelink Builder Fundamentals Course Page A-11


Appendix A: Internationalization

Figure A-9: The Internationalization window

Figure A-10: XDB Search window

Figure A-11: New Xlate window

Page A-12 Open Text Corporation


Appendix A: Internationalization
Step set A.3: Create Xlates for all of your “user strings”.

3. From the Internationalization window, choose the “Quoted Strings” radio button, select
an area in which to search from the in dropdown list, and click the Search button.
Livelink lists all of the strings found in the selected area in the lower half of the
Internationalization window. (See A.3.2 for important information concerning
“concatenated strings” vs. “quoted strings”.)

4. Double-click a row in the Internationalization window.


The appropriate editor is opened.

5. If the string is part of a script, choose Xlate Selection from the Script menu. If the string
is stored in a feature, choose Xlate All from the Text menu.
The XDB Search window opens and automatically searches for an existing Xlate for the
string. Any matching Xlates are listed in the lower half of the XDB Search window. If
one or more Xlates are found, you should strongly consider using one of the existing
Xlates. This will make the text in your interface more consistent. Be careful, however, to
consider how the Xlate might be changed over time for the strings it is currently
translating — for example, a string in the “Project_HTMLLabel” group might look nice
for your module today, but it might be changed to something too specific to Projects in
the future.
After you make your decision, here are your options:
• Select a row and click the Replace button to replace the string with the existing
Xlate.
The string is replaced by the “key” for the Xlate, in the format
[OSpace_Group.Xlate].
• Click the New button to create a new Xlate. (See Step 4.)
• Click the Cancel button to cancel the process.

6. If there are no matches, or if you click the New button in the XDB Search window, the
New Xlate window opens.
(a) Select the XDB to which you want to add the Xlate from the XDB dropdown list.
(b) Select the Group in which you want to place the Xlate from the Group dropdown list.
(Or use the New Group button to create a new group if you like.)
The XDBs that ship with Livelink have a practical set of groups, centered around the
logic, functionality, and grammar of the interface. Some of the more common groups
include “ErrMsg” for error messages, “HTMLLabel” for HTML labels, and
“message” for Messages.
(c) Type a key for the Xlate in the Key field. Type or paste the string in its current
language into the Translation field. Enter notes about the purpose of the string in the
Intention field. (See A.3.3 for more information.) Then click the Replace button.
The new Xlate is added to the XDB, and the original string is replaced by the “key”
for the Xlate, in the format [OSpace_Group.Xlate].

Livelink Builder Fundamentals Course Page A-13


Appendix A: Internationalization

L’élément “Q1 Report” ne pouvait pas être ajouté au fichier “Reports”.

The item “Q1 Report” could not be added to the “Reports” Folder.

Das Objekt “Q1 Report” konnte nicht in das Verzeichnis “Reports” eingefugt werden.

Figure A-12: Examples of different sentence structures in different languages

Page A-14 Open Text Corporation


Appendix A: Internationalization

A.3.2 Important: Convert your “Concatenated strings” to


“Quoted strings”.

The Internationalization window and the Script Editor both provide tools for allowing you to
convert code like this:
"The item " + itemName + "could not be added to the" + folderName + " Folder."

to code like this:


Str.Format( "The item %1 could not be added to the %2 Folder.", \
itemName, folderName )

The latter is much more “translatable” into other languages, where the order of the subjects,
objects, etc. may be different. (See Figure A-12.) To assist with this process, the
Internationalization Window allows you to search for Concatenated strings by clicking the
corresponding radio button, selecting the area to search, then clicking the Search button.
You can double-click rows listed in the Internationalization window and convert them to the
better format. You can then select the converted string and make it into an Xlate.

You can also use the Find Next Concatenated String command in the Script Editor’s Script
menu to find concatenated strings when working on a particular script.

For more information about the Str.Format function, see the OScript Language reference
documentation for the Str package.

A.3.3 Important: Having Good Intentions

If you give the string “%1 was %2 for %3” to someone to translate, how are they going to
know what %1, %2, and %3 stand for? You’re going to write some good notes in the
Intentions field for the XLate, that’s how.

For example: If the string for which you’re creating an Xlate is:
The item %1 was stored in the %2 Folder

Your Intention field for the XLate should say something like:
Status message notifying user of successful storage of item.
%1 – item name
%2 – folder name

Livelink Builder Fundamentals Course Page A-15


Appendix A: Internationalization

Figure A-13: The dialog box for selecting an XDB to export

Group Key Translation Intention


Kernel_Misc CouldNotSatisfy1SDepend "Could not satisfy '%1's "Could not satisfy '%1's
encyOn2 dependency on '%2'." dependency on '%2'."
Kernel_Misc CouldNotWriteToPrefsFile1 "Could not write to prefs "Could not write to prefs
file: %1" file: %1"
Kernel_Misc InvalidItemSpecified "Invalid item specified." "Invalid item specified."
Figure A-14: Portion of an exported XDB text file (formatted)

Page A-16 Open Text Corporation


Appendix A: Internationalization

Step set A.4: Export the current language XDB to a text file.

1. From the Internationalization window, choose Export DB from the Internationalization


menu.
A dialog box lists all of the currently active XDBs.

2. Select an XDB, click OK, then specify a target directory for the text file.
The exported text file is in the form of a tab-delimited text file with four fields: Group,
Key, Translation, and Intention.

3. Give the text file to your translators, and tell them to modify only the Translation field for
each row of the file.
The only field that needs to be translated is the Translation field, as this is the only text
that the users will see. In fact the first 2 fields must not be altered, or the new language
Xlate will not be found. (You may want to import the TXT file into a spreadsheet
program and “write lock” the first two fields.)

Step set A.5: Import the text file as a new XDB.

4. Create a new XDB for the XDB text file you want to import.
Remember the naming requirement: OSpaceNameCode.XDB

5. Stop the Livelink server in the current language and start the Livelink server in the
language to which you are translating.
Livelink has a separate set of server code for each language, so if you want to run
Livelink in German, you need to have the German installation of Livelink. (If you have a
multi-national organization and would like to have, for example, both English and French
versions of Livelink, you can “point” both installations to the same database, so that there
is one repository of data with two interfaces.)
If you wrote your custom interface in English using an English installation of Livelink,
and you created an XDB for German, you would stop the English installation of Livelink
and start the German installation of Livelink.

6. From the Builder, import a translated XDB text file into its corresponding XDB file by
choosing the Import XDB command from the Internationalization menu of the
Internationalization window.
The Import XDB dialog box displays, listing all of the XDBs into which you can import
an exported XDB file.

7. Select the XDB into which you want to import, then click OK.
The Import XDB file selection dialog box opens, prompting you for the name and
location of the exported XDB file.

8. Locate the file you wish to import, then click OK.


A progress indicator displays as the XDB is imported.

Livelink Builder Fundamentals Course Page A-17


Appendix A: Internationalization

Figure A-15: The XDB Search window, locating all occurences of a string

Figure A-16: Edit Xlate Window

Page A-18 Open Text Corporation


Appendix A: Internationalization

A.4 How do I translate Livelink’s off-the-shelf interface into another


language?

The Open Text developers have already replaced all the user text with Xlates. However, there
are still steps to setting up a new language version of Livelink at the “source” level that
requires the use of a localization “toolkit”. The toolkit is designed for translation houses who
are planning to do a significant project, not for minor translations. If you want to translate
Livelink into another language, contact your Open Text account representative, who can
make the proper contacts for initiating this kind of project.

A.5 I just want to change the wording a bit. Can I do that with
Xlates?

Absolutely. “Translating” can mean translating from Livelink’s more generic terminology to
the specific terminology used in your organization. You can use the XDB Search window to
assist with this kind of work.

9. Choose XDB Search from the Tools menu.


The XDB Search window opens.

10. Enter the string you wish to search for in the Find field. If you want the search to be case
sensitive, or if you want the Xlate’s Translation field to exactly match the string, click the
appropriate checkboxes. Then click the Search button.
The search results are displayed in the table at the bottom of the window. Note that unless
you check the “exact match” checkbox, Livelink tries to assist you by including Xlates
that are a close approximation of the string you entered.

11. Decide which, if any, of the Xlates you want to change. For each Xlate you want to edit,
double-click the row to open it in the Edit Xlate window.
You can modify only the Translation and Intention fields in this window. Pay careful
attention to the Intention field’s contents — it can provide valuable information about the
purpose of the translation, especially as regards any parameters. Close the window to
save your changes.

The Script Editor has a number of useful commands for internationalizing scripts, including Find next
Quoted String, Find next HTML String, Find next Concatenated String, and more. Read about these
commands in the Livelink Builder Developer’s Guide.

Livelink Builder Fundamentals Course Page A-19


Appendix A: Internationalization
———————- snip —————————
<HTML>
<HEAD>
<TITLE>`[WebUser_HTMLLabel.LivelinkCreateUser]`</TITLE>
</HEAD>

———————- snip —————————


<TR>
<TD NOWRAP COLSPAN="2" BGCOLOR="#CCCCCC"><FONT SIZE="2"
FACE="`[WebDsp_Font.SansSerif]`">&nbsp;`[WebUser_HTMLLabel.EnterPassword_]`
</FONT></TD>
<TD NOWRAP COLSPAN="2"><INPUT TYPE="PASSWORD" NAME="password"
MAXLENGTH="64"></TD>
</TR>

<TR>
<TD NOWRAP COLSPAN="2" BGCOLOR="#CCCCCC" NOAP> <FONT SIZE="2"
FACE="`[WebDsp_Font.SansSerif]`">&nbsp;`[WebUser_HTMLLabel.VerifyPassword_]`
</FONT></TD>
<TD NOWRAP COLSPAN="2"><INPUT TYPE="PASSWORD" NAME="verify_pw"
MAXLENGTH="64"></TD>
</TR>

———————- snip —————————

Figure A-17: Portion of the newuser.html file

———————- snip —————————


<HTML>
<HEAD>
<TITLE>Livelink Create User</TITLE>
</HEAD>

———————- snip —————————


<TR>
<TD NOWRAP COLSPAN="2" BGCOLOR="#CCCCCC"><FONT SIZE="2"
FACE="Arial,Helvetica,sans-serif">&nbsp;Password:</FONT></TD>
<TD NOWRAP COLSPAN="2"><INPUT TYPE="PASSWORD" NAME="password"
MAXLENGTH="64"></TD>
</TR>

<TR>
<TD NOWRAP COLSPAN="2" BGCOLOR="#CCCCCC" NOAP><FONT SIZE="2"
FACE="Arial,Helvetica,sans-serif">&nbsp;Verify Password:</FONT></TD>
<TD NOWRAP COLSPAN="2"><INPUT TYPE="PASSWORD" NAME="verify_pw"
MAXLENGTH="64"></TD>
</TR>

Figure A-18: Same newuser.html file portion, but “localized” to US English

Page A-20 Open Text Corporation


Appendix A: Internationalization

A.6 This is all very nice, but I’m not doing any translating, and I’m
tired of looking at Xlates while doing Builder development. Can
I get rid of them?

You cannot easily eliminate all of the Xlates, but it’s fairly simple to create a “localized”
version of an HTML file that you’re working on:

1. Open the HTML file you want to “localize” in the Script Editor.

2. Choose Save Localized File from the Script menu.


A file download dialog box defaults the filename to the language code for the installation,
followed by an underscore and then followed by the filename, for example,
“USA_newuser.html”. After you save the file, Livelink immediately opens it in the Script
Editor. All of the Xlates are replaced with the Xlates’ translations.

Livelink Builder Fundamentals Course Page A-21


Appendix A: Internationalization

A.7 Summary

Livelink’s internationalization functionality makes it simple to use the same Livelink code
for different language versions of Livelink.

You can use the Internationalization technology to translate your custom code into another of
the languages supported by Livelink (which at the time of this writing include US English,
French, and German). You can also use this technology to edit the interface text to match
your organization’s lexicon.

Xlates are language-neutral tags in Livelink scripts, webscripts, and features that are
converted to a particular language at runtime. XDBs are collections of Xlates with their
corresponding translated text. Xlates within an XDB are organized into groups.

To translate new code into another language, you: Create an XDB for each OSpace; replace
all user strings in the code with Xlates; export the XDB to a text file for translation; and
import the text file as a new XDB.

If you want to translate the Livelink off-the-shelf code into another language, you need to
work with Open Text developers to create a new Livelink server language version.

The Internationalization window and the XDB Search window are the two primary tools for
converting user strings to Xlates. The Internationalization window lists strings to be “Xlated”
and provides the interface for creating XDBs and groups within XDBs. The XDB Search
window searches existing XDBs for Xlates containing text you intend to translate.

Remember to refer to the Livelink Builder Developer’s Guide for more information about the
Internationalization tools.

Page A-22 Open Text Corporation


Appendix B: Creating Online Help for Your Module
Overview:

Many organizations, once they have created a new module for Livelink, wish to assist users
in using their new Livelink functionality by adding their own help information to Livelink’s
existing help system. This is a trivial and relatively non time-consuming task in Livelink.
You will need to have a basic knowledge of designing HTML pages (or find someone who
can help you design them) and, of course, the Builder if you are taking on the task of adding
help for your custom Livelink modules.

Objectives:

By the end of this appendix, you will know how to create custom help for your module. In
the process, you will learn how to:

• Structure the help files

• Inform the module about the help files, so that they are installed when the module is
installed

• Make the module’s help context sensitive

Livelink Builder Fundamentals Course 92-300 04Feb11 Page B-1


Appendix B: Creating Online Help for Your Module

Figure B-1: Example Help page

Page B-2 Open Text Corporation


Appendix B: Creating Online Help for Your Module

B.1 The GUI for Livelink’s Help

Livelink’s Help page is a frameset, with a menu frame on


the left whose items display their contents (the
corresponding help HTML file) in a frame on the right.

Topics and subtopics can be nested to any depth (but three


is the maximum practical depth).

The help for a module can be context-sensitive, so that


choosing For This Page from the Help menu on a
particular page displays help related to that page.

Livelink Builder Fundamentals Course Page B-3


Appendix B: Creating Online Help for Your Module

Discussions |d_main.html

Add a Discussion |d_add_disc.html

View a Discussion |d_view_disc.html

Topics

Post a Topic |d_post_top.html

Delete a Topic |d_del_top.html

Replies

Post a Reply |d_disc_rply.html

Mark Topics Read |d_mrk_top_rd.html

Figure B-2: Example help file from the Discussions module

Figure B-3: Help interface built from the file in Figure B-2

Page B-4 Open Text Corporation


Appendix B: Creating Online Help for Your Module

B.2 Help File Structure

B.2.1 The TOC.txt file

The TOC.txt file defines the menu items for the left frame
of the Help page and the links to files to display in the right
frame.

Nesting (using tabs) defines the hierarchy of the table of


contents for that help topic.

When creating the TOC.txt file for your module, place it in


the root directory of your module. Use the format
menuItemName |helpFileName to define each menu item.
Use tabs at the beginning of lines to define the hierarchy.
See Figure B-2 for an example and Figure B-3 for its
resulting help file.

Livelink Builder Fundamentals Course Page B-5


Appendix B: Creating Online Help for Your Module

<HTML>
<HEAD>
<TITLE>Reply to a Discussion Topic</TITLE>
</HEAD>

<BODY TEXT="#000000" BGCOLOR="#FFFFFF" BACKGROUND="../pattern.gif"


LINK="#003399">

<<<SNIP>>>

<p>While the project team coordinator(s), members, and guests can view all
discussion topics and replies, only individuals with the first two roles
can reply to a topic.

<p>To reply to a topic you are currently reading, follow the steps below.
To reply to a topic you have already read and closed, click the link for
the discussion containing the topic to which you want to reply. Then, to
access the complete list of topics on the Discussion page, select All.
From this list, click a topic and then follow the steps below.

<<<SNIP>>>
Link to another help file
<h3><a name="related">Related Topics:</a></h3>
in the same module
<ul>
<li><a href="d_main.html">Discussions</a>
<li><a href="d_mrk_top_rd.html">Mark Topics Read</a>
<li><a href="d_post_top.html">Post a Discussion Topic</a>
<li><a href="d_view_disc.html">View a Discussion</a>
</ul>
<p>To go to a different Livelink page, use the <a href="../go_to.html">Go
to menu</a> or the <a href="../go_to.html#frameset">Livelink Menubar</a>
at any time.
Link to a help file in the
<P>Detailed information is available about using Livelink's <ahelp directory
“core”
href="../using_help.html">online Help</a> and about how to <A
HREF="../navigate.html">navigate</a> through Livelink.
<!-- Footer -->
<P>
<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="0" WIDTH="100%">
<TR>
<TD NOWRAP ALIGN=LEFT VALIGN="MIDDLE" BGCOLOR="#CCCCCC">
<FONT SIZE="0" FACE="Arial, Helvetica, sans-serif"
COLOR="#666666">&nbsp;Livelink &reg; Version 8, Copyright &copy; 1995-1999
Open Text Inc. All rights reserved.</FONT></TD>
<TD NOWRAP ALIGN="RIGHT" BGCOLOR="#CCCCCC"><A HREF="#top"><IMG
SRC="../arrowup2.gif" ALT="Top" WIDTH="16" HEIGHT="16"
BORDER="0"></A></TD>
</TR>
</TABLE></BODY></HTML>

Figure B-4: Example help file

Page B-6 Open Text Corporation


Appendix B: Creating Online Help for Your Module

B.2.2 The Help Files

The most time consuming step in adding new help files to


Livelink is the creation of the HTML files containing the
help text. The help HTML files should be located in your
module’s help folder. (If there is no help folder in your
module, then you will need to create one.)

The standard naming convention used for the HTML files


is the initial(s) of your module, followed by an underscore,
followed by a descriptive name of the HTML file’s
contents, delimited by underscores. For example:
c_read_contact_file

You should create a separate file for each topic or subtopic


that is going to be in the help table of contents. If you are
unsure of where to start when it comes to the format of
your HTML files, you may wish to look at the source code
of some of Livelink’s own help files. (Almost every
Livelink module has its own set of help files.)

You can define relative links within the help HTML files to
link to other help HTML files:

Type of link Example


To create a link to help files in the same <a href="c_add_contact.html">Add a
module, just refer to the HTML file name. contact</a>

If you want to create links to help files in other <a href=


modules, use the convention "../webdoc/fn_del_an_item.html">
Delete a contact</a>
“../othermodulename/htmlhelpfile.html”.

If you want to create links to Livelink’s main <a href="../go_to.html">Go to


set of help files, use the convention menu</a>
“../htmlhelpfilename”.

Livelink Builder Fundamentals Course Page B-7


Appendix B: Creating Online Help for Your Module

{{'%3support%1','%4%5%1'},{'%3help%1','%4help%1%5%1'}}

Figure B-5: Example fFilesToCopy feature in a Module object

Figure B-6: Module object and its fFilesToCopy feature

Page B-8 Open Text Corporation


Appendix B: Creating Online Help for Your Module

B.3 Informing the Module about the Help files

During installation, the Configure request handler copies


files as specified in the Module object’s fFilesToCopy
feature. The help directory must be specified there. See
Figure B-5 for an example. Livelink uses this feature to
copy the help files of your module to the
LLHOME/support/help/MODULENAME folder. Read the
Module’s Documentation feature and trace the
Configure.DoFileInstall() method for more information.

Also during installation, the Configure request handler


looks for the TOC.txt file and will create help for its
contents, adding the module’s help to the cached
information for the other modules’ help. (Trace the
Configure.DoHelpInstall() method for more information.)
This causes your module’s help to be added to the bottom
of the Help menu’s main menu.

Step set B.1: Preparing the help for your module

If your module is already installed and you are adding help


later, you can:

1. Uninstall the module.

2. Create a TOC.txt file, following the guidelines in


Section B.2.1.

3. Create the help files, following the guidelines in


Section B.2.2.

4. Open the module’s OSpace manually from within the


Builder.

5. Edit the Module object’s fFilesToCopy feature to


include the help directory, as in Figure B-5. (It might be
easiest to delete the feature so that it reinherits from its
parent, then edit.)

6. Save your OSpace, exit and restart the Builder, and


reinstall your module.

7. To test, choose Contents from the Help menu and look


for your topic at the bottom of the menu.

Livelink Builder Fundamentals Course Page B-9


Appendix B: Creating Online Help for Your Module

[HelpMap]

mapping_6={'LL.Topic.view','d_view_disc.html'}

mapping_5={'LL.Topic.create','d_post_top.html'}

mapping_4={'LL.Reply.view','d_view_disc.html'}

mapping_3={'LL.Reply.create','d_disc_rply.html'}

mapping_2={'LL.Discussion.view','d_view_disc.html'}

mapping_1={'LL.Discussion.create','d_add_disc.html'}

Figure B-7: The [HELPMAP] section of the Discussion module’s INI file

{{'LL.Discussion.create','d_add_disc.html'},

{'LL.Discussion.view','d_view_disc.html'},

{'LL.Reply.create','d_disc_rply.html'},

{'LL.Reply.view','d_view_disc.html'},

{'LL.Topic.create','d_post_top.html'},

{'LL.Topic.view','d_view_disc.html'} Help key

Figure B-8: Example Module.fHelpMappings feature

When linking to Format/Example


If the help file should be linked to an action of LL.webnodeobjectname.action
the ll request handler LL.websuggestionbox.create

If the help file should be linked to a different funcprefix.requesthandlername


request handler suggestions.getsuggestions

Figure B-9: Help key formats

Page B-10 Open Text Corporation


Appendix B: Creating Online Help for Your Module

B.4 Making the Help Context-Sensitive

B.4.1 The INI file

The INI files for modules that have context-sensitive help


contain a [HELPMAP] section that maps help files to
request handlers or to ll request handler actions. See Figure
B-7 for an example.

This section of the INI file is generated automatically by


the Module object’s 0 DumpModuleConfigToFile() Read the
Documentation feature of
method—that is, if you’ve edited the fHelpMappings the WebHelp:Index object
feature of the Module object. You will want to create a for more information about
setup script to populate the fHelpMappings feature. Its the help key format.
format:
{ { helpkey1, helpfile1}, { helpkey2, helpfile2}, …}

See Figure B-8 for an example. The help key has a


required format, described in Figure B-9.)

Step set B.2: Making the help context-sensitive

If you have already installed your module and want to


make context-sensitive help, then you can:

1. Uninstall the module.

2. Open the OSpace manually, and edit the


fHelpMappings feature of your module’s Module
object. (You may find it easier to create and run a setup
script.)

3. Run your Module object’s


0DumpModuleConfigToFile() method to regenerate the
INI file, overwriting the existing INI file.

4. Save your OSpace, exit and restart the Builder, and


reinstall your module.

To test, go to a page that is triggered by one of the request


handlers or node actions specified in your fHelpMappings
feature, and choose For This Page from the Help menu to
see whether the proper help file opens.

Livelink Builder Fundamentals Course Page B-11


Appendix B: Creating Online Help for Your Module

B.5 Summary

• It’s quite simple to add online help for your module to


Livelink’s online help as part of the installation of your
module.

• Livelink’s online help is organized as a hierarchy of


topics and subtopics. An “expandable” table of
contents (TOC) is displayed in the left frame of the
help page, and clicking a link triggers the display of the
help content in the right frame of the page. You create a
TOC.txt file in your module’s root directory to define
the topics and subtopics and to link them to help files.

• The help files for your module are stored in a “help”


directory under your module’s root directory. The help
files can include links to other help topics.

• To trigger the proper copying of the help files during


installation, your module’s Module.fFilesToCopy
feature must include the sublist
{'%3help%1','%4help%1%5%1'}.

• You can make your help context-sensitive by editing


your module’s Module.fHelpMappings feature. This
feature is a list of lists which map request handler
names or ll request handler actions to particular help
files. The fHelpMappings feature is used to add a
[HelpMap] section to the module’s INI during
configuration.

Page B-12 Open Text Corporation


Appendix C: Pkg and Utils Object List
Overview

This appendix lists all of the OSpace objects whose names contain the string “Pkg” or “Util”,
since those strings are a naming convention for objects with handy, reusable features. If there
was a populated Documentation feature, this feature was included as well. We used a script
to get the raw content for this appendix – here is the script:

// Find all Utils and Pkg objects and if the documentation


// feature has been overridden then echo it.
//
// April 2002 - HPell - first written

Function void UtilsAndPkgs()

List ospaceObjects, allFeatures, info


Object root, obj
string feature, tmpString, outString
integer i

echo("============================================")
echo("A complete list of all Util and Pkg objects.")
echo("OSpace", str.tab(), str.tab(), "Object")

for root in OS.Roots()

// this consumes all the time - begin any optimisation here


ospaceObjects = $KERNEL.OSpaceUtils.GetDescendants(root, TRUE)

for obj in ospaceObjects


if (!OS.IsTemp(obj)) // don't count temp objects
if str.LocateI(obj.OSName,"util") or str.LocateI(obj.OSName, "pkg")
echo(Root.OSName[:-6], str.tab(), str.tab(), obj.OSName)
allFeatures = OS.FeatureQuery(obj)
for feature in allFeatures
info = OS.FeatureInfo(obj, feature)
if (IsDefined(info))
if info[6] == 1 || info[6] == 0
// is this feature overridden or new?
echo(str.tab(), feature)
if info[6] == 1 && str.cmpI(feature, "Documentation") == 0
// is this the documentation feature?
tmpString = str.String(obj.documentation)
i = str.locateI(tmpString, "#ifdef DOC")
outString = tmpString[i+14:-24]
echo(outString)
end
end
end
end
end
end
end
end
end

Livelink Builder Fundamentals Course 92-300-04Feb11 Page C-1


Appendix C: Pkg and Utils Object List

C.1 Format

The objects are listed in the format:

OSpace Name
Object Name
“Documentation” if a documentation feature has been overridden
The text in the documentation feature, if the Documentation feature has been overriden
Name of new or overridden feature

The objects are listed in the order in which they were exported from the OSpaces, which is
probably in the order that the OSpaces were opened.

C.2 List of Pkg and Utils Objects

Kernel Kernel
OSpaceUtils FileUtils
Timings MoveRecursive
TimingSub6 MoveOverlay
TimingSub5 Move
TimingSub4 GetTempDir
TimingSub3 FileListRecursive
TimingSub2 DirSeparator
TimingSub1 DeleteRecursive
TimingSub0 DeleteOverlay
Timing Delete
ListOpenOSpaces CreateTempDir
IsOSpace CopyRecursive
IsDescendant CopyOverlay
IsCircular Copy
InitObjects BaseName
ImportObject 0 Test MoveRecursive
GetRequired 0 Test DeleteRecursive
GetOrphans 0 Test CopyRecursive
GetOSpaceRoot
GetOSpaceObjectsWithFeature
GetOSpaceObjects
GetDescendantsWithFeature2
GetDescendantsWithFeature
GetDescendants
Fix Scripts
ExportObject
DescribeObjectInheritance
DependencySort
ChildrenByOSpace
ChildrenByInheritance
AlphaObjects
AllChildren

Page C-2 Open Text Corporation


Appendix C: Pkg and Utils Object List

Kernel Kernel
XlateUtils ResourceUtils
_XlateBuiltinsTest OpenResourceFile
XlateDBs
VerifyAll
Verify Kernel
UnlockXDB ModuleUtils
SetXlation Documentation
SetIntention Module Utils are the place to go to get
SearchDBs things done to a 'generic' module.
OpenXDB
NewXlation This objects contains scripts that can
NewXlateGroup determine if a module's requirements
NewXlateDB (installation pre-req's) are satisfied.
LockXDB
LocalizeString This object contains scripts that can 'file
LocalizeFile install' or file uninstall a module.\
IsXlation _SplitOffVersionNumber
IsXlateDB _OTHome
ImportHTMLString _ListOSpacesForModule
ImportHTMLFile _GetVersionFromPath
GetXlation _GetModulePathHelper
GetXlateGroup RegisterModuleToOSpaceMap
GetIntention OpenInstalledModuleOSpaces
GetDBName OSpacesFromFile
GetDBLanguage MoveBackToStaging
GetDBFromGroup ModuleIniPath
FindQuotedString MarkAsUninstalled
FindHTMLString MarkAsInstalled
FindConcatenatedString ListUpgradableModules
Filter ListUninstalledModules
ExportHTMLString ListUninstallableModules
ExportHTMLFile ListInstalledModules
DeleteXlation ListAlwaysInstalledModules
DeleteIntention IsUninstallable
GetNiceName
GetModuleToOSpaceMap
GetDependencies
FindStagingPath
FindModulePath
FindModuleOSpaces
DescriptionFromFile
DescribeUpgradableModules
DescribeUninstalledModules
DescribeUninstallableModules
DescribeInstalledModules
DependenciesSatisfiedWithout
DependenciesSatisfied
DependenciesFromFile
ClearOSpaceCache

Livelink Builder Fundamentals Course Page C-3


Appendix C: Pkg and Utils Object List

Kernel DBWizAPI
Utils ConnectPkg
fObsoleteAgents OpenLog
fController Disconnect
_Upgrade5040 Connect
StatsReset CloseLog
StatsReport Check
ScheduleUpdate
ScheduleGetByID
ScheduleGet DBWizAPI
ScheduleAdd ExecPkg
Log fTriggerProc
LoadConfigSchedule fStorageProc
Err fDisplayName
DBType UseAccount
ConfigUpdate UpdateUsers
ConfigLoad UpdateSchema
UpdateModule
UpdateLibrary
Kernel UpdateGrants
Utils ProcessScripts
fPathSep ModifyAccount
fController InitDapi
_Upgrade5040 GrantAccess
PathSep DropTriggers
ObtainNotificationStatus DropTables
MessagesTest CreateTriggers
MessagesReport CreateTables
MessagesPurgeByDate CreateAccount
MessagesMaxSeqNo BringUpToDate
MessagesGet
MessagesDeleteAll
Log
InterestsGetSpecific
InterestsGet
InterestsDeleteAll
InterestsDelete
InterestsAdd
GetScriptName
EventAdd
Err

Page C-4 Open Text Corporation


Appendix C: Pkg and Utils Object List

DBWizAPI
VerifyPkg

Documentation
VerifyPkg performs simple SQL queries against a
Livelink database to find any errors in the Livelink
schema or in the storage of Livelink information.

This documentation comes in two parts:


1) How To Install A New Verification Object
2) Description Of Features, Scripts, And Layout In VerifyPkg

****************************************
HOW TO INSTALL A NEW VERIFICATION OBJECT
****************************************
1) It is highly recommended that you read section 2 before
adding a verification object.
2) Write the SQL statement your verification will use to
check the database table(s).
3) Determine the group to which your new verification
will belong. This should be dictated by the .InitRec()
feature of each verification group. See the description
of .InitRec() in Section 2 for details
IF
there is no suitable group or errorRecArray for your
verification object:
a) Create a new child or orphan of VerifyPkg. The
name will correspond, in most cases, to the
database table being verified.
b) Over-ride the .InitRec() feature. Each field of the
recArray will, in most cases, correspond to a
column name from the table being verified.
c) Over-ride the .DBCols feature. This list contains
the string names of the columns of the table
being verified. Exercise care in this list: the
strings of .DBCols are used to create the SQL statement.
d) Over-ride the .fTableName feature. This string
is the table name used in the construction of the
SQL statement.

4) Create a new child of your chosen group. The naming


convention is as follows: "Ver" + ( the_thing_being_verified )
Examples: VerACLCount, VerParentIDs, VerChildCount
5) Over-ride the .fWhereClause feature. This string is
where clause of the SQL statement you constructed in
step 1). This where clause includes any sub-queries
necessary (correlated or uncorrelated).
6) Over-ride the .fErrorMsg. This string will be displayed
to the end user with any problems found by the verification.
7) Over-ride the .fGUIText. This string will be displayed
to the end user as a description of the verification to
be performed (on a menu of options, or whatever)
8) Over-ride the .fEnabled feature to register

Livelink Builder Fundamentals Course Page C-5


Appendix C: Pkg and Utils Object List

the object with the VerifySubsystem.


9) Over-ride the .fDisplayable feature if you do not wish the
new verification to be presented to the user as an option.
10) Add an object reference in the Verification Group pointing to the
new child.
11) If you wish to add your new verification to the list of existing
suites, change the .GenerateSuiteList feature of the
$WebAdmin.DbVerifySuites request handler to include the new
verification.

NOTE: Certain atypical verifications will not be able to follow


these instructions. Such complex, multi-part verifications
as External Document Storage verifications (which require
multiple SQL statements and recursion) must over-ride
the .Execute feature at the verification object level,
and completely disregard the standard format.

*********************************************************
DESCRIPTION OF FEATURES, SCRIPTS, AND LAYOUT IN VERIFYPKG
*********************************************************
It consists of a family of groups, each of which contains
verification objects capable of performing independent
verifications, and each of which returns a recArray of error
information. The general layout is as follows:

DBWizAPI
|
VerifyPkg
| |
VerGroup VerGroup
| |
VerObject(s) VerObject(s)

Components of a verification object:

I) Features defined or consistently over-ridden at the VerifyPkg level


SCRIPTS:
1) .Execute
This feature is common to all verification objects
and in general is not to be over-ridden.
2) .GetGUIText( verifyObj )
Retrieves the description of the procedure for
options display. Not to be over-ridden
3) .SetupCursor
Generic cursor housekeeping, not to be over-ridden.
VALUES:
None
II) Features defined or consistently over-ridden at the Verification Group level
SCRIPTS:
1) .InitRec()
Initializes the recArray to be used by each
verification object in the group for recording
and reporting errors found in the database. In
most cases, new verifications will fall into
an existing group and can make use of the inherited
recArray. If no existing recArray suffices to

Page C-6 Open Text Corporation


Appendix C: Pkg and Utils Object List

describe a new verfication object's task, a new


group will have to be defined (as a child or orphan
of VerifyPkg). Note that the recArray defined by
.InitRec() is a fundamental characteristic of a
Verification Group.
VALUES:
1) .fTableName
Contains the string name of the database table being
queried/verified.
2) .DBCols
Contains the database columns needed to verify the
table named in .fTableName and to report errors found.
Note that each column corresponds to a field in .InitRec()

III)Features defined or over-ridden at the verification object level


SCRIPTS:
1) Documentation
VALUES:
1) .fEnabled
A boolean flag indicating whether the object is a fully
functional verification object. This is false at the
Verification Group and VerifyPkg levels. When set to "TRUE"
the __Init feature of VerifyPkg will register the object
as a verification object.
2) .fGUIText
Contains the text to be displayed by the GUI, describing the
function of the verification. Note that when a new verification
object is added to VerifyPkg and it's .fEnabled flag is set
to "TRUE", the current GUI will attempt to add the verification
as an option to front-end. If .fGUIText remains unfilled,
an undescribed checkbox will appear.
3) .fDisplayable
A boolean flag indicating whether the object is a verification
intended for GUI display (and thus containing an associated
.GUIText) or is simply a "utility" class of verification objects.
If the verification is a fully functional object but is
used exclusively as a tool by other verification objects (and
should not be presented as an independent verification option
to the end user), this flag should be over-ridden to "FALSE".
The default is "TRUE".
4) .fWhereClause
Contains the where clause of the select statement performed
by the verification object. When combined with the .fTableName
and .DBCols features, a complete SQL statement is formed for
execution in the .Execute feature.
5) .fErrorMsg
The text of the error message describing the problems detected
by the verification object.

The following are the current groups and their recArray descriptions as defined
in the .InitRec() features.

GROUP NAME: BlobData


DEFINITION: RecArray.Create( {\\
'LongID',\\

Livelink Builder Fundamentals Course Page C-7


Appendix C: Pkg and Utils Object List

'OwnerID',\\
'SegmentID' } )

GROUP NAME: DTree


DEFINITION: RecArray.Create( {\\
'Name',\\
'OwnerID',\\
'ParentID',\\
'DataID',\\
'ChildCount',\\
'DataType',\\
'SubType',\\
'ACLCount' } )

GROUP NAME: DVersData


DEFINITION: RecArray.Create( {\\
'VersionID',\\
'DocID',\\
'Owner',\\
'VerCDate',\\
'VerMDate',\\
'Platform',\\
'ProviderID' } )

GROUP NAME: ExtFileStore


DEFINITION: Currently Not Implemented

GROUP NAME: KUAF


DEFINITION: RecArray.Create( {\\
'ID',\\
'Type',\\
'Name',\\
'UserData' } )

GROUP NAME: KUAFChildren


DEFINITION: RecArray.Create( {\\
'ID',\\
'ChildID' } )

GROUP NAME: KUAFUser


DEFINITION: RecArray.Create( {\\
'UserID',\\
'GroupID',\\
'LastName',\\
'FirstName',\\
'MailAddress' } )

GROUP NAME: ProviderData


DEFINITION: RecArray.Create( {\\
'providerID',\\
'refcnt',\\
'providerType',\\
'providerData' } )

GROUP NAME: Schema

Page C-8 Open Text Corporation


Appendix C: Pkg and Utils Object List

DEFINITION: RecArray.Create( {\\


'Name' } )

GROUP NAME: TaskList


DEFINITION: RecArray.Create( {\\
'Project',\\
'TaskID',\\
'Title',\\
'Assignee',\\
'TCreator' } )

fWhereClause
fTableName
fGUIText
fExternal
fErrorMsg
fEnabled
fDisplayable
__Init
SetupCursor
InitRec
GetGUIText
FormatCols
Execute
DBCol

DBWizAPI
DBWizAPI FormAPIExecPkg
Utility
CheckExtStorage
DBWizAPI
DSPExecPkg
DBWizAPI
ExecPkg orphan
DBWizAPI
ExecPkg
DBWizAPI
FormExecPkg
DBWizAP
Undelete ExecPkg
DBWizAPI
WFMainExecPkg
DBWizAPI
Rendition ExecPkg
DBWizAPI
SystemObjExecPkg
DBWizAP
WebExpExecPkg
DBWizAPI
ReportExecPkg

DBWizAPI
Polling ExecPkg

Livelink Builder Fundamentals Course Page C-9


Appendix C: Pkg and Utils Object List

LLIApi
NodeUtil
Documentation
Description:
This is a package contains utility methods dealing with DAPI nodes.

Fields:
Refer to the superclass documentation for inherited fields.

Methods:
Refer to the superclass documentation for inherited methods.

AppendPermissionsToRec - Append the permissions to a RecArray which has DataID and


PermID columns.
ApplyPermsToSubNodes - Update all subnodes so that their permissions and
acls are the same as the passed
in node.
Audit - Record a specific audit event for a node.
CheckName - Make sure that a node name is valid before using it.
CheckPermissions - Check the passed in permission list against the node permission.
CopyAttributes - Copy the system and category attributes from a node to the other.
FindDapiCtx - Find the DapiSession object related to the passed in node.
GetAuditAssoc - Get the list of LLNodes which auditable flags is set
GetNodeTypeName - Get the node type name of a node, eg 'Document', 'Document
Alias'.
GetUniqueName - Generate the unqiue child name of a node.
IsNameUnique - Check if the passed in name is already used by a child node.
ListNodes - Fetches nodes from the database based on query and
permissions.
PermAssocToMask - the permission mask based on the passed in permission assoc
PermissionsUpgradeToRWD - Upgrade the permissions.
PermListToMask - Combine the list of permissions to a integer mask.
PermMaskToAssoc - Return an assoc with the permissions.
PermMaskToSee - Return the value for the See column in the ACL table.
PreScreenClause - Get the pre-screen clause based on the permissions.
RootInfoGet - Get the volume root information of a node.
StreamNodeToText - Query node version data utility: Get the text from a version.
StreamNodeToVal - Map node version data utility: Get the value from a version.
StreamTextToNode - Query node version data utility: Store the text as a version.
StreamValToNode - Map node version data utility: Store the value as a version.
UnreservableByID - Return TRUE if the reserved by value is the current user.

Obsolete methods (they are not maintained and will be deleted):

IsEditable
GetPath
Node2Rec

UnreservableByID StreamSocketToNode
StreamValToNode StreamNodeToVal
StreamTextToNode StreamNodeToText

Page C-10 Open Text Corporation


Appendix C: Pkg and Utils Object List

StreamNodeToSocket GetUserAttributes
StreamBytesToNode GetUniqueName
RootInfoGet GetSystemAttributes
PreScreenClause GetPath
PermissionsUpgradeToRWD GetNodeTypeName
PermMaskToSee GetAuditAssoc
PermMaskToAssoc FindDapiCtx
PermListToMask CopyAttributes
PermAssocToMask CheckPermissions
Node2Rec CheckName
LocalizeAuditEvent Audit
ListNodesByIDs ApplyPermsToSubNodes
ListNodes AppendPermissionsToRec
IsNameUnique
IsEditable

LLIApi LLIApi
CatPkg DbInfoPkg
ListCategories fStrHideKey
ListAttributes fNeedToWrite
IsIdentifier fCurrLine
GetDefaultValue fConnectInfo
GetAttrValues WriteDbInfo
GetAttrInfo UnmapServerType
FindAttrType SessionRecToList
CreateAttrArray SessionListToStorage
CategoryUpdate SessionListToRec
CategoryDelete SessionListFromStorage
CategoryCreate ReadLine
AttrTypeToDbType ReadInfoPath
AttrRecsProcess ReadDbinfoV3
AnyRequired ReadDbinfoV2
AddAttrRecords ReadDbInfoV1
ReadDbInfo
PutConnectInfo
New
MapServerTypeFromString
MapServerType
GetConnectInfo
GetConnectField
FindRec
DelRec

Livelink Builder Fundamentals Course Page C-11


Appendix C: Pkg and Utils Object List

LLIApi
RecArrayPkg
String2RecArray
String2Rec
Record2List
RecArray2List
Rec2String
Rec2List
NewRecord
MergeSimilarRecArrays
MergeRecArrays
List2Record
List2RecArray
List2Assoc
GetRecordIndex
GetFieldVal
DumpRecord
DumpRecArray
DeleteRecord
CopyRec
ClearFieldValue
CheckField
Assoc2List
AddFieldsToRecord

LLIApi
ReleasePkg
VolumeGetByID
VolumeGet
VolumeCreate
ReleasesGet
ReleasedNodeGet
ReleaseStringGet
ReleaseGet
ReleaseCreate
PreReleaseCheck
MasterNodeGet

Page C-12 Open Text Corporation


Appendix C: Pkg and Utils Object List

DomainIsEnabled
DomainGet
LLIApi DomainDisplayNameGet
UsersPkg DisplayNameFormat
Documentation CheckUserLoginName
Description: CheckTabPerms
The root object of LLIApi ospace. CheckPassword
CheckGroupName
Fields: CheckDomainName
fNameLength - The max length AttributesUpdate
for a user name and group name. Defined AllDomainsGroupNew
as 48. The field can hold up to 64 AllDomainsGroupIDGet
characters. But since we add "( delete ) AllDomainsGroupGet
userId" to the userName or groupName
when we delete a user or group, the actual
name can only be less than 48 characters.
fNameLength LLIApi
fMaxUsersInGroup AdminPkg
fMaxUsers UserCreated
fDefaultPWExpirationDate Documentation
fChangePWAtFirstLoginDate Description:
UsersNumGet Deprecated.\
UsersList
UserUpdate
UserNew LLIApi
UserLogout QueryPkg
UserLogin TextQueryAssocGet
UserDisplayNamesAdd QueryAssocGet
UserDisplayNameGet
UserDelete
UserChange
UpdateAdminCookie
PrivsMaskToAssoc
PrivsAssocToMask
PasswordExpirationEnabled
PWDExpireDaysGet
NewUserExpirationDateGet
NameXlateGet
NameXlateAdd
NameGetByID
MyPublicGroupsGet
IsEditable
IsDeleted
IsDefaultGroup
GroupsList
GroupUpdate
GroupNumUsers
GroupNew
GroupDelete
GetUserById
GetAdminCookie
ExpandGroup
DomainUpdate
DomainSystemNameUpdate
DomainSystemNameGet
DomainNew

Livelink Builder Fundamentals Course Page C-13


Appendix C: Pkg and Utils Object List

LLIApi LLIApi
FormatPkg FactoryUtil
fTimeZones LoadDB
fDefFormat Load
fDefDisplayFormat IsCreatable
ValToString Delete
ToIdentifier Add
ToByteString
TestStringToDate
StringToVal LLIApi
StringToDate NewsUtil
StringItemsGet GetSources
StrChangeAll GetNews
RealToPercentage
IsIdentifier
HTMLifyText
GetValue
GetTimeZones
GetTimeZoneByNumber
GetTimeFormat
GetIDsClause
GetIDClauses
GetErrDisplayDate
GetDateFormat
FormatMacroField
FormatDate
DateToList
DateFormatInit
ConvertToSeconds
ConvertFromSeconds
0SetupTimeZone

Page C-14 Open Text Corporation


Appendix C: Pkg and Utils Object List

LLIApi
CacheUtil
_Write
_ObjectDate
_GetObjectDate
_Delete
Update
Touch
New
Load
Delete
Cleanup
0 Test1
Documentation
This package is used to maintain a cache of objects (values) in the
database .. the objects are identified by a unique id .. they are
date stamped when created and when updated .. a method can be called
to clean the cache (stuff older than a certain number of days)

Note that the field ObjectDate contains the expiration date of the
cached object and is undefined if the object should not be flushed
from the cache by the cleanup routines.

The cache table is defined as follows ...

create table %Prefix%LLCache


(
ObjectID %type_int% %not_null%,
SegmentID %type_int% %not_null%,
SegmentBlob %type_long_string% %null%,
ObjectDate %type_date% %null%
)

create unique index LLCache_Primary


on %Prefix%LLCache ( ObjectID, SegmentID )
/

create index LLCache_Index1


on %Prefix%LLCache ( ObjectDate )
/

commit
/

Thats all folks ...

Modifications:
JEM 1999.03 Modified CacheUtil to allow an update to keep the existing
ObjectDate field instead of forcing new one

Livelink Builder Fundamentals Course Page C-15


Appendix C: Pkg and Utils Object List

LLIApi LLIApi
AuthentPkg XMLUtil
LivelinkAuthentication fZeroOrOne
GetUserName fZeroOrMore
GetHiddenPassword fOneOrMore
AuthenticationMethod fLLSystemID
Documentation fLLRootElementVersion
Description: fLLRootElement
This is a container for scripts that fLLPublicID
deal with authentication in Livelink. fISODateFormat
fEmpty
fCharacterData
LLIApi fAttValueFixed
DAPIExtraPkg fAttStringType
fEnabled fAttRequired
fApplTypes fAttNoDefault
CBVersionDelete fAttNameToken
CBDelete fAttID
fAttEntity
LLIApi fAny
AttrUtil Parens
Documentation NotationPublicId
Description: LivelinkDTDFilename
This object AttrUtil contains LivelinkDTD
utility script for the CreateSchemaNotation
complex attribute CreateSchemaElement
implementation.\ CreateSchemaAttribute
UpgradeNodes CreateIDAttribute
TextToValidValues AttNotationType
NumNodesOutdated
GetValuesForIndexing LLPatch
GetDefByID Utils
GetDefAssocByID Sort
GetAttrsForSearch Patch
GetAttrDataWithSourceOption Dump
GenerateMappingRecords
FieldNameToSpec
DumpDefinitions WebDsp
DumpData HTMLPkg
AttrGroupCurrVerGet fButtonBar
AttrDefReferences RemoveDocumentStructureElements
AttrDefIsUsed MailtoAddressSeparator
AttrDefGet ImagePrefix
AttrDefCheckRequired FmtURL
FmtPopupItems
FmtDueDate
FmtDate
ContainsHTML
ArgsToURL

Page C-16 Open Text Corporation


Appendix C: Pkg and Utils Object List

WebDsp
MIMETypePkg
Documentation
Description:
MIMETypePkg defines an object which provides MIME type-
related services. These services include: managing MIME
type to file extension, MIME type to AutoRec type, and GIF
to MIME type mappings, AutoRec-ing a file upload's MIME
type, and determining a version's MIME type.

Data Members:
Assoc .fAutoRecMIMETypes
AutoRec type to MIME type mappings.

String .fDefaultMIMEType
The default MIME type.

Assoc .fFileExtMIMETypes
File extension to MIME type mappings.

String .fFilenameAutoRecTypes
MIME type to AutoRec type mapping textfile name
(currently autorec.types).

String .fFilenameMIMEGIFs
GIF filename to MIME type mapping textfile name
(currently mime.gifs).

String .fFilenameMIMETypes
MIME type to file extension mapping textfile name
(currently mime.types).

Assoc .fMIMETypeFileExts
MIME type to file extension(s) mappings.

Assoc .fMIMETypeGIFs
MIME type to GIF filename mappings.

String .fMIMETypeGIFsDefault
Used to set fMIMETypeGIFs' default item.

List .fMIMETypes
Available MIME types.

Modifications:
DJW 11/06/97 Initial version.
DJW 12/10/97 Added .GetAutoRecMIMETypes().fMIMETypes
fMIMETypeGIFsDefault
fMIMETypeGIFs
fMIMETypeFileExts
fFilenameMIMETypes
fFilenameMIMEGIFs
fFilenameAutoRecTypes
fFileExtMIMETypes

Livelink Builder Fundamentals Course Page C-17


Appendix C: Pkg and Utils Object List

fDefaultMIMEType
fAutoRecMIMETypes
__Init
_SetMIMETypes
_SetMIMETypeGIFs
_SetAutoRecMIMETypes
IsInMIMETypeList
GetMIMETypes
GetMIMETypeGIF
GetMIMETypeFileExts
GetMIMETypeFileExt
GetFileExtMIMEType
GetDefaultMIMEType
GetAutoRecMIMETypes
GetAutoRecMIMEType
FindFile
AutoRecMIMEType

WebDsp WebDsp
WebModuleUtils WebTimingsPkg
SupportPath Documentation
SetupUrl Description:
RemoveLineFromHTML WebTimingsPkg defines an
QueryStringFromIniFile object which provides web request
GetModuleDocPath timing services.
GetDocPath
FindHTMLFile Data Members:
FileNameBuilder Assoc .fTimingData
AddLineToHTML Collection of the
provided timing data.
fTimingData
WebDsp fLineCount
RequestHandlerUtils fCSVLogFile
Documentation __Init
Description:
ResetTimingData
This object is just a container for
OutputCSVEntry
functions that relate to request handlers
MergeTimingData
GetTimingDataTypes
Data Members:
GetTimingData
fRequestHandlerGrandPa
GenerateSummaryTimings
Object ref points to the first ever
DeleteTimingData
request handler (private)
AddTimingData
Modifications:
WJM Sept 26, 1997
First Version.
fRequestHandlerGrandPa
SetContentRH
ServiceString
ListRHsInThisOSpace
IsKindOfRequestHandler

Page C-18 Open Text Corporation


Appendix C: Pkg and Utils Object List

WebLL IndexObject
WebUtils UpdateUtils
fMenu fStopIniKeyword
UserGifTags fIniSection
UserGifTag fIniKeyword
UserGifAltTag fExcludedMimeTypesSection
UserGif fCookiePrefName
UnixClient StopExtraction
TextToNumber Setup
SortIndicatorGet SetLogin
SetTargetBrowseCookie SetLastUpdate
SetCookie ReIndex
NoJavaInHTML IsStopExtraction
NoFunctionPopup IsPrefValueDefined
NetscapeClient IsMimeTypeExcluded
NavJavaEnabled GetLogin
NavAllowOverride GetLastUpdate
MacClient DeleteLastUpdate
MSIEClient ClearStopExtraction
GetUserLinkInfo AddEvent
GetMenu
GetCookie
EditUserGifTag IndexObject
DisplayStylesGet IndexObjectUtils
AddMenu fIndexTimeFormat
fIndexDateFormat
MetaString
IndexObject IndexTimeToString
RegionUtils IndexDateToString
fRegionAssoc
fIniSection
fIniKeyWord IndexObject
__Init VerifyUtils
UpdateRegions fStatusIniKeyword
SaveRegionAssoc fLogFileName
IsRegionUndefined fIniSection
IsRegionDefined StatusSet
GetRegionAssoc Status
DeleteAllRegions LogWrite
DefineRegion LogClear
GetLogFileName

IndexObject
CorrectIndexUtils
fStatusIniKeyword
fLogFileName

Livelink Builder Fundamentals Course Page C-19


Appendix C: Pkg and Utils Object List

WebAdmin Hh
AdminUtils HHUtils
fINSOTemplateHTML fObjName
WriteOT6Config fExcludedMimeTypes
SortNodeTypes fDefaultValue
SetSysCookie _PutDataToDB
SetDBInfo _GetDataFromDB
ResyncAll PutDataToDB
ProviderInfo IsBrowserViewable
GetNodeAuditEvents HHDoc
GenerateINSOTemplate HHBuffer
GetFilteredContent
GetExcludedMimeTypes
WebAdmin GetDataFromDB
WebStatusPkg ExpandQuery
Update 0 test
Setup

APIExplorer
Inbox APIExplorerUtils
InboxUtil GetRegisteredSubtypeExtension
fStatusPending _Test
fStatusOnHold RegisterExplorerType
fStatusIssue IsCompoundDocSubtype
fStatusInProcess GetRegisteredSubtype
fStatusCompleted GetExplorerTypeRegistry
fStatusCancelled _InitializeFeatures
ValueToStatusStr
ValueToStatus
ValueToPriorityStr
ValueToPriority
ValueToDueDate
StatusStrToValue
PriorityStrToValue
IsActiveExpression
CodesStatus
CodesPriority

Hh
DocFetcherUtils
GetURLContent
GetDocToDisk

Page C-20 Open Text Corporation


Appendix C: Pkg and Utils Object List

CreateBroker
CheckNodes
SupSearch CheckFileNameForBadChars
SearchUtils BSlashToFSlash
fLibrarySearchEngines
fLibraryIndex
fLibraryIPool SupSearch
fLibrary ScriptUtils
fHelpIndex SpiderCreation
fHelp SearchManagerCreation
fAdminHelpIndex SearchCreation
fAdminHelp ProducerCreation
UpdateSearchEnginesList IntermediateCreation
StopIPool IndexUpdateCreation
StartIPool FilterCreation
SetPermissions EnterpriseExtractorCreation
RemoveQuotesFromPath DataFlowCreation
RemoveLastSlash ConsumerCreation
PortValidation
NameValidation
IsValidURL SupSearch
HelpDataSourceInitialControlRules CacheUtils
GetPorts fEnabled
GetOrphanedSlices fDefaultNumEntries
GetIndexObjs fCacheDateTime
GetDirFromFilePath fCache
GetDataFlowParameters __Init
GetBrokerObjs _BuildKey
FSlashToBSlash SetEntryValues
EnterpriseDataSourceInitialControlRules SetData
CreateThis GetNumberofObjects
CreateSearchManager GetEntryValue
CreateSearch GetDefaultValue
CreateProcess GetData
CreateLibraryExtraction DeleteData
CreateIPool 0 EchoCache
CreateBrokerAlias

Livelink Builder Fundamentals Course Page C-21


Appendix C: Pkg and Utils Object List

SupSearch
DAPIExtraPkg
Documentation
All of the functions in this package return an assoc

Parameters

prgCtx Prg Session


dataPkg
VersionID | ( DocID, Version ) Either reference by VersionID or DocID/Version
KeyWords A string of keywords (optional)
Summary A summary string (optional)
DataBlock A general data block

Returns

ok = TRUE|FALSE
errMsg = Error String

Add Add a new entry to the DVersExtraData table


Get Get the specified content of the DVersExtraData table
Delete Delete the specified content of the DVersExtraData table

Table Def'n in MSSQL

CREATE TABLE [DVersExtraData] (


[VersionID] [int] NOT NULL ,
[TextStr] [varchar] (64) NULL ,
[DataString] [text] NULL
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

_GetVersionID
Get
Delete
Add

Page C-22 Open Text Corporation


Appendix C: Pkg and Utils Object List

Sovmgmt Websovmgmt
Utils DataFlowRuleUtils
fSOVtempFileName _RuleString5
fSOVAlertDirectory _RuleString4
fSMTPMailtemplateHTML _RuleString3
fPendingOperations _RuleString2
fMailConfig _RuleString1
_MailMessage _CreateReportString
_GetTimeStatus _CreateActionString
_GetRules _CreateActionAndReportString
_GetMessages CreateUserPrintableRuleString
_GetMailFileName CreateRuleAltTagString
_GetEmailAddress
_GenerateUserMessage
_GenerateUsageTable Distributedsupport
_GenerateSummaryMailMessage Utils
_GenerateHTMLMailMessage GetORB
_GenerateCompleteMessageList GetBOA
_GenerateBackupMailMessage
_GenerateASCIIMailMessage Distributedsupport
TestSOVMailMessage PrivateUtils
SetTimeStatus CopyORB
SetMsgsSeen
SetMailConfig
ResetSOVManagement Formapi
RemoveIBRNotificationInstanceRule FormTemplatePkg
GetTimeStatus _UpgradeValueTemplate
GetMsgTypeList _LoadTemplateInfo
GetMessages _GetInfoFromRendition
GetMailConfig _FlattenSchema
GetIBRNotificationInstanceRules VerifyTableSchema
GetCustomMessages ValidateTemplateView
GetCompleteListOfMessages ValidateTemplate
DoPendingOperation UpgradeFormData
DoMailMessage UpdateTableSchema
ConvertUsers TemplateNodeFromID
ClearPendingOperation TemplateNodeFromFormNode
ClearMsgLine SetTemplateSQLTableName
ClearAllMessages NewSchema
AddPendingOperation ListViews
AddMsgLine GetTemplateSQLTableName
AddInstanceRule GetTemplateFieldList
AddCustomLine GetTemplateFieldInfo
fMailOffline GetAllTemplateInfo
FlattenData
CreateSQLTable
ConvertDefaults
BackMapSchema
AddField

Livelink Builder Fundamentals Course Page C-23


Appendix C: Pkg and Utils Object List

Formapi Formapi
FormRevisablePkg FormSubmitPkg
fTemplateWritePerms fTemplateWritePerms
fTemplateReadPerms fTemplateReadPerms
fTemplateDeletePerms fTemplateDeletePerms
fSubType fSubType
fRequiresNode fObjectFactory
fObjectFactory fName
fName fIsDataModifiable
fFormWritePerms fIsDataListable
fFormReadPerms fFormWritePerms
fFormDeletePerms fFormReadPerms
fFlags fFormDeletePerms
fEnabled fFlags
__Init fEnabled
SaveNonFormData __Init
SaveData SubmitData
PurgeData MoveData
MoveData MechRightsUpdate
MechRightsUpdate MechRightUpdate
MechRightUpdate MechRightDelete
MechRightDelete MechRightAdd
MechRightAdd LoadData
LoadNonFormData ListData
LoadData IsModifiable
InitStorage IsListable
GetSubmitDispatchArgs InitSubmitArchive
GetFlags GetSubmitDispatchArgs
GetFlag GetFlags
FactoryType GetFlag
FactoryName FactoryType
DeleteAllNonFormData FactoryName
DeleteAllData DeleteOneData
CreatePre DeleteAllData
CopyData CreatePre
0 Setup CopyData
0 Setup

Formapi
FormUtil
fMinorVer
fMajorVer
ToIdentifier
StreamValToNodeVersion
SetDataFromFlatData
IsIdentifier
GetAttrToParentAssoc
DeepCopy
CreateRendition

Page C-24 Open Text Corporation


Appendix C: Pkg and Utils Object List

Formapi
WFFormSubmitPkg
Formapi
FormViewPkg
fSubType Formapi
fName HTMLFormViewPkg
fEnabled fSubType
fAddableToTemplate fName
fAddableAsTemplate fEnabled
__Init fAddableToTemplate
NodeAddVersionSubclassPre
NodeAddVersionSubclassPost
NodeAddVersionSubclass
AddViewToTemplate

WF
WAPIPkg GetStatusSortPref
fErrorMsg GetStatusPagingPref
XLateStatus GetStatusListStepName
XLateAuditInfo GetStatusListRows
UpdateWorkflowMap GetStatusListRelation
TestCondValues GetStatusKindPref
StartWF GetStatusExprPref
SetWorkUserData GetStatusCondInfo
SetWorkDataPackage GetStatus
SetWFStatus GetProxyPref
SetTaskDoneData GetPagePref
SetSubWorkReturnData GetMapStatusInfo
SetSubWorkData GetInitiatorID
SetStatusTypePref GetGroupDispoChoice
SetStatusSortPref GetExpandGroupData
SetStatusPagingPref GetEvaluateData
SetStatusNoArchiveExprPref GetDispositionData
SetStatusKindPref GetAuditRec
SetStatusArchiveExprPref GetAuditPref
SetProxyPref GenericCB
SetPagePref FinishTask
SetExpandGroupData Expand
SetAuditPref EvaluateCondition
SetAdvancedPerformer DeleteWorkPackages
SaveWork DeleteDispositions
SaveSubMap CustomStartWF
SaveDisposition CustomCB
ReplaceVariable CreateWorkPackage
RemoveWorkDataPackage CheckWrkPkgTaskDone
LoadWorkPkgRec CheckWFPermissions
LoadWorkData CheckTaskAssignedToUser
LoadUpdateMap AddWorkDataPackage
LoadSubMap AddIndexNotifyRow
IsNotificationEnabled AddAuditData
HasByPassPerm AcceptTask
GetWorkPackages 0Documentation
GetWFStatusList
GetWFPermissions
GetTodoList
GetStatusTypePref

Livelink Builder Fundamentals Course Page C-25


Appendix C: Pkg and Utils Object List

WF DropTaskRecord
MapStoragePkg DropLinkRecord
SaveMap CreateWorkPkgRec
LoadMap CreateWFPermissionRecArray
IsTempStorage CreateTasksRec
GetMapFromTempHolder CreateModificationMap
GetHolderName CreateMapRec
GetHolderByID CreateMapInfoRec
CreateTempHolder CreateMap
CheckEditable CreateLinksRec
0Documentation CreateAttribRec
CleanupPkgsAfterModify
AddLinkRecord
WF 0Documentation
WFMapPkg
fVerNumMinor
fVerNumMajor WF
_WillLoopbackBeSelfContained WFCustomScriptPkg
_IsStepInLoopbackBlock __Init
_DoesLinkCauseLoopback StartWF
VerifyMapDefinition CBExecute
VFMakeNewFreshMap 0Documentation
VFDeletePackage
VFAddPackage
VFAddNewTask WF
UpdateMapDefinition AdvancedPerformerPkg
_SetSubMapID
UpdateEvaluateData
SyncUserIDsInMapDef _SendToAllUsers
SyncTaskWorkPackages VerifyDefinition
SetToSameUser
SetSubMapCallbacks
SetPackagesVersionInfo SetToMultiUsers
SetMapTempStorage SetToAttrUsers
EvaluateUser
SetMapCallbacks
SaveMapPackages
SaveMap WF
RemoveCBInfoType WFUtils
ReadyWMapRec UpdateV8ToV9SubMapTask
ReadyTasksRec UpdateV8ToV9Attributes
ReadyPkgsForModify UpdateTaskCallback
ReadyLinksRec UpdateSubMapDataInfo
PrepareWorkPackage UpdateOperator
PrepareMapData UpdateMapCallback
PrepareLinkCache UpdateFormFieldInfo
LoadMap UpdateConjunction
IsLinkValid UpdateConditionalInfo
GetWFTypes
GetWFRoleTypes
GetWFDataTypes
GetValidEvents
GetObjectScripts
GetNewTaskRec
GetMapData
GetAllDispositionInfo
GetAllConditionalInfo
FormatPainterIconData
DropUserIDsFromMapDef

Page C-26 Open Text Corporation


Appendix C: Pkg and Utils Object List

otadmin
Utils
WF fSingle
XMLICCustomScriptPkg fAdminActionSection
fAdminActionKeyword
WebNode StartAdminActionTransaction
WebNodeUtils HTTPServerURL
Documentation GetDeselectFileName
Description: EndAdminActionTransaction
WebNodeUtils defines a class DeselectDBPre
which contains WebNode utility DeselectDB
functions. DeleteSetupPrefs

Data Members:
WebOTCIndex
None.
WebOTCIndexUtils
Space2NoSpace
Modifications:
GetSystemVolumeFolders
DJW 09/97 Initial version.
GetLibraryNode
RetrieveTree CreateFolder
NodeToWebNode
ModifiedIMG
GetRightName WebOTCIndex
GetRightIcon FindSimiliarUtils
GetRightIMGs fObjName
GetRightIMG fDefaultValue
GetRightGIF _PutStatsToDB
_GetStatsFromDB
PutStatsToDB
Home GetStatsFromDB
HomeUtils
Remove
GetTickerData sbroker
GetFavoritesData Util
Get fNewBrokers
Add StoreSearchData
SearchLogNewSearch
SearchLog
Home QueryWhereFromTemplate
TabsUtil QueryWhere
ManageTasks QueryOTSQLFromTemplate
ManageStatus
QueryMerge
ManageProjects QueryFromTemplate
ManageNews PutSearchData
ManageFavorites
MergeSearchResults
DefaultTabs GetSlicesFromTemplate
Add GetSearchDataFromID
GetSearchData
Channel GetCollections
ChannelUtils FixSavedQueries
ViewAllChannels DeleteSearchTemplates
UpdateNewsCount CreateSearchLog
ManageMyChannels Convert
GetWriteableChannels ApplyQueryKids
GetReadableChannels AppendLocation
GetChannels

Livelink Builder Fundamentals Course Page C-27


Appendix C: Pkg and Utils Object List

sbrokerweb sbrokerweb
BrokerUtil AttributeUtil
searchFormUpdate _ItemLQLWhereConnect
UpdateAttrList WriteNewAttrList
TurnOnComponents WriteAttrList
Truncation UpdateNewAttrList
Template ProcessCategoryArgs
SortColumns PrefixOTToRegion
SetVirtureSysAttributes ModifierMapping
SetBrokerParameters ListCatAttributes
SearchForm GetWidgetCommand
ResetAttributes GetWhereFromAttrList
RecArray2AssocList GetSearchWidgetList
ProcessArgs GetSearchWidgetByName
NewSearch GetSearchWidget
MergeOTSQL GetOTSFromNewAttributes
ListAllAttributes GetOTSFromAttributes
GetWhereFromArgs GetNewAttrTableFieldNames
GetVirtureSysAttributes GetLQLFromItemDate
GetSystemSearchObjs GetLQLFromItem
GetSystemDefDsp GetFulltextWidget
GetSystemBrokers GetFilteredAttributes
GetSysAttributeByName GetAttrsForSearch
GetSlicesFromArgs GetAttributeTable
GetSearchModeInOrder GetAttrTableFieldNames
GetResults ConvertTemplate
GetObjectTypes CategoryExist
GetOTSQLWhere
GetModifiersName
GetLibraryBroker sbrokerweb
GetFieldNames TemplateUtil
GetDspOptsFromNode WriteTemplate
GetDisplayName UpdateTemplate
GetDefDspOpts Template
GetDate SetDefaultTemplate
GetComponentsInOrder SaveTemplate
GetCategories SaveAsTemplate
GetBrokers NewSearchFromTemplate
GetAttributeByName2 HardCodedSystemDefTemplate
GetAttributeByName GetUserTemplateFolderNode
GetAllSearchObjs GetTemplateList
DisplayOption GetSystemDefTemplate
ConstructRegions GetSearchTemplateNode
BrokerDefDspRegion GetSearchBarDefTemplate
AssocList2RecArray GetReadableTemplates
ApplyQuery GetPSTFolderNode
AddToOtherSection GetAdminTemplateNode
AddSynthetic DefTemplate
CreateUserTemplateFolder
CreateSearchTemplateNode

Page C-28 Open Text Corporation


Appendix C: Pkg and Utils Object List

sbrokerweb SystemObj
RegionUtil BackupUtil
GetAllQueryRegions UpdateRestoreFile
GetAllDisplayRegions SetConfigFile
ReadRestoreFile
ReadHistoryFile
sbrokerweb MakeRestoreTable
ButtonUtil MakeHistoryTable
GetButtonsInOrder IsEnterpriseDataSrc
GetRemoteFile
SystemObj GetIndexPath
Utils GetBCMFromDataSource
ReadFileContents DeleteConfigFile
PrintAssoc CreateRestoreFile
GetProcessTermination CreateProcess
ArgsToAssoc CreateConfigFile
CreateConfigAssoc
CleanupManagerProcesses
SystemObj BuildCompleteLabel
DBUpgradePkg AddEnterpriseReExtraction
UpdateSysTemplateFolderType
UpdateDefaultRegionsOnEnterprise
RenameFilterToOTDocCnv SystemObj
PutTextToNode ConfigFileUtils
MoveRegionMapToVersData SetConfigFile
HardCodedSystemDefTemplate MoveConfigFile
GetTextFromNode CreateConfigFile
CreatePersonalTemplateFolderNew
CreatePersonalTemplateFolder Report
AddQLToKeywords ReportUtils
ReadImportFile
SystemObj ImportString
TagPkg GetObjectPrompt
RemoveTaggedRegion GetMenuItems
RemoveItalicTags GetInvMenuItems
GenerateSubstitutionString
GenerateBindings
ExportReports
AddSQLArg

Dirwalk
Utils
DirWalkerCreation
DirWalkerCleanup
DWErrorHandler
CreateDirWalker

Livelink Builder Fundamentals Course Page C-29


Appendix C: Pkg and Utils Object List

Xmlactivator Themes
Utils ThemesUtils
fName test
XMLActivatorCreation reverseAssocOrder
SetConfigFile fkey
MetadataValidation fDefaultThemeSettings
GetInfo ThemesDate
CreateXMLActivator SplitTerms
PutThemesSettings
MakeGraph
NLQSearc GetThemesSettings
NLQutils GetThemesInfoFromResults
ProcessNLQ GetStatsFromResults
GetHotWords GetRating
GetPlateau
Summarizer GetOriginalQuery
SumUtils GetMyThemes
fObjName GetClustersAndPhrasesFromList
_PutDataToDB GetClusterSeeds
_GetDataFromDB FormatTopic
PutDataToDB FormatLocationNameURL
HighlightOffsets FormatLocationName
Highlight DateWhere
GetDataFromDB DateName
DateCategory
CullPhrases
ClusterList
AddRegionToSelect
AddNames
0 Setup

Page C-30 Open Text Corporation


Appendix C: Pkg and Utils Object List

Formwfapi Task
FormWFUtils TaskListUtils
UpdateSubmapData _TasksGet
_TaskInfoSet
_ResourcesDetailSet
XMLDSP _MilestonesDetailSet
Utils _AssigneesGet
SaveErrorLogFile UpdateTaskListCount
QDEcho TaskSubTypeClause
MakeTempFile TaskListSummary
GetRelayLock TaskListAttachmentAssoc
DOMToFile ResourcesDetail
CompactInt RemoveMilestoneReferences
MilestonesDetail
WebDoc MilestoneInfo
WebDocUtils ManageMyTasklists
VStreamToWeb LengthDays
UpdateAttr GetWriteableTaskLists
Space2UnderScore GetTaskLists
SetupAttribs GetTaskListMenu
NodeToWeb GetTaskListInfo
NodeToView GetReadableTaskLists
ManageMyReservedItems GetMilestones
GetVersionMIMEType ClauseTaskMilestone
GetName ClauseTaskAttachment
GetHits ClauseTaskAndGroupSubType
GetFileUploadName AttachmentRecArray
GetFileUploadInfo AssigneeDetail
GetDownloadFileName
CreateQueryString Project
CreateFileUploadVersion ProjectUtils
CreateFileUploadDocument ManageMyProjects
BadChar2UnderScore MailToURL
AutoRec GetReadableProjects
GetMenu
WebUser
WebUserPkg
UGSearchPrototype
UGSearchDomainPopup
ManageMyGroups
GroupCount
GetSortString
GetGroupEmail
FormatFullName
FormatDisplayName
ExecuteUserSearch
Documentation

Livelink Builder Fundamentals Course Page C-31


Appendix C: Pkg and Utils Object List

Discussion
TopicPkg
Documentation
Description:
The package contains methods that supports Livelink discussion.

A discussion is a node which has an associated discussion volume.


A discussion item is a message stored in a discussion volume.
Livelink implements Topic and Reply as discussion items. Topics
are items stored under the volume. A reply can be a child or parent
of another discussion item to form the threads. Other non-discussion
items in the tree are attachments.

A discussion and all its items do not have permissions set. The
access permissions is actually based on the permissions of the
discussion. Every nodes in the discussion volume have PermID
defined to the discussion's DataID.

When a discussion item is created, an unique sequential number


(within that discussion volume) is assigned to the Ordering column.
These sequential numbers are used for storing read indicator as well
as for generating outline threads for displaying.

This package supports the read items list for a user of a discussion.
The read list is in the form:

{ {3,8}, {12,12}, {15,20}, ... }

which means the discussion items 3 to 8, 12, and 15 to 20 are


already read by a user. The deleted list, which contains the
items id which have deleted in a discussion, has the same format.

The read list or a deleted list will be compacted when more items
are read and more items are deleted.

It is important that all discussion items have larger Ordering


values than their parent discussion items. This is to maintain the
integrity of the discussion database. The forming of the
nested thread (for displaying) is depending on this structure.
Therefore, moving of a discussion item is only possible if the
item is to be moved to the top level (which is the level under
the root node).

The followings are related database tables:

- DTree: Used to store the discussions and all their items.

- DiscussionID: Each row stores the latest id used of a discussion.

- DReadList: Each row stores the read list of a user of a discussion.

- DDelList: Each row stores the deleted list of a discussion.

Page C-32 Open Text Corporation


Appendix C: Pkg and Utils Object List

Fields:
Refer to the superclass documentation for inherited fields.

Methods:
Refer to the superclass documentation for inherited methods.

AttachmentAssoc - Get the attachment information for all items in a discussion.


AttachmentRecArray - Get the attachments of a discussion item.
BSearch - Search for a number from a read list.
ContentGet - Get all the discussion items of a discussion or the children
items of a discussion item.
ContentLoad - Get all the discussion items of a discussion.
DeletedListDelete - Delete a deleted list of a discussion (when a discussion is
deleted).
DeletedListFix - Administrative method to fix the deleted list of a discussion.
DeletedListGet - Get the deleted list of a discussion.
DeletedListPut - Create or update the deleted list of a discussion.
DiscussionInfoGet - Get the basic item and read information of a discussion for the
current user.
IsInList - Check whether an integer is in a read list.
ItemsAssoc - Get the count for all items in a discussion.
ListAdd - Add an integer to a list.
ListCompact - Compact a list.
ListLength - Get the number of integers in the list.
ListMerge - Merge two lists.
ListTest - The test script for read list.
MarkAllRead - Mark all items of a discussion read for the current user.
MarkIsRead - Mark an item read for the current user.
MaxIDGet - The latest discussion id used in a discussion.
ParticipantsAssoc - Get the participants information in this discussion.
ReadListGet - Get the read list of a discussion of the current user.
ReadListPut - Delete the read list of a discussion of the current user.
ReadListsDelete - Create or update the read list of a discussion of the current user.
RootGet - Get the root of a discussion volume by specifying an OwnerID.
SequentialIdGet - Get the next sequential integer and update the latest used integer.
UniqueNameGet - Get an unique name for a reply before creation.
WhereSubTypes - Get the where clause to retrieve discussion items or attachments.\
WhereSubTypes IsInList
UnreadInfoGet DiscussionInfoGet
UniqueNameGet DeletedListPut
SequentialIdGet DeletedListGet
RootGet DeletedListFix
ReadListsDelete DeletedListDelete
ReadListPut ContentLoadEx
ReadListGet ContentLoad
ParticipantsAssoc ContentGet
MaxIDGet BSearch
MarkIsRead AttachmentRecArray
MarkAllRead AttachmentAssoc
ManageMyDiscussions
ListTest
ListMerge
ListLength
ListCompact
ListAdd
ItemsAssoc

Livelink Builder Fundamentals Course Page C-33


Appendix C: Pkg and Utils Object List

OTCIndex Webform
Utils WebFormPkg
UpdateRegionMap _IsNotError
SetDictionaries _GetTemplateNode
GetMechLists
EditFormData
OTCIndex
PermissionObjectHandlerUtils
Workflow Webform
AdminIndexPkg
fEnabled
WebAttribute __Init
WebAttributeUtils GetSectionInfo
GetCategoryNamesFromNode
GetCategoryNames
Webform
LivelinkIndexPkg
Webxmlactivator fEnabled
Utils __Init
ParseFormUtil GetSectionInfo

TextEdit Webform
TextEditUtils WebSubmitPkg
GetEditableMimeTypes fSubType
fHTMLCreateStationery
Undelete fHTMLCreate
UndeleteUtils fEnabled
fPurgeStatusIniKeyword __Init
fIniSection SubmitData
fExcludedSubtypeIniKeyword Name
SetDefaultIniSettings GetArgsFromRequest
SaveDeletedData GetAPIObj
PurgeStatusSet Create2
PurgeStatus
PurgeDeletedDocsTable Webform
IsSubTypeExcluded WebStoragePkg
GetOriginalPath fSubType
GetNodeDeletedDocVol fHTMLCreateStationery
GetDeletedData fHTMLCreate
DBUpgradeMSSQL fEnabled
__Init
Undelete Name
LogUtils GetAPIObj
LogWrite Create2
LogClear
GetLogFileName

Page C-34 Open Text Corporation


Appendix C: Pkg and Utils Object List

Rendition
RenditionUtils
Webform QueueAgain
WebFormViewPkg LogErrors
fSubType
LoadQueue
fMustRedirect LoadPrefs
fHelpKey EnQueue
fHTMLFile
DeQueueBySeq
fHTMLAddVersion DeQueueByID
fFrameFriendly
fEnabled
__Init WebWork
_SubclassCreatePre WFPkg
_SubclassCreateIsCreatable StartWorkflow
_SubclassCreate2Pre SetURLArg
_SubclassCreate SetTaskIDArg
_AddVersion2 SetPaneIndexArg
ValuesFromRequest SetNewStatusArg
UpdateRequestParams SaveMap
URLCreate LoadMap
RedirectAfterSave GetStatusPageInfo
Name GetStatusLocationList
IsFrameFriendly GetStatusIcon
GetSubmitDispatchArgs GetStatusDisplayUserSettings
GetStandardExtendedData GetStatusDisplaySortOrder
GetRedirectLocation GetStatusDisplayKind
DisplayForm GetStatusDisplayInfo
AddVersionInfo GetStatusColor
GetStartTaskData
GetSortInfo
Webform GetNextTask
ExtDataPkg GetMapName
fEnabled
GetHeaderTypeArgs
__Init GetDefaultDisplay
AddExtendedData GetAllStatusIcons
GetAllPainterInfo
Webform CheckTaskAssignee
WFWebSubmitPkg AddStatusSortInfo

Webform WebWork
HFormViewPkg StatusPkg
_UpdateFormSchema GetWhereClause
_SendFormDownWire GetNameTypes
_ParseArgsForFormData GetInitiatorTypes
_GetViewPath GetExecuteStatusTypes
_GetViewDirPath GetDateTypes
_GetView GetAllStatusInfo
fSubType GenerateWhereClause
fMustRedirect
fEnabled
ValuesFromRequest
RedirectAfterSave
DisplayForm

Livelink Builder Fundamentals Course Page C-35


Appendix C: Pkg and Utils Object List

Main
TextFindUtil
WebWFP ReplaceAllText
WFPkg Replace
StoreCallbackData
FindText
SetURLDirtyFlag FindAgain
SavePaintedMap Find
SaveMap
LoadMap
IsMapDirty Builder
GetPropertiesPageInfo Builder Utils
GetPerformer
GetNavMenuItems
GetMapLocationInfo Builder
GetEventData Path Utils
GetCallbackFields StoreValue
ReadOnly
OpDefinitions
WebFormwf MakeGlobalPath
WFPkg MakeFeaturePath
SaveFormData MakeExprPath
GetWorkflowExtendedData MakeDebuggerPath
GetFormEditData IsValid
GetExtendedFormData IsExpandable
GetValue
GetName
XMLWFIC GetElements
WFUtils GeneratePathName
XMLToPackages
SetTargetStates
SendToTargets Builder
SendFinishCheck Utilities
QDDepth SystemFeatures
PrepareTargets Post
PackagesToXML NewOSpaceSetup
GetTargetStates NewOSpace
ExtractTargetStates MoveObject
CreateStringHash MoveFeatures
ImportObject
ImportOSpace
Main GlobalsParent
Dialog Utils ExportObject
YesNo ExportOSpace
SaveChanges DeleteObjectAndChildren
Notify
CopyObject
Error CopyFeatures
Confirm
Ask

Page C-36 Open Text Corporation


Appendix D: Glossary

Action-[CommandName] methods Methods of WebNodes that contain the code (built-in


function calls, database selects, updates, etc.) to perform node
commands.

Action object Used to add new or override existing commands for node types.

ApplType A group of node types. ApplTypes are used to identify a group of node
types at once, for example, when naming the node types which can be
used as the parent or child of a given node type.

Builder The Livelink Builder is an application development environment for


customizing Livelink.

Child object An object directly below another object in an object tree, which
inherits features from its parent.

Class object An object containing some base functionality that is reused and
augmented by the children of that object, which children are often
called subclasses.

DAPINode A multi-value datatype, used to work with documents, folders,


workflow maps, projects, and other node types. (DAPI refers to the
document management built-in package of functions.)

DTree table A table in the Livelink schema that stores one record for every
DAPINode.

ExtendedData column A column in the DTree table which can store custom data for a node.

fCmdNames feature A feature of each WebNode object that maintains a list of commands
that can be performed against the node type. The URLs for these
commands are stored in WebNodeCmd objects.

fCmdNamesInfo feature A feature of each WebNode object that maintains a list of tab
names that appear on the Info page for nodes of the type defined by the
WebNode.

Feature A value (string, number, recArray, method, etc.), given a name and
stored as a component of an object. Features are dynamically typed in
Livelink, which means that you can store a string in them one moment,
and a date the next moment.

Livelink Builder Fundamentals Course 92-300 04Feb11 Page D-1


Appendix D: Glossary

fPrototype feature A list feature for request handler and WebNode objects that defines the
input parameters for calls to the object.

Globals object An object which stores references to all features which should be
accessed globally using the syntax $GlobalName.featureName. Every
OSpace contains one Globals object.

Inherited feature A feature inherited from the parent that has not been modified in the
object.

LAPI The Livelink API (Application Programming Interface), a set of


functions for accessing and updating the Livelink database from C++,
Java, and Visual Basic.

ll request handler The request handler that processes most actions against Livelink items.

Localization The process of translating the user interface text from one language to
another.

New feature A new feature for this object that does not exist in the parent object.

Node A Livelink item (such as a document, folder, workflow map).

Node type A type of Livelink item (such as the document node type, the folder
node type, or the workflow node type).

Object reference An object reference feature stores the ID number of another object.

Object A set of features that represent one element of the overall


functionality, such as a set of file management routines.

opentext.ini file A configuration file that is used during system startup to set options
and specify the modules that should be loaded when the server is
started.

Orphan object A child object that is not stored in the same OSpace as its parent.

OScript A full featured programming language that lies at the heart of Livelink,
driving its functionality. OScript is used in primarily in methods and
WebLingo files.

OSpace A set of objects stored in a file, including a root object and the root
object’s descendants (called an object tree) and often some orphan
objects.

Overridden feature A feature inherited from the parent that has been modified in
this object.

Page D-2 Open Text Corporation


Appendix D: Glossary

Parent object The object that is directly above an object in an object tree, from
whom an object inherits features.

RecArray An OScript datatype that defines a two-dimensional array with


multiple rows of data, called records.

Request handler A type of object that processes Livelink URLs.

Root object The object at the very top of an object tree. There is one root object per
OSpace. The Startup() method of the root object runs when the
OSpace is opened.

Setup script A method that is used to populate other features of an object, and that
is run only by the developer during development.

Subsystems Objects that manage a related group of objects. For example, the
ModuleSubsystem provides scripts for retrieving and registering all of
the WebModule objects throughout Livelink.

WebLingo An HTML file containing embedded OScript in a special format, used


to dynamically generate HTML pages.

WebModule An object which stores all the details about a module, such as its name,
dependencies, and version number.

WebNode An object whose attributes and methods drive the web representation
for a node type.

WebNodeCmd An object that defines the URL, display name, icon, and some of the
enabling and disabling behavior for a WebNode command.

XLate An identifier in a method or WebLingo file for a string of text in stored


in an XDB (translation database), containing user text in a specific
language (such as English or German).

Livelink Builder Fundamentals Course Page D-3


Appendix D: Glossary

Page D-4 Open Text Corporation


Appendix E: Quiz
Overview:

Whew! That was a lot of information, and this is only the beginning—remember, this course
is called Builder Fundamentals. Here’s a summary of what we did and some information
about where to go next.

Livelink Builder Fundamentals Course 92-300 03Dec29 Page E-1


E.1 Time for the Quiz

A quiz is a good way to review the topics of the course:

From Section 1, Introduction

1. What’s the difference between the Builder and LAPI?


When should you use which tool?

From Section 2, How Requests are Processed

2. Draw a picture of Livelink’s architecture, tracing a call


from the web browser to the storage of data.

3. What is the purpose of the opentext.ini file?

4. Describe how Livelink takes the URL


?func=user.edituser&userID=5644 and decides
what object to use to process the URL—in other words,
how does Livelink locate the request handler object?

From Section 3, The Builder as a Development


Environment

5. Describe the hardware and software in a typical


Livelink development environment.

6. Define “orphan object.”

7. When using the object browser window, what’s the


difference between “browse by inheritance” and
“browse by OSpace”?

8. How often should you export your OSpace?

9. When you delete a feature that was overridden from its


parent object, what happens?

Page E-2 Open Text Corporation


From Section 4, Setting Up a Module

10. What are the main components of a module, file-wise?

11. What happens when you install a module, file-wise?

12. What objects do you need to create in order to create a


module?

13. Describe how Livelink initializes objects during startup.

From Section 5, OScript

14. Describe what this code does:


RecArray empsData = [code for selecting from EMP table]
record employee
string msg
for employee in empsData
msg = Str.Format( "Employee: %1. Dept: %2. Phone: %3",\
employee.NAME, employee.DEPT, employee.EXT )
Echo( msg )
end

15. What’s wrong with this code fragment?


function void GetInfo( name, date=Date.Now(), event )

16. When should you add an object to your OSpace’s


Globals registry?

Livelink Builder Fundamentals Course Page E-3


From Section 6, Making a Request Handler

17. Explain how Livelink processes the request in this URL


and displays the Edit User page, naming the objects and
features involved:

?func=user.edituser&userID=5644

18. What are the basic steps for creating a request handler?

19. How does data get from the Livelink database into an
HTML file when using a request handler?

From Section 7, Taking Advantage of WebLingo

20. What’s the syntax you would use to:

a. Insert a line of OScript into a WebLingo file?

b. Insert a string of OScript into a line of HTML in a


WebLingo file?

c. Call a webscript from a WebLingo file?

21. What does a request handler’s HTMLPrefix() method


return?

From Section 8, Plugging into the Livelink Interface

22. What are the basic steps you take to put a new
command on the Navigation menus?

23. Give an example of a URL that would not work on the


Navigation menus.

Page E-4 Open Text Corporation


From Section 9, Overview of Livelink Node Objects

24. Name two of the tables in the Livelink schema that are
used to store Livelink nodes (items).

25. Compare and contrast these objects that are involved in


creating and managing a node type: ll, LLNode,
WebNode, and WebNodeCmd.

26. Describe what the ll request handler does when it


processes a request.

27. What’s an ApplType?

From Section 10, Controlling the Commands for a Node


Type

28. How does Livelink determine which commands are


available to a node of a given node type?

29. How does Livelink determine which tabs should appear


on the Info page for a node of a given node type?

From Section 11, Storing Additional Node Data

30. Name some of the ways you can store custom data with
a node.

31. Describe the basic steps for using the ExtendedData


column of the DTree table to store additional data.

From Section 12, Adding a New Node Command

32. Given this URL, describe how Livelink might find an


Action object to perform the command.
?func=ll&objId=2402&objAction=browse

33. How does Livelink know the node types to which an


Action object should apply?

Livelink Builder Fundamentals Course Page E-5


E.2 Summary

We have:

• Shown you how to use the Builder’s interface.

• Introduced you to Livelink’s programming language,


OScript.

• Explained the basics of how Livelink’s object system


works and how its code was implemented.

• Shown you how to create new features in a supported


way.

• Shown you how to figure out how particular features of


Livelink were implemented, so that you can reuse and
enhance them.

• Most importantly: Taught you a development


methodology for your customizations.

E.3 Where to Go Next

Skim the Builder documentation and find out more.

Visit the SDK areas of the Knowledge Center to find out


more and ask questions. Use Change Agents to set
notification on areas like the Builder discussion.

Keep an eye out for future courses.

If you have a difficult customization to do, get in touch


with Professional Services.

Page E-6 Open Text Corporation

You might also like