You are on page 1of 88

Advanced WebReports Workshop

Creating Advanced WebReports


12 November 2012
Contents

Contents
Contents ........................................................................................................................................... i
1 Welcome to the Advanced WebReports Workshop ........................................................... 1
1.1 Workshop Audience and Objectives ................................................................................... 1
1.2 Prerequisites ....................................................................................................................... 1
1.3 Class Information ................................................................................................................ 1
2 Accessing Content Server Data Structures ........................................................................ 3
2.1 Overview and Objectives .................................................................................................... 3
2.2 Accessing Content Server Data Structures......................................................................... 3
2.2.1 The Problem and Solution....................................................................................... 3
2.2.2 Other Content Server Data Structures .................................................................... 4
2.2.3 Coping with Nested Data Structures ....................................................................... 5
2.3 Exercises ............................................................................................................................. 7
2.3.1 Task List Report ...................................................................................................... 7
2.3.2 WebReport with Constants Report.......................................................................... 7
3 Action Sub-tags...................................................................................................................... 9
3.1 Overview and Objectives .................................................................................................... 9
3.2 Action Sub-tag List .............................................................................................................. 9
3.3 Action Sub-tag Properties ................................................................................................. 11
3.4 Display Considerations ..................................................................................................... 11
4 Variables and Variable Action Sub-tags ............................................................................ 12
4.1 Overview and Objectives .................................................................................................. 12
4.2 The Variable Tag ............................................................................................................... 12
4.3 Variable Sub-tag Types ..................................................................................................... 13
4.4 Using Variable Sub-tag Actions ......................................................................................... 14
4.4.1 Using CONCATVAR and ADDVAR ....................................................................... 14
4.4.2 Using CURRENTVAL to Display Intermediate Variable Values ............................ 15
4.4.3 Using Variable Data with Other Action Tags.......................................................... 16
4.5 Variables and Conditional Tags ......................................................................................... 17
4.6 Exercises ........................................................................................................................... 18
4.6.1 Building an email distribution list ........................................................................... 18
5 NODEACTION & USERACTION Sub-tags .......................................................................... 19
5.1 Overview and Objectives .................................................................................................. 19
5.2 Using NODEACTION ........................................................................................................ 19
5.3 Using USERACTION ........................................................................................................ 21
5.4 Exercises ........................................................................................................................... 22
5.4.1 Copying Content Server content ........................................................................... 22
6 Pre-defined Sort Parameters .............................................................................................. 23
6.1 Overview and Objectives .................................................................................................. 23
6.2 SORT Review.................................................................................................................... 23
6.3 New SORT Directives ....................................................................................................... 24
6.4 Exercises ........................................................................................................................... 26
6.4.1 Specifying Complex sort keys ............................................................................... 26
7 Initiating Workflows ............................................................................................................. 27
7.1 Overview and Objectives .................................................................................................. 27
7.2 Concepts ........................................................................................................................... 27
7.3 Populating Workflow Attributes ......................................................................................... 29

Advanced WebReports Workshop i


Contents

7.4 Populating Forms Within a Workflow ................................................................................ 30


7.4.1 Populating a Form Field ........................................................................................ 30
7.4.2 Populating a Multi-Value Form Field ..................................................................... 31
7.4.3 Populating a Field in a Multi-Value Set ................................................................. 31
7.4.4 Populating a Multi-Value Form Field in a Multi-Value Set ..................................... 32
7.5 Initiating Multiple Workflows .............................................................................................. 33
7.6 Exercises ........................................................................................................................... 34
7.6.1 Initiating a Workflow .............................................................................................. 34
7.6.2 Set Attributes in the Workflow ............................................................................... 34
7.6.3 Conditionally call a Sub-WebReport ..................................................................... 34
8 Ajax with WebReports ......................................................................................................... 35
8.1 Overview and Objectives .................................................................................................. 35
8.2 Displaying Reports in a Customview with an IFRAME ..................................................... 35
8.3 Displaying Reports in a Customview with ajax.js .............................................................. 36
8.4 Inserting Context Sensitive Data into a Customview ........................................................ 38
8.5 Dynamically Counting Filter Hits as the User Types ......................................................... 39
8.5.1 Creating a WebReport with XML Output ............................................................... 39
8.5.2 Calling a WebReport Using Ajax ........................................................................... 40
8.5.3 Component Review ............................................................................................... 42
8.6 Calling a WebReports Service using AJAX....................................................................... 43
8.6.1 Service Request Syntax ........................................................................................ 43
8.6.2 Using the Predefined JavaScript Function from ajax.js ........................................ 45
8.7 Exercises ........................................................................................................................... 46
8.7.1 Creating a Dynamic PWS page ............................................................................ 46
8.7.2 Creating a Sub-tag Lookup Tool............................................................................ 46
9 Data Source Parameters ..................................................................................................... 47
9.1 Overview ........................................................................................................................... 47
9.2 Request as a Data Source - Parameters .......................................................................... 48
9.3 Example ............................................................................................................................ 49
9.4 Exercises ........................................................................................................................... 49
9.4.1 Passing SourceId as Parameter ........................................................................... 49
10 WR Trigger ............................................................................................................................ 50
10.1 Overview ..................................................................................................................... 50
10.2 General Usage ........................................................................................................... 50
10.3 WR Trigger tags .......................................................................................................... 51
10.4 Exercises .................................................................................................................... 52
10.4.1 Initiate Workflow with WR Trigger ......................................................................... 52
11 WR Power View .................................................................................................................... 53
11.1 Overview and Objectives ............................................................................................ 53
11.2 Adding a WR Power View .......................................................................................... 53
11.3 Benefits of WR Power View ........................................................................................ 54
11.4 WR Power View Usage .............................................................................................. 54
11.5 Exercises .................................................................................................................... 56
11.5.1 Adding a Power View to Content Server WebForms ............................................ 56
12 Administration and Debugging .......................................................................................... 58
12.1 Overview and Objectives ............................................................................................ 58
12.2 Configuring opentext.ini .............................................................................................. 58
12.3 Tags for Debugging .................................................................................................... 60

Page ii Advanced WebReports Workshop


Contents

12.4 Debugging Tips ........................................................................................................... 60


13 Help! ...................................................................................................................................... 62
14 Appendix - LiveReport Extensions SQL Templates ......................................................... 63
14.1 Overview and Objectives ............................................................................................ 63
14.2 Template Fields .......................................................................................................... 64
14.3 Using URL Parameter ................................................................................................ 65
14.3.1 Adding an Order By Clause .................................................................................. 65
14.4 Using Auto-Where ...................................................................................................... 66
14.5 Re-Using Templates ................................................................................................... 67
14.6 Re-Using Templates with Multiple Variable Inputs...................................................... 68
14.7 Using the Auto Comma feature .................................................................................. 71
14.8 Additional Template Features ..................................................................................... 71
14.8.1 Using Templates within Templates ........................................................................ 71
14.8.2 Using the Template View Icon ............................................................................... 71
15 Appendix - Server Side Scripting ....................................................................................... 73
15.1 Overview ..................................................................................................................... 73
15.2 Security ....................................................................................................................... 73
15.2.1 Enabling Scripting for a WebReport ...................................................................... 73
15.2.2 Oscript Restrictions ............................................................................................... 74
15.3 Recommendations for Developing Scripted Reportviews .......................................... 75
15.4 Defining and Calling a Script ...................................................................................... 75
15.5 Passing Data to a Script ............................................................................................. 76
15.5.1 The Context Assoc ................................................................................................ 76
15.5.2 Passing Parameters .............................................................................................. 76
15.6 Calling Static Data Tags .............................................................................................. 77
15.7 Calling Sub-tags ......................................................................................................... 78
15.8 Calling Sub-WebReports ............................................................................................ 78
15.9 Script Scope and Calling a Script From Within a Script ............................................. 79
15.10 Exercises.............................................................................................................. 80
15.10.1 Scripting Exercise ............................................................................................. 80

Advanced WebReports Workshop iii


Welcome to the Advanced WebReports Workshop

1 Welcome to the Advanced WebReports Workshop

1.1 Workshop Audience and Objectives


This workshop covers some of the more advanced aspects of designing WebReports. It
discusses a number of advanced features and explores some useful techniques.

The intended participants are report developers who want to create more sophisticated
WebReports or even build applications within Content Server using WebReports and other
objects such as Content Server Forms.

1.2 Prerequisites
Delegates attending this workshop are expected to be familiar with creating WebReports and
LiveReports including writing SQL. The following are considered prerequisites:

Content Server ECM WebReports Design I

Creating LiveReports and Content Server Schema

Familiarity with SQL, HTML and JavaScript

1.3 Class Information


Please record the username and password that the instructor assigns to you:

Username:

wr (1,2,3,etc.)

Password:

livelink

URL:

http://training.v.resonatekt.com/T97/livelink.exe

Advanced WebReports Workshop Page 1


Welcome to the Advanced WebReports Workshop

Page 2 Advanced WebReports Workshop


Accessing Content Server Data Structures

2 Accessing Content Server Data Structures

2.1 Overview and Objectives


In this section we examine some more advanced features of WebReports such as sub-tags
for accessing complex Content Server data structures.

By the end of this section you will be able to

Index into Content Server data structures like Assoc and RecArray to extract the data
you want.

2.2 Accessing Content Server Data Structures

2.2.1 The Problem and Solution

Sometimes useful data that you need in a report or application is stored in the database in a
special proprietary format that is difficult to unravel with a SQL query. For example Content
Servers task list object stores data in a structure known as an Assoc. Lets look at an
example:

Tasks store their data in the DTree table and many of the fields are separate columns but not
all. Some are stored in a string representation of an Assoc in the ExtendedData column.
For the task above the ExtendedData column looks like this:

A<1,?,'Comments'='Keep it brief. Use the corporate


template','Instructions'='Write up meeting minutes and
distribute. Remember to include Peter Bond in R&D on
distribution.'>

This string represents a data structure with the following key-value pairs:

Advanced WebReports Workshop Page 3


Accessing Content Server Data Structures

Key Value

'Comments' 'Keep it brief. Use the corporate template'

'Instructions' 'Write up meeting minutes and distribute. Remember to include Peter


Bond in R&D on distribution.'

If you wanted to create a report displaying comments and instructions from a task you would
need a way to index into the Assoc to get the values you wanted. WebReports provides a
simple way to do this using a sub-tag:

[LL_REPTAG=extendedData ASSOC:Instructions /]

The Assoc sub-tag takes a parameter that identifies the key for the value you want returned.
The overall result of the tag above would be the insertion of the following text:

Write up meeting minutes and distribute. Remember to include


Peter Bond in R&D on distribution.

The tag in this


example did not return the
text enclosed in single
quotes even though thats
how it appeared in the
Assoc. The single quotes
exist in the Assoc to
identify that the value was
a string type.

2.2.2 Other Content Server Data Structures

Content Server has a number of proprietary data structures posing the same issues as the
Assoc for report developers. The following table describes them and shows examples of sub-
tags to access their data. See also the tag syntax reference in the online help or user
documentation for reference documentation.

Type Notes/Example Sub-tag Example

Assoc A data structure of key-value pairs. Keys may ASSOC:status returns 3


be any type (not just strings). E.g.
ASSOC:42 returns meaning of
A<1,?,'status'=3,'text key with universe
spaces'='value',42='meaning of
universe'> ASSOC:"text key with
spaces" returns value
ASSOC:[3] returns the third
value in this case meaning of
universe

Page 4 Advanced WebReports Workshop


Accessing Content Server Data Structures

List A list of values. E.g. LIST:1 returns first item


{'first item',2,3,'forth LIST:3 returns 3
item',{'a','b','c'}}
LIST:5 LIST:3 returns c

Record A record consisting of fields identified by a RECORD:name returns Steve


string label. E.g.
RECORD:2 returns Finance
R<'name'='Steve','role'='Finance'>

RecArray An array of records. E.g. this RecArray has RECARRAY:2:name returns the
two records (each with fields name and role): name field of the 2nd record i.e.
V{<'name','role'><'Steve', Lee
'Finance'><'Lee','Marketing'>} RECARRAY:1:2 returns the
second field of the first record
i.e. Finance

2.2.3 Coping with Nested Data Structures

Sometimes useful Content Server data can be buried inside highly nested data structures
which combine a number of different data types in a hierarchy. We can access these by
combining the sub-tags and using them one after the other to work our way into the data
structure.

Lets take a look at a real example:

Category and attribute metadata is stored in Content Server in two tables LLAttraData and
LLAttrBlobData. Both contain the same data but in a different structure. The second of these
is really intended for internal use only. However it has the advantage of storing the
information in a flattened form with a nodes ID and version number as keys to a row in the
table that holds all the attribute data for that node. (LLAttraData has the same data but data
for each node is split over many rows requiring lots of SQL self joins to bring it together).

The columns for LLAttraBlobData are ID, VerNum, SegmentID, SegmentBlob. The attribute
data appears in SegmentBlob. Here is an example:

A<1,?,{274176,3}=A<1,?,'CustomID'=0,'ID'=1,'Values'={A<1,?,2=A<1,?,'I
D'=2,'Values'={'home & home office','small
business'}>,3=A<1,?,'ID'=3,'Values'={1}>,4=A<1,?,'ID'=4,'Values'={'On
the
Road'}>,5=A<1,?,'ID'=5,'Values'={?}>,6=A<1,?,'ID'=6,'Values'={'Good'}
>,7=A<1,?,'ID'=7,'Values'={'Good'}>,8=A<1,?,'ID'=8,'Values'={'Better'
}>,9=A<1,?,'ID'=9,'Values'={'N/A'}>,10=A<1,?,'ID'=10,'Values'={'Best'
}>,11=A<1,?,'ID'=11,'Values'={1}>>}>>

Look closely and you can see that there are Assocs nested within Assocs. The first key of the
first Assoc {274176,3} is a List that identifies a category (274176 is the nodeID of the
category and 3 is the version of the category in use). The value that goes with this key
represents the attribute data. This attribute data for the node looks like this:

Advanced WebReports Workshop Page 5


Accessing Content Server Data Structures

As an example lets imagine we want to get access to the usage attribute (which has
attribute ID 4). Its nested inside several Assocs, but by combining several sub-tags we can
get to it (the relevant bits are highlighted in the data structure above):

ASSOC:{274176,3} ASSOC:Values LIST:1 ASSOC:4 ASSOC:Values


LIST:1

This returns the data

On the Road

While this is syntactically correct, creating a key such as {274176,3} can be difficult in practice
as you would need to find a category ID as well as the latest version of that category. For this
particular table, this Assoc has only one member so a simpler syntax to use would be:

ASSOC:[1] ASSOC:Values LIST:1 ASSOC:4 ASSOC:Values LIST:1

This variation is mentioned in section 2.2.2 and basically allows each ASSOC item to be
referenced using a numeric index instead of the specific name key.

Of course there are


easier ways to do this using
the CAT sub-tag but
occasionally this approach
can be useful where the
best performance is critical.
(CAT has to do database
lookups each time it is
used, although it caches
data during the execution
of a WebReports to deliver
maximum efficiency where
the same data is used
twice).

Page 6 Advanced WebReports Workshop


Accessing Content Server Data Structures

2.3 Exercises
2.3.1 Task List Report

1. Create a task list with a couple of tasks in it that include example data in the name,
status, comments and instruction fields.
2. (Optional -) Write a LiveReport called List Tasks that lists all the DTree columns for the
tasks in your list. Here is the SQL you will need (note the minus sign):

select * from DTree where ParentId=-<node ID of task list>

Find the node ID of your task list by hovering the mouse over the task list link and
observing the URL in your browser status bar.

3. Create a WebReport to display the tasks from your created task list. This can either be
done by using the task list as a data source or by using the List Tasks LiveReport as a
data source. For a reportview you could use the basic reportview as a starting point. Edit
the reportview to provide a tabular report with the following columns:
Task Name
Status (hint: to convert to the phrase, try using the STATUS:TASK sub-tag)
Instructions
Comments
4. Add a column on the far left that contains a link or icon or button to open the task for
editing.

Want to cheat? Here is the code to provide an icon that does this:

<A HREF="[LL_REPTAG=DATAID LLURL:DEFAULTLINK /]


&nexturl=[LL_REPTAG_MYURL ESCAPEURL /]" ><IMG
SRC="[LL_REPTAG_SUPPORTDIR /]button_edit.gif" NAME="editbutton"
BORDER="0" ALT="Edit Task"></A>

2.3.2 WebReport with Constants Report

WebReports objects themselves make use of the ExtendedData column in the DTree table.
Each WebReport object holds information about things like Parameters, Constants and Export
(Destination) settings inside Content Server data structures in the ExtendedData column.

1. Create a LiveReport called List WebReports to list all the DTree fields for all
WebReports in the system. Here is the SQL you will need:

select * from DTree where SubType = 30303

2. Create a new WebReport using List WebReports as your data source. Edit the
reportview to display the following information in separate columns:

WebReport Name
Name and Value of the first constant if it is defined (display as <name> = <value> in a
single column)
Name and Value of the second constant if it is defined
3. Now filter the results so only WebReports that have constants defined are included in the
report. Use the INCLUDEIF tag to achieve this.

Advanced WebReports Workshop Page 7


Page 8 Advanced WebReports Workshop
Action Sub-tags

3 Action Sub-tags

3.1 Overview and Objectives


In this section we examine some specialized sub-tags that have unique behaviors and effects.

By the end of this section you will be able to


Identify the current set of Action Sub-tags available in WebReports and where they
can be used
Identify how Action Sub-tags are different from other sub-tags and how to use them

3.2 Action Sub-tag List


The term Action Sub-tags describes a set of sub-tags that perform specific actions as
opposed to simply manipulating data returned by a WebReports tag. The following list
describes the current set of these sub-tags and what they do.

Sub-tag Name Description

Action tags used to manipulate variables

SETVAR Takes the data specified by the associated tag and sets a
named variable with it

CONCATVAR Takes the data specified by the associated tag and


concatenates it to a named variable

ADDVAR Takes the data specified by the associated tag and adds it
numerically to a named variable

Action tags associated with export destination types

SETFORM Used with the Form export destination to specify which field in
the form will be set with data from the corresponding tag

SETWFFORM Used with the Workflow export destination to specify which


form and which field in the form will be set with data from the
corresponding tag

SETWFATTR Used with the Workflow export destination to specify which


attributes will be set with data from the corresponding tag

SETWFATTACH Used with the Workflow export destination to copy or move


aContent Server node specified by the corresponding tag to
the attachments folder of the workflow

Action tags that are independent of the export destination

NODEACTION Used to copy, move, create, delete and update nodes in


Content Server irrespective of the WebReport destination

Advanced WebReports Workshop Page 9


Action Sub-tags

USERACTION Used to create, delete and update Content Server users


irrespective of the WebReport destination

AUDITACTION Used to generate Audit logs for a specified node or user

CATACTION Used to set Category/Attributes with specific values

PERMACTION Used to set permissions on a specified Content Server node

RMACTION Use to set RM data for a specified Content Server node

WFACTION Used to perform actions on a specified Content Server


workflow

Most of these sub-tags will be described in more depth in future chapters.

Page 10 Advanced WebReports Workshop


Action Sub-tags

3.3 Action Sub-tag Properties


One of the main differences between action sub-tags and the normal sub-tags is that they are
designed to store or set the tag data in some other storage location. Normally this means that
the data from the corresponding tag will not be displayed in the output of the WebReport.

An action sub-tag can have any number of normal sub-tags to the left of it in the tag
syntax. Any changes these normal subtags make will be used to perform the
specified action.

Most sub-tags used to the right of an action sub-tag will be ignored. The SHOW sub-
tag (described below) and the CURRENTVAL sub-tag (described in chapter 5) are
notable exceptions to this rule.

3.4 Display Considerations


Normally the use of an Action Sub-tag in a tag means that the tag data is not displayed in the
output of the WebReport. If it is required that the tag data be displayed, then the SHOW sub-
tag must be used. This should usually be in the rightmost position in the sub-tag list. Note that
this sub-tag always causes the original tag value (prior to the action being performed) to be
displayed. For variable action sub-tags it is important to note that any variable calculations
are not included in the displayed data. The examples below should clarify this.

Sub-tag Syntax Description

[LL_REPTAG_"2" SETVAR:test /] A variable called test is created and


set to the value: 2. (This value for
test will be assumed in the
subsequent examples.)

[LL_REPTAG_"123" ADDVAR:test /] The value 123 is added to the


variable named test (making the
new value of test equal to 125).
Nothing is displayed in the report
output.

[LL_REPTAG_"123" ADDVAR:test SHOW /] The value 123 is added to the


variable named test (assuming
test is still set to 2). This makes the
new value of test equal to 125.
The original value 123 is displayed
in the report output.

[LL_REPTAG_"123" DEC ADDVAR:test SHOW /] The value 123 is decremented by


the DEC subtag (changing the value
to 122). This is then added to the
variable named test making the
new value of test equal to 124).
The original value (after
decrementing) of 122 is displayed in
the report output.

Advanced WebReports Workshop Page 11


Variables and Variable Action Sub-tags

4 Variables and Variable Action Sub-tags

4.1 Overview and Objectives


In this section we examine tag variables and the various associated sub-tags that are used to
work with variables.

By the end of this section you will be able to

Use appropriate sub-tags to set and amend variables

Use the CONCAT sub-tag to build an email list

Use the variable tag to display the final value of a variable

Use the CURRENTVAL sub-tag to show the intermediate value of a variable

Use the CURRENTVAL sub-tag to show the new value of variables following
operations by variable sub-tags

4.2 The Variable Tag


Variables can be displayed using a special WebReports variable tag like this:

[LL_REPTAG_%test /]

This example shows the syntax if we wanted to display a variable called test in the report
output. This tag can be used anywhere in the reportview but will always display the final
value of the variable. That is, after any variable sub-tags elsewhere in the reportview have
modified the variable. Normal formatting type sub-tags can be used with this tag, e.g.:

[LL_REPTAG_%test UPPER /]

If you want to see the current value of a variable at a specific point in the reportview
(reflecting only the sub-tag actions that have occurred up to that point) you must use the
CURRENTVAL sub-tag as shown here:

[LL_REPTAG_%test CURRENTVAL /]

Action sub-tags can not be used with variable tags unless this CURRENTVAL sub-tag has
been included.

In the upcoming sections we will explore various ways the CURRENTVAL sub-tag can be
used to allow variables to interact with other action sub-tags.

Page 12 Advanced WebReports Workshop


Variables and Variable Action Sub-tags

4.3 Variable Sub-tag Types


First we will review the different variable sub-tag actions ( see WebReports tag guide).

Sub-tag Syntax Description

SETVAR:<variable name> Stores the value of the tag (after


formatting by any previous sub-tags) in
a variable which can be referenced
using the specified name. E.g.
[LL_REPTAG=DATAID SETVAR:ID /]
This example would store the dataid
returned by the report tag in a variable
called "ID"

CONCATVAR:<variable name> Concatenates the value of the tag with


or the current contents of a variable
CONCATVAR:<varname>:<joinstr> referenced using the specified variable
or name. The first time this sub-tag is used,
CONCATVAR:<varname>:<joinstr>:NOBLANKS
it behaves as if the variable already
or
CONCATVAR:<varname>:<joinstr>:UNIQUE existed with an empty string. The
second (optional) parameter can be
used to specify a character or string of
characters which are used before each
new value added to the variable. If the
special string @EMAIL is used as the
"join string" the standard email separator
as defined for the Content Server
system will be automatically inserted. A
third optional parameter can only be
used if the join string has been supplied.
When NOBLANKS is used, no join
strings will be added for empty data
cells. Alternatively (instead of
NOBLANKS) the parameter UNIQUE
can be used to ensure that only unique
values are added to the concatenated
variable.

ADDVAR:<variable name> Numerically adds the value of the tag


(after formatting by any previous sub-
tags) with the current contents of a
variable. This tag only works when
numeric values are returned by the
corresponding tag. The first time this
sub-tag is used, it behaves as if the
variable already existed with the value of
zero (0)

CURRENTVAL Used to return the current value of a


variable and or the result of a variable
action sub-tag.

Advanced WebReports Workshop Page 13


Variables and Variable Action Sub-tags

4.4 Using Variable Sub-tag Actions


In this section we will examine how some of these sub-tags are used in conjunction with other
tags to solve problems.

4.4.1 Using CONCATVAR and ADDVAR

The sub-tags ADDVAR and CONCATVAR are most useful when used in the row section to
combine multiple cells of data into a single value. Note that for adding multiple numeric
values from report data columns, the [LL_REPTAG_@SUM /] tag can also be used. We will
examine some examples of using CONCATVAR and ADDVAR here using this sample data
source and the following syntax explanation table.

ID Name Quota

1 Bob 100

2 Ted 250

3 Carol 150

4 Alice 50

5 Bob 50

Tag Syntax Variable Result Description

[LL_REPTAG=Name Names = The name column for each row in


CONCATVAR:names:, Bob,Ted,Carol,Alice,B the data source is concatenated
/] ob into the names variable with a
comma (,) in between each item.
Note that for the first row the
Names variable is assumed to be
a blank string

[LL_REPTAG=Name Names = This is the same as the previous


CONCATVAR:names:, Bob,Ted,Carol,Alice example but use of the UNIQUE
:UNIQUE /] parameter means the second
occurrence of Bob is omitted

[LL_REPTAG=Quota Total = 600 The quota column for each row in


ADDVAR:Total /] the data source is cumulatively
added to the Total variable.
(100+250+150+50+50)

Page 14 Advanced WebReports Workshop


Variables and Variable Action Sub-tags

4.4.2 Using CURRENTVAL to Display Intermediate Variable Values

The CURRENTVAL sub-tag is used to allow variable sub-tags to display the current value of a
variable according to its position within the reportview. Variable sub-tags are processed
starting at the top of the file and working towards the bottom (rows are also processed in
order from 1 to n). A variable tag of the form, [LL_REPTAG_%test /], returns the final value of
a variable regardless of where it was positioned in the reportview; however, if the
CURRENTVAL sub-tag is included in a variable tag, the tag will display its value according to
its position in the reportview. This example illustrates the difference.

Reportview

The total for all quotas in the report: [LL_REPTAG_%totals /]

[LL_WEBREPORT_STARTROW /]

Quota for [LL_REPTAG=name /]: [LL_REPTAG=quota ADDVAR:totals SHOW /]


([LL_REPTAG_%totals CURRENTVAL /])

[LL_WEBREPORT_ENDROW /]

Output

The total for all quotas in the report: 600


Quota for Bob: 100 (100)
Quota for Ted: 250 (350)
Quota for Carol: 150 (500)
Quota for Alice: 50 (550)
Quota for Bob: 50 (600)

Note: observe the different between in behavior CURRENTVAL and SHOW

The same output could also be produced with this alternative syntax:

The total for all quotas in the report: [LL_REPTAG_%totals /]

[LL_WEBREPORT_STARTROW /]

Quota for [LL_REPTAG=name /]: [LL_REPTAG=quota /] ([LL_REPTAG=quota


ADDVAR:totals CURRENTVAL /]

[LL_WEBREPORT_ENDROW /]

This variation uses a simple report tag, [LL_REPTAG=quota /], to display the quota value then
when adding the quota to totals, the CURRENTVAL sub-tag is used to display the new value
of totals after ADDVAR executes.

The output of CURRENTVAL can be modified by other sub-tags like this:

[LL_REPTAG_%totals CURRENTVAL TRUNC:5 /]

Advanced WebReports Workshop Page 15


Variables and Variable Action Sub-tags

4.4.3 Using Variable Data with Other Action Tags

Normal variable tags can not be used to supply data for action sub-tags unless the
CURRENTVAL sub-tag is used.

[LL_REPTAG_%totals CURRENTVAL SETFORM:field1 /]

It is also possible to use formatting or display type sub-tags to modify the data that is output
by CURRENTVAL.

[LL_REPTAG_%totals CURRENTVAL TRUNC:5 SETFORM:field1 /]

More than one CURRENTVAL sub-tag can be used in a tag provided all syntax requirements
are met.

[LL_REPTAG_%names CURRENTVAL TRUNC:5 CONCATVAR:namestr CURRENTVAL /]

The last example works as follows: the current value of names is output by the first
(leftmost) CURRENTVAL. This output is then processed by TRUNC:5 (which truncates the
output string to 5 characters) and then concatenated with the variable namestr. Finally the
last CURRENTVAL sub-tag causes the new value of namestr to be displayed in the
reportview

The following syntax rules apply to the use of CURRENTVAL:

A CURRENTVAL sub-tag must be the first sub-tag used in a variable tag list or must
have a variable action tag (e.g. ADDVAR, CONCATVAR, SETVAR) immediately to its
left in the sub-tag list.

Syntax Validity

[LL_REPTAG_%somevar CURRENTVAL /] VALID

[LL_REPTAG_%somevar DEC CURRENTVAL /] INVALID

[LL_REPTAG_"2" CURRENTVAL /] INVALID

[LL_REPTAG_"2" ADDVAR:anyvar CURRENTVAL /] VALID

[LL_REPTAG_"2" ADDVAR:anyvar DEC CURRENTVAL /] INVALID

Where a CURRENTVAL sub-tag has other action sub-tags to its right, the output of
the CURRENTVAL sub-tag can be used by the next action sub-tag to its right in the
sub-tag list.

Syntax Validity

[LL_REPTAG_%temp CURRENTVAL ADDVAR:anyvar /] VALID

[LL_REPTAG_%temp ADDVAR:anyvar /] INVALID

Page 16 Advanced WebReports Workshop


Variables and Variable Action Sub-tags

Where there are non-action (e.g. formatting) sub-tags between CURRENTVAL and
the next action sub-tag to its right, the formatting sub-tags will effect the output of
CURRENTVAL to modify the data that will be used by the next action sub-tag

[LL_REPTAG_%temp CURRENTVAL UPPER TRUNC:5 ADDVAR:anyvar /]

In this example the output of temp is converted to uppercase, truncated and then
added to anyvar.

4.5 Variables and Conditional Tags


From WebReports 4.0.1 variables can be used to control IF/ENDIF type tags. The setting or
editing of variables can also be prevented if they are nested within IF/ENDIF blocks. This
behavior is linear. That is, variables and conditionals are processed from the top of the
reportview to the bottom. The examples in this section illustrate this effect.

Normally, to use a variable as part of a conditional expression, the CURRENTVAL sub-tag is


used to ensure we are working with the current value as opposed to the final value. E.g.:

[LL_WEBREPORT_IF "[LL_REPTAG_%totals CURRENTVAL /]" >= "500" /]

The next example illustrates the cause and effect of using variables in conditional expressions
as well as placing variable action sub-tags within a conditional expression.

[LL_REPTAG_"Name List: " SETVAR:somestr /]


[LL_WEBREPORT_STARTROW /]
[LL_REPTAG=NAME CONCATVAR:names:, /]
[LL_WEBREPORT_ENDROW /]
[LL_WEBREPORT_IF "[LL_REPTAG_%names CURRENTVAL /]" <> "" /]
[LL_REPTAG_%names CURRENTVAL CONCATVAR:somestr /]
[LL_WEBREPORT_ELSE /]
[LL_REPTAG_"No Names" SETVAR:somestr /]
[LL_WEBREPORT_ENDIF /]
Final Output: [LL_REPTAG_%somestr /]

This example sets a variable called somestr to the string Name List:. In the row section,
multiple names are potentially concatenated to the variable called names. Following the row
section we have a check to see if the names variable is empty or not. If the names variable
is not empty, we concatenate the names variable to the somestr variable to create an
output that would be something like: Name List: Bob, Ted, etc. If the names variable is
empty then we simply set somestr to the literal string: No Names. The somestr variable is
output at the end of the report output.

Advanced WebReports Workshop Page 17


Variables and Variable Action Sub-tags

4.6 Exercises
4.6.1 Building an email distribution list

1. Create a basic WebReport with the _listUsers data source provided and note the
response when you run this report to the browser

2. In the row section for this WebReport, add a report tag to return the mail-addresses from
the data source (E.g. [LL_REPTAG=MAILADDRESS /]). Add the CONCATVAR sub-tag to
this tag so that all of the mail addresses will concatenated (using a comma as the
delimiter) and stored in a variable called emails.

3. Add a variable somewhere near the top of the reportview to show the final value of the
variable emails. Run the WebReport manually and observe the variable result

4. Find a way to force the CONCATVAR sub-tag to use the delimiter for separating email
addresses as defined for the Content Server system. Re-run the WebReport to examine
the final variable result again

5. Add to the row section of the reportview a variation on the variable tag that will show for
each row, the current value of the emails variable

6. Change the destination of the reportview so that the output will be sent via email. Use a
WebReports variable tag to allow the emails variable to be inserted as the E-mail Address:
field

Page 18 Advanced WebReports Workshop


NODEACTION & USERACTION Sub-tags

5 NODEACTION & USERACTION Sub-tags

5.1 Overview and Objectives


In this section we examine the NODEACTION and USERACTION sub-tags.

Superficially NODEACTION and USERACTION are similar to other sub-tags but on closer
inspection they differ considerably from both regular sub-tags and action sub-tags. Whilst
regular sub-tags effect formatting and action sub-tags effect data in the WebReport
destination (for example meta data in a workflow) these two sub-tags directly effect the items
that they are executed against, which can be any number of items anywhere in Content
Server.

By the end of this section you will be able to

Understand how to use NODEACTION to create, update, move and delete content in
Content Server

Understand how to use USERACTION to create, update and delete users and groups
in Content Server

5.2 Using NODEACTION


NODEACTION has no impact on the WebReports destination. It acts on a tag-by-tag basis to
manipulate objects in Content Server. This sub-tag needs to be used with care as a
statement such as this in the row section:

[LL_REPTAG=DATAID NODEACTION:DELETE /]

Would delete every object returned by the data source. If the data source was a LiveReport
returning 1,000 rows, you can quickly see what can be achieved!

Only objects that the


user running the
WebReport has appropriate
permissions on will actually
be deleted. The tag
doesnt allow users to do
anything they cant in the
regular interface; it just
happens much faster and
on a much larger scale.

Advanced WebReports Workshop Page 19


NODEACTION & USERACTION Sub-tags

Current NODEACTION capabilities:

NODEACTION Option Description

Copy Allows any node in Content Server (providing the user running the
WebReport has permission) to be copied to a specified
destination. Its possible to specify a name for the new node and
also whether it contains all the versions in the source node or just
the latest version

Create Allows the creation of Content Server objects such as URLs,


Shortcuts, Folders, Generations and Documents. If a document is
being created it is possible to specify a source object where the
content will be taken from

Delete Simply deletes the node returned in the main tag

Display Used to change the display setting of an object e.g. change an


item from being featured to being hidden

Lock Allows a specific version of a node to be locked

MaxVers Sets the maximum number of versions for a node

Move Allows items to be moved in Content Server whilst also allowing


control over whether permissions are inherited from the
destination or maintained from the source

MoveProvider Changes the storage provider for a version

Nickname Allows new nicknames to be assigned

OwnedBy Change the ownership of a node

Promote Allows promotion to a major version

PurgeVersions Allows a specified number of versions to be purged from a node

Rename Simple renaming of a node

Rendition Triggers a rendition of the specified type

Reserve Allows a node to be reserved by the user running the WebReport


or optionally any other user that you specify a userid of

Unlock Allows a specific version of a node to be unlocked

Unreserve Unreserves a node

UpdateDescription Updates the description field of a node

Page 20 Advanced WebReports Workshop


NODEACTION & USERACTION Sub-tags

5.3 Using USERACTION


USERACTION has comparable options and behaves in a similar fashion to NODEACTION,
The difference being that it is used to perform bulk operations on users and groups.

USERACTION Option Description

Add Adds a user or group to a group

Delete Deletes a user or a group

Remove Removes a user or group from a group

Creategroup Creates a new group

Rename Changes a user login name or a group name

Advanced WebReports Workshop Page 21


NODEACTION & USERACTION Sub-tags

5.4 Exercises
5.4.1 Copying Content Server content

1. Create a new basic WebReport using the getReportData LiveReport.

2. Use INCLUDEIF to include only documents in the row section. (NODEINFO:SUBTYPE


will return the subtype of a node - documents are 144)

3. Add TOTALROWS and ACTUALROWS to the report to verify you are filtering on
documents. Run the report and check they return different values.

4. Use NODEACTION to copy only documents to your personal workspace

a. Look in the Tag Guide to get the NODEACTION syntax for COPY

b. Use the USERID tag in combination with the USERINFO sub-tag to get the objectid of
your PWS

5. Execute the report and check the items were added to your PWS.

6. Delete the new documents in your PWS

7. Modify the WebReport so that instead of using the USERID tag you use a user type
parameter for the ID of the user. On the parameters tab, give the parameter a default
value of your own user.

8. Run the WebReport again you should observe the same behavior

Note: By making the userid a parameter we can call this WebReport as a Sub WebReport any
number of times we want passing a new userid each time.

Another possibility is to change the destination of the WebReport so that it does the action
copy, move, delete, etc. then sends an email to the owner of the content informing them of the
action taken

Page 22 Advanced WebReports Workshop


Pre-defined Sort Parameters

6 Pre-defined Sort Parameters

6.1 Overview and Objectives


In this section we will explore some additional capabilities of the WebReports SORT content
control tag that were introduced with WebReports 5.0. Specifically we will learn about:

The concept of directives to add additional complex features

Predefining complex SORT keys so they dont have to be passed as URL parameters

Defining URL parameters that will be used to pass SORT information (removes the
need for WebReports parameter tags to be used as SORT keys

This feature allows complex sort keys to be associated with simple references that can be
passed in the URL. This feature is particularly useful when setting up reports that are sorting
using WebReports tags and sub-tags. When the user selects a column for sorting, it can be
difficult to pass the necessary tag syntax in the URL in order for the SORT tag to execute. To
solve this problem, this feature provides the ability to specify:

The name of one or more parameters that should be checked in the URL
A series of reference words and their associated tag syntax

When this is setup correctly, each specified parameter is checked to see if one of the
predefined reference words has been found. If a specified reference word is found in the URL
parameter then the corresponding syntax for this word is inserted into the SORT tag.

6.2 SORT Review


This Functionality is built on top of the existing SORT functionality and can be used in
conjunction with the original SORT functionality that existed prior to WebReports 5.0.

In order to demonstrate the new functionality and to understand some of the benefits it brings,
we will review some of the basics of the original functionality and how the new functionality
addresses some limitations of the original SORT tag functionality.

The basic sort syntax allows one or more sort keys to be specified as well as a sort direction.
E.g.:

[LL_WEBREPORT_SORT "NAME":DESC "DATAID":DESC /]

In this example the keys are specified directly by using the name of a column such as Name
or DataID. While this is useful, the more common case is that we need to run a WebReport
and specify (using a URL parameter) which column should be sorted. Currently we handle
this situation by using WebReports Parameter tags.

E.g.:

[LL_WEBREPORT_SORT "[LL_REPTAG_&sort /]":[LL_REPTAG_&direction /] /]

This technique is useful to make a SORT tag flexible enough that a WebReport can be re-run
multiple times using a different SORT order each time.

Advanced WebReports Workshop Page 23


Pre-defined Sort Parameters

Another common scenario is that we need to be able to sort according to the fully processed
output of a WebReports tag/sub-tag combination. In many WebReports there will be one or
more display columns that use WebReports to provide data that is not in the data source. For
example, if a data source only provides a list of data IDs. The WebReports sub-tag
NODEINFO could be used to return other pieces of information such as the item Name. E.g.

[LL_REPTAG=DataId NODEINFO:NAME /]

When used in a row section, this allows a WebReports developer to display data that does not
necessarily correspond with any column in the data source. This means that if we want to be
able to sort on this particular column, we need to be able to specify a SORT key in a similar
way. This is done like this:
[LL_WEBREPORT_SORT "[LL_REPTAG=dataid nodeinfo:name /]" /]

This example shows how we would setup a SORT tag to sort based on the output of:

[LL_REPTAG=dataid nodeinfo:name /]

Now if we extend the requirement to pass a sort key as a parameter, we need to be able to
pass syntax such as: [LL_REPTAG=dataid nodeinfo:name /] in a URL parameter. The SORT
tag syntax might look the same as our previous example but the problem is that we have to
pass a relatively complex set of characters in the URL. For example, our URL might look like
this:

&sortkey=[LL_REPTAG=dataid nodeinfo:name /]

There are ways of reducing the amount of tag that needs to be passed as a URL parameter;
however, in general this syntax is fairly verbose and in some cases, the need to include
special characters such as quotes in this syntax can actually cause a rendered WebReport to
fail with JavaScript errors.

This particular requirement is being addressed with the new SORT syntax.

6.3 New SORT Directives


The term Directive was introduced in WebReports 5.0 and is used in tags such as SORT
and INSERTJSON. It provides a way of specifying content control tags with multiple complex
parameters. For example, in the SORT tag, the directive @PARMNAMES can be used
multiple times inside the SORT content control tag. Typically a directive is specified with an at
sign @ and any information from the start of the directive until the next @ sign (or the
information ends) is considered part of that directive.

In order to provide the new functionality, two "directives" are provided that can be included
within the SORT tag. These directives are: @PARMNAMES AND @PREDEFKEY. These
directives are explained in depth in the next table.

Page 24 Advanced WebReports Workshop


Pre-defined Sort Parameters

Directive Description
@PARMNAMES One or more of these directives can optionally be
SORTCOL:<sortcolname> specified. If none of these directives are specified (and a
SORTDIR:<directioncolname> predefined key - as below - is specified) then it is
assumed that the parameters &sort and &direction will be
used to pass any sort or directional references. For each
@PARMNAMES directive that is supplied, an alternative
URL parameter name can be specified for either the sort
column or the sort direction. The ability to specify more
than one @PARMNAMES directive allows multiple sort
columns to be specified. These parameters are used in
the order of the @PARMNAMES directives specified in
the SORT tag. For example, given the following set of
directives:

@PARMNAMES SORTCOL:sortcol1 SORTDIR:dircol1

@PARMNAMES SORTCOL:sortcol2 SORTDIR:dircol2

@PARMNAMES SORTCOL:sortcol3 SORTDIR:dircol3

If the URL
contained:&sortcol3=parentid&sortcol1=Name&sortcol2=
dataid

The SORT would execute based on: Name, DataID and


then ParentID - in that sequence.

Note that normally the value of each of these parameters


will specify one of the predefined keys as setup by the
PREDEFKEY directive below.
@PREDEFKEY This directive is used to setup a simple identifier that can
be used to reference a complex tag/sub-tag type sort
REF:<reference key> key. This allows the client application to specify a simple
key as a sort parameter rather than a large chunk of
PARM:<tag/sub-tag syntax> WebReports tag and sub-tag information. For example, if
a particular column contains the following syntax:
[LL_REPTAG=DATAID CAT:somecat:attr1:DISPLAY /]
and we want to be able to sort using this data, we could
setup a key as follows:

@PREDEFKEY REF:col3
PARM:"[LL_REPTAG=DATAID
CAT:somecat:attr1:DISPLAY /]"

With this definition in place, &sort=col3 in the URL (or


POST request) would tell the SORT tag to use
[LL_REPTAG=DATAID CAT:somecat:attr1:DISPLAY /]
as a SORT key. Several such predefined keys can be
created, one for each and every column that could be
sorted. Usually this feature is only used where the sort
key is complex, such as in the example above.

Advanced WebReports Workshop Page 25


Pre-defined Sort Parameters

6.4 Exercises
6.4.1 Specifying Complex sort keys
1. Create a WebReport using the basic reportview and the simple List Docs with Category
data source
2. Change the last two columns so that they display two of the attribute values shown in the
graphic below (use the CAT: sub-tag)
3. For each column that displays an attribute, create a hyper link in the column name.
E.g. <A HREF="[LL_REPTAG_URLPREFIX /][LL_REPTAG_MYID LLURL:REPORT /]&mysort=col1">ColName1</A>

4. Create an empty SORT tag and then add an @PARMNAMES directive to ensure that the
URL parameter (mysort in the example) is recognized by the SORT tag. Specify a
direction parm name as well (although the hyperlink does not actually include any
direction parameters in the URL)
5. In this SORT tag, add two @PREDEFKEY directives so that when each column hyperlink
is activated, the correct tag/sub-tag syntax is executed. Hints:
Each hyperlink should specify a sort parameter and a unique (simple) value for that
sort parameter
The (two) PREDEFKEY directives should be used to map the unique value to
whatever tag/sub-tag syntax is required for the SORT to occur properly

Category Sample:

6. (Advanced) Add the JavaScript listed below and change the hyperlinks as per the
example so that selecting a column multiple times will reverse the direction of the SORT

<script>
var direction="[LL_REPTAG_&dirkey /]";
function doSort(colref) {
url = "[LL_REPTAG_URLPREFIX /][LL_REPTAG_MYID LLURL:REPORT /]";
url += "&sortkey=" + colref;
if (direction == "DESC") {
url += "&dirkey=ASC";
} else {
url += "&dirkey=DESC";
}
document.location = url;
// document.location.replace(url); // if different sort pages are not wanted in history
}
</script>
<A href="javascript:doSort(colname1);">col name1</A>

Page 26 Advanced WebReports Workshop


Initiating Workflows

7 Initiating Workflows

7.1 Overview and Objectives


Often administrators need to initiate a business process based on conditions found in the
Content Server database, search index, or other source of information. By using the
WebReports export to workflow feature a report can be executed on a predefined schedule
and a set of logical expressions evaluated allowing different business processes to be
selectively triggered.

By the end of the section you will be able to

Understand how to initiate a workflow from a WebReport

Be able to selectively initiate multiple workflows from a WebReport

Populate data in a form associated with a workflow

Populate data in attributes associated with a workflow.

7.2 Concepts
In order for a workflow to be triggered the developer must first set the destination tab of the
WebReport to point to the workflow requiring initiation. Below is a typical configuration

Remember from
WR Design I the blue
callouts provide inline help
for individual fields, the red
flags indicate support for
tag replacement and the
yellow exclamations
indicate mandatory fields.

Advanced WebReports Workshop Page 27


Initiating Workflows

In the above example the workflow specific field values can be described as follows

Field Description

1. Destination In order to trigger a workflow the destination field must be set to


workflow.

2. Initiate Map This is a browse field and must be set to the workflow that is to be
initiated. In the example above the standard browse has been
used to define the map. It is also possible to do this via a tag, for
example, a parameter of the form [LL_REPTAG_&MAPID /] could
be used and then passed at run time. The implication of this is that
you can use logic in the reportview to determine which map you
wish to initiate.

3. Workflow Title This is the title you wish to give to the initiated instance of the map.
As this field supports tags, the developer might, as in the example,
pass a parameter to dynamically provide all or part of the name.

4. Workflow Description The description of the instance of the triggered map. In the
example above you will note that the date is also being used as
part of the description.

5. Workflow Due This field determines when the workflow is due. In the example
above the workflow is due in two days. We could have specified
hours here by entering a fraction of a day. So, for example, 0.25
would mean the workflow is due in 6 hours. We could also enter a
fixed due date buy using the due on option.

6. Attach Output to Workflow This field determines whether the results of the report that
triggered the workflow are attached to the instance as a document.
This can be useful when person working on a workflow task wants
to see the reason or set of conditions that caused the workflow to
be triggered.

7. Attachment Name The name of the file to be attached to the workflow

8. Attachment Description As above but for the description

9. Attachment Categories As above but for categories associated with the attachment

10. Attachment MIME Type As above but for the MIME type

Tip: if you wish to populate a field based on more complicated calculations (as an example a
column total) it is possible to use WebReports variables to build the data then use a variable
tag in the appropriate field on the destination tab.

When this WebReport runs a single workflow will be initiated and the various pieces of meta-
data above will be auto populated at that time. This is illustrated below.

Page 28 Advanced WebReports Workshop


Initiating Workflows

LiveReport

Main Workflow
WebReport Instance
Results attached
Basic meta-data populated

Triggering a Workflow

7.3 Populating Workflow Attributes


At this point we are able to initiate a workflow but may want to populate attribute meta-data to
make the application more context-aware. As an example, a user attribute field might be
populated based on a userid found in the data source query. This, in turn, might be used to
assign the workflow to that individual in a future workflow step. Another possibility might be to
take category and attribute data from an existing node (see CAT sub-tag) and map this data
to workflow attribute values.

To set workflow attribute values we must define them in the reportview via the SETWFATTR
(SET WorkFlow ATTRibute) sub-tag. Example:

[LL_REPTAG_DATETIME SETWFATTR:INITDATE /]

The current date and time is returned from the main tag. SETWFATTR then takes this value
and maps it into the workflow attribute called InitDate.

Workflow attributes also support multi values which can be populated using the WebReports
MV operator and the optional ++ operand.

As an example, the File Owner attribute in the diagram above can be populated as follows

Advanced WebReports Workshop Page 29


Initiating Workflows

[LL_REPTAG=USERID SETWFATTR:MV:"File Owner" /]

This would insert whatever is in the USERID column for the current row into the first element
of the multi value workflow attribute File Owner. To populate the second and any subsequent
elements the ++ operand must be used. As an example,

Remember to use
quotes around field names
[LL_REPTAG_USERID SETWFATTR:MV++:"File Owner" /]
that contain spaces.

would insert the userid of the person running the report into the next element of the attribute
File Owner. By using ++ in this way it is possible to populate multi value attributes of any
length.

All fields that


require a user to browse for
an object or user/group
need to be provided with
the underlying objectid or
userid rather than the
object name/user name.
This is because Livelink
uses the id as the unique
identifier.

7.4 Populating Forms Within a Workflow


The SETWFFORM (SET WorkFlow FORM) sub-tag works similarly to SETWFATTR but
allows population of data in forms associated with a workflow rather than attributes. Syntax
for SETWFFORM is necessarily more complex than SETWFATTR because multiple forms
can be populated and each of these can support sets, multi-values, multi-value sets and
multi-values within multi-value sets.

The following series of image and tag examples relate to a workflow form called Allocations.
Unless otherwise stated, the image shows the field and the tag shows the syntax to populate
it.

7.4.1 Populating a Form Field

[LL_REPTAG_"TRUE" SETWFFORM:Allocations:"Approved" /]

In this example the SETWFFORM sub-tag is being used to set the Approved field for the
form called Allocations to the literal value TRUE which results in the field being checked.

Page 30 Advanced WebReports Workshop


Initiating Workflows

7.4.2 Populating a Multi-Value Form Field

1.5556

1.6667

1.8889

In order to set the above multi-value Cost Allocation field we need to use the MV operator:

[LL_REPTAG_"1.5556" SETWFFORM:Allocations:MV:"Cost Allocation" /]

The above statement will insert the literal 1.5556 into the first element of the multi-value field
Cost Allocation. To access any subsequent elements we must use the ++ operand. So,

[LL_REPTAG_"1.6667" SETWFFORM:Allocations:MV++:"Cost Allocation" /]

would insert the literal 1.6667 into the second element of the multi value field and then

[LL_REPTAG_"1.8889" SETWFFORM:Allocations:MV++:"Cost Allocation" /]

would insert 1.8889 into the third field.

7.4.3 Populating a Field in a Multi-Value Set

Microsoft On Hold

Oracle

Test

In this example we need to use the MVSET operator to index into the Competitors multi-
value set.

[LL_REPTAG_"Microsoft"
SETWFFORM:Allocations:MVSET:Competitors:Developer /]

[LL_REPTAG_"On Hold" SETWFFORM:Allocations:MVSET:Competitors:Temp /]

The two statements above would insert the words Microsoft and On Hold into the two fields
in the first element of the multi-value set.

SETWFFORM
does not output the results
directly to the report by
default. If you also want to
view the value that is being
set, use the optional
SHOW sub-tag.

Advanced WebReports Workshop Page 31


Initiating Workflows

In order to populate subsequent elements in the multi value set the ++ operand must be used.
As an example,

[LL_REPTAG_"Oracle"
SETWFFORM:Allocations:MVSET++:Competitors:Developer /]

would populate the second value in the multi value set if the statement was used after an
MVSET to populate at least one field in the first element (here the first one inserts the word
Microsoft). As the statement above has had the effect of incrementing the position in the set
to the second element we can use MVSET without the ++ operand to access the field, Temp,
at the current element index, or we can use MVSET++ and move on to the third element of
the multi value set without populating the Temp field.

[LL_REPTAG_"Test" SETWFFORM:Allocations:MVSET++:Competitors:Temp /]

In this example, because we have incremented the MVSET again, we are populating the third
element of the multi value set with the value Test.

7.4.4 Populating a Multi-Value Form Field in a Multi-Value Set

Populating a multi-value within a multi-value set can be considered a combination of the


previous two methods. Here we must specify the MV within MVSET.

March 15 2007

April 1 2009

No Test Info

The following statement has the effect of setting the current date into the first element of the
multi-value attribute Target within the multi-value set Inputs. In this case 15th March 2007.

[LL_REPTAG_DATETIME SETWFFORM:Allocations:MVSET:Inputs:MV:Target /]

This next statement increments the multi-value with the same element of the multi-value set
and inserts the date from the URL parameter called &date1. In this case the value in the URL
is set to 1st April 2007.

[LL_REPTAG_&DATE1 SETWFFORM:Allocations:MVSET:Inputs:MV++:Target /]

Finally this statement show the multi-value set being incremented and a value being inserted
into the Reasons field.

[LL_REPTAG_"No Test Info"


SETWFFORM:Allocations:MVSET:Inputs:MV++:Reasons /]

Page 32 Advanced WebReports Workshop


Initiating Workflows

7.5 Initiating Multiple Workflows


Until this point we have had a one-to-one relationship between the WebReport and the
initiated Workflow. The next step is to initiate multiple instances of a workflow whilst assigning
different values to attributes and form data for each of those instances. The best method to
achieve this is illustrated in the diagram below.

Sub Unlimited # of
Main
LiveReport
WebReport Workflow Instances
WebReport
Results attached
Workflow Dest.
Basic meta-data populated
Form data populated
Attribute data populated

Triggering multiple Workflows

You might want to


have a quick recap of
WebReports Design I
where we described the
use of sub-WebReports.

By breaking the problem down into a WebReport and sub-WebReport we are able to report
on all the data were interested in then pass a key as a parameter to a sub-WebReport. The
sub-WebReport has its output destination set to export to a workflow.

In the diagram above we might have the main report returning a list of Content Server dataids
that we want to perform some action on (e.g. theyre all to have an attribute assigned to them
that is in a particular condition). In this case we would want to pass the dataid to the sub-
WebReport and have the sub-WebReport trigger a workflow for that object. The main
WebReport (assuming all filtering etc. is done at the data source level) would simply consist
of:

[LL_WEBREPORT_STARTROW /]
[LL_WEBREPORT_SUBWEBREPORT NODEID:[LL_REPTAG_$SWR /]
PARM:INPUTLABEL1:[LL_REPTAG=DATAID /] /]
[LL_WEBREPORT_ENDROW /]

Here the call to the sub-WebReport is in the row section (between STARTROW and
ENDROW) which means it is called once for each row of data returned by the data source.
The sub-WebReport is defined as a constant called SWR and the column called DATAID is
passed to the sub-WebReport as the parameter inputLabel1.

The sub-WebReport can optionally have a data source that takes parameters and looks up
further information about the nodeid we have passed. The results of this can be used to
populate meta-data.

Advanced WebReports Workshop Page 33


Initiating Workflows

7.6 Exercises
Use export to workflow to trigger a workflow when a user has exceeded 500 bytes of space in
their personal workspace.

7.6.1 Initiating a Workflow


1. Create a new WebReport using the basic reportview and the LiveReport data source,
getDocs.
2. Go to the parameters tab of the new WebReport and define a default value for the user
parameter (Click the icon in the top right corner to auto-populate the parameter) then
set your user as the default value.
3. Go to the destination tab and set the WebReport to trigger the workflow map Reduce
Size of your PWS files located in the destinations folder.. Use tags to populate the
user name from the userid, passed in the inputLabel1 parameter, in the Workflow Title
field. After the user name, append a hyphen and the text you are over your size limit.
This should result something like student3 - you are over your size limit.
4. On the destination tab, set the output to attach to the workflow, provide it with an
appropriate name and mime type.
5. Run the WebReport and check that the workflow is triggered by looking at the status page
(from the function menu of the workflow map). Check that the results are attached with
the right name and open them to check there is a list of documents from the users
personal workspace.

At this stage we have initiated a workflow for the selected user and we have used parameter
tags to populate basic metadata in the workflow (the title).

7.6.2 Set Attributes in the Workflow


1. Create a constant called MAXSPACE to specify a value of 500. Use this constant to set
the Max Allowable PWS Size (Bytes) attribute.
2. Set the Current Date attribute with an appropriate value.
3. Use the inputLabel1 parameter to set the PWS Owner attribute
4. Finally, use WebReports variables to find the total size of all documents in the users
personal workspace (look at NODEINFO:SIZE:BYTES and ADDVAR) then use this value
to populate the Size of PWS (Bytes) attribute.
5. Run the WebReport and verify you see the results you expect in the initiated workflows
attributes.

Now were initiating a workflow and populating basic Metadata as well as attribute data using
a combination of parameters, tags and WebReports variables (where we need to calculate
values).

7.6.3 Conditionally call a Sub-WebReport


1. Create a second WebReport using the blank default reportview and set the data source to
use the LiveReport called overSizeUsers.
2. Edit the reportview to call a sub-WebReport passing it each of the userids (if you run the
LiveReport you will see it returns a list of userIDs) as parameters.
3. Put a WEBREPORT_INCLUDEIF statement around the sub-WebReport call so that only
the users who have over 500 bytes in use get a workflow triggered. Use a constant to
specify this 500 byte limit (similar to step 6). You can also use the Global Constant
feature to avoid duplicating this constant by referencing the constant in the first
WebReport

Page 34 Advanced WebReports Workshop


Ajax with WebReports

8 Ajax with WebReports

8.1 Overview and Objectives


Ajax (Asynchronous JavaScript and XML) is a method of interchanging information between
web-based applications. Some of its benefits include the ability to bring information to the
browser in small pieces, as the user requests it, and the ability to do this without redrawing
the entire page.

By the end of this section you will be able to

Update a Customview using Ajax or an IFRAME

Make use of the WebReports Ajax library

8.2 Displaying Reports in a Customview with an IFRAME


It has always been possible to use an IFRAME to run a WebReport within a customview. This
was and still is relatively easy to do by using the following HTML in a customview.

<IFRAME SRC="?func=ll&objId=xyz&objAction=RunReport"></IFRAME>

Where xyz is the object id of the WebReport you want to run in the IFRAME.

This method has some limitations but is simple and can be used to good effect. There are
two main limitations with this method

IFRAMES always return a string. This is difficult to parse when compared to Ajax
which can return an XML document.

Positioning and sizing within the page is not always easy and often results in
unsightly scrollbars appearing in document. Fixed result sizes are better to deal with
because you can determine the dimensions of the IFRAME in advance.

Note that for any submissions to Content Server that require a document upload (using the
TYPE=FILE form field) it is not possible to use AJAX to post this type of field. For these
scenarios an IFRAME would need to be used.

Use EXCLUDEHTML
to stop headers and footers
appearing in the IFRAME. This
is unsightly and also breaks
some of the Livelink menus

Advanced WebReports Workshop Page 35


Ajax with WebReports

8.3 Displaying Reports in a Customview with ajax.js


A more flexible approach than IFRAMES is to use the Ajax functions bundled with
WebReports. These functions allow calls to a WebReport from a customview or another
WebReport and use the returned data to dynamically update the current page.

WebReport Interacting with Customview

Customview
1. Request WebReport
<DIV ID=customView>

2. Returned Data

</DIV>

Page 36 Advanced WebReports Workshop


Ajax with WebReports

Below is a simple example of what might be used in a customview to dynamically update it


with information from a WebReport.

<SCRIPT SRC="/<your support dir>/webreports/library/ajax.js"></SCRIPT>

<SCRIPT>
updatePage( 1234, 'customView' );
</SCRIPT>

This code can be broken down as follows:

This example is designed to update an HTML DIV that is always added by Content Server as
part of any customview. This DIV has not been included in this example but is assumed to
exist in any customview. Any content in a customview is inserted into this DIV. In our
example we use Ajax to update the contents of this DIV dynamically. While this example is
using an existing DIV, you could just as easily create your own DIV with a unique name and
adapt this example accordingly.

It is not mandatory to
use a DIV, any HTML element
where the attribute innerHTML
is writable can be used.

This first line is a JavaScript include file reference that contains the code to make and return
the Ajax request. This JavaScript library is packaged with WebReports.

The tag
[LL_REPTAG_LIBPATH /]
returns the path to a folder on
the Livelink server which
contains the library file ajax.js.
However, because we are
referencing the include file from
a customview (not a
WebReport) we need to use a
qualified path. In a WebReport
we would only need the tag and
filename

The next reference is a call to the library function, updatePage(). This function takes two
parameters. The first is the object id of the WebReport we are using to retrieve the additional
data (If we had been making the call from another WebReport instead of a customview, we
could have used a WebReports constant which would resolve to an object id). It is also
possible to use a Content Server nickname instead of a literal object ID. The second
parameter is the id of the HTML element we wish to update - in this case we're updating a
customview and we know all customviews are wrappered by a DIV with id, "customView"; this
is the DIV that will be updated with any data returned by the WebReport that is being called
via AJAX.

Advanced WebReports Workshop Page 37


Ajax with WebReports

8.4 Inserting Context Sensitive Data into a Customview


Until now the information provided in the customview is dynamic but not context sensitive. We
now take this example a step further and make the information displayed in the customview
relevant to the current folder. By doing this we are able to use one centrally managed
WebReport to provide dynamic information which is specific to each folder.

An example of this could involve displaying each folders category information in its own
customview. To do this we need to pass an extra parameter to the WebReport so that we can
retrieve the category information relevant to the current folder. Here's an example of what the
updated call to updatePage() might look like:

<SCRIPT SRC="/<your support dir>/webreports/library/ajax.js"></SCRIPT>

<SCRIPT>
updatePage('nickname', 'customView', '&folderid=' + getURLParm('objid'));
</SCRIPT>

The difference between this and the previous example is a third optional parameter, folderid,
which can be used by the Ajax report to retrieve information specific to the folder we're in. The
function getURLParm() accepts a parameter name and returns the value that is associated
with that parameter in the current URL. In the example above we would end up with
something looking like updatePage('nickname', 'customView', '&folderid=5678' ).

Customview 1. Request
+ folderid
WebReport
<DIV ID=customView>
If folderid == x
process1
else
2. Returned Data process2
end
</DIV>

Page 38 Advanced WebReports Workshop


Ajax with WebReports

If you run the Ajax WebReport on its own, everything you see in the browser will be returned
to the main report. For this reason, remember to use [LL_WEBREPORT_EXCLUDEHTML /]
to turn off the standard Content Server headers, footers and include files.

Although we have called this an Ajax example, it is not true Ajax as there is no XML
component were returning plain text instead.

8.5 Dynamically Counting Filter Hits as the User Types


In this section we demonstrate a filter field that, as the user types, will be used to
automatically update a HTML element showing how many results to expect when the query
runs. This type of functionality is particularly useful when dealing with large result sets as the
user knows how many results to expect before issuing the query. It can also be a great time
saver where network latency is impacting performance.

Heres how it might look as the user is typing (observe the number at the bottom of each).

8.5.1 Creating a WebReport with XML Output

First, create a simple LiveReport (LiveReport Extensions must be installed) which counts the
number of matches for a given string. Something like:

select count(*) hits from DTree where Name like '%1%'

Define the parameter, %1, as type insertString. The LiveReport should prompt for user input
and count all items that start with the letters provided.

Advanced WebReports Workshop Page 39


Ajax with WebReports

Next add a new WebReport that uses the above LiveReport as its data source. Edit this
WebReport and create a simple XML schema so that you have something that looks like:

<?xml version="1.0" encoding="ISO-8859-1" ?>


[LL_WEBREPORT_STARTROW /]
<[LL_REPTAG_COLNAME1 /]>[LL_REPTAG=HITS /]</[LL_REPTAG_COLNAME1 /]>
[LL_WEBREPORT_ENDROW /]

When you create XML


WebReports it is critical that no
white space (this includes
spaces, tabs and carriage
returns) precedes the initial
declaration.

Set the WebReports Destination page set the mime type to text/xml so that we can make
use of the XML response when we call this WebReport. Now run the report in the browser
and verify that it runs with no errors.

The resultant document should look like:

<?xml version="1.0" encoding="ISO-8859-1" ?>


<HITS>16</HITS>

If the destination
mimetype is left as plain text or
html the
http_request.responseXML
object will not be properly
populated when the report runs.
This is in spite of the fact it
looks fine in the browser.

At this point we have finished the WebReport that will return the count information, now we
need to call this from where the user will run his query.

8.5.2 Calling a WebReport Using Ajax

Create a second LiveReport that returns a list of DTree items based on the first part of their
name (Like the LiveReport in 7.5.1, this requires an insertString parameter type). As an
example:

select * from DTree where Name like '%1%'

Page 40 Advanced WebReports Workshop


Ajax with WebReports

You will note that this is very similar to the previous query; the only difference being that we're
bringing back the data set rather than a count.

Finally, create a second WebReport and use the new LiveReport as the data source. Edit the
reportview so that you have something like:

<SCRIPT>
function updateHits( myFilter ) {

var url = '[LL_REPTAG_$AJAXWR LLURL:REPORT /]&inputLabel1=' + myFilter +


'&prompting=done';
if (window.ActiveXObject) {
http_request = new ActiveXObject( "Msxml2.XMLHTTP" );
}
http_request.onreadystatechange = function() { displayHits(); };
http_request.open( 'GET', url, true );
http_request.send( null );
}

function displayHits( ) {
if (http_request.readyState == 4) {
document.getElementById("hitsText").innerHTML = "Matches: " +
http_request.responseXML.childNodes[1].text;
}
}
</SCRIPT>

[LL_REPTAG_MYID NODEINFO:NAME /]
[LL_REPTAG_MYID LLURL:FUNCTIONMENU /]
[LL_REPTAG_MYID LLURL:UPALEVEL /]

<BR>

<INPUT TYPE=TEXT ID="MYFILTER" ONKEYUP="updateHits(this.value);">


<INPUT TYPE=BUTTON VALUE="Run" ONCLICK="document.location='[LL_REPTAG_MYID LLURL:REPORT
/]&inputLabel1=' + document.getElementById('MYFILTER').value">

<DIV ID="hitsText">Updates when you type</DIV>

<TABLE>
<TR>
<TD>[LL_REPTAG_COLNAME1 /]</TD>
<TD>[LL_REPTAG_COLNAME++ /]</TD>
<TD>[LL_REPTAG_COLNAME++ /]</TD>
<TD>[LL_REPTAG_COLNAME++ /]</TD>
<TD>[LL_REPTAG_COLNAME++ /]</TD>
</TR>

[LL_WEBREPORT_STARTROW /]

<TR>
<TD>[LL_REPTAG_1 /]</TD>
<TD>[LL_REPTAG_2 /]</TD>
<TD>[LL_REPTAG_3 /]</TD>
<TD>[LL_REPTAG_4 /]</TD>
<TD>[LL_REPTAG_5 /]</TD>
</TR>

[LL_WEBREPORT_ENDROW /]

</TABLE>

The interaction between the two WebReports is shown diagrammatically below.

Advanced WebReports Workshop Page 41


Ajax with WebReports

Main WebReport 1. Request +


users filter WebReport
<DIV ID=hitsText>
Produces
XML Doc

2. Returned Data

</DIV>

8.5.3 Component Review

Each time a user presses a key in the filter box a request is issued from the main report
(created in 7.5.2) asking for a new count from the Ajax report (created in 7.5.1). These
requests are very quick as there is no Content Server header, footer or other weighty data to
bring back across the network.

The main report uses a constant, AJAXWR, which needs to be defined on the constants tab
by setting the object type to Content Server and browsing for the Ajax report. Each time the
user clicks, it is the report defined on the constants tab that executes.

The main report also expects a parameter which, unless the report developer states
otherwise will cause a prompt when the report runs. The developer could, on the parameters
tab, enter the parameter name, inputLabel1 in this case, along with an empty default value
and the prompt field set to no. This will have the effect of causing all the results to be returned
initially. Obviously other values could be used although the developer needs to be careful how
many results will be returned when the user first runs the report.

All the code in this chapter has been cut down to a minimum to demonstrate principles and
techniques. It takes no account of error paths, browsers other than IE or Content Server
permissions. These things can all be easily added by the developer.

Page 42 Advanced WebReports Workshop


Ajax with WebReports

8.6 Calling a WebReports Service using AJAX

8.6.1 Service Request Syntax

Starting with WebReports version 5.0.0 there is a feature that allows WebReports sub-tag
processing to be invoked as a service. This feature is invoked using a unique URL as follows:

<prefix>?func=webreports.runservice&servicetype=<type><service specific parms>

The servicetype parameter currently supports the following types:

&func=webreports.runservice

&servicetype= Description/Parameters

gettagdata This service allows the execution of static tags and or sub-tags from the
WebReports engine to be invoked directly. This capability provides a way to
leverage the vast number of useful functions that are available through thie engine,
particularly with the ability to access the 60+ sub-tags and several static tags. Many
of the sub-tags provide the ability to access some useful Content Server functions
such as looking up categories and attributes, testing group membership and even
performing Content Server actions (subject to normal permissions controls).

This table illustrates the supplementary parameters that are used by this service.
Parameter
Mand- Description
Name
atory

TAGDATA YES (if no This parameter can be used to specify data to be operated on by
STATIC any specified sub-tags. If a statictag has also been specified, the
tag is tagdata will be ignored unless the static tag returns a blank
specified string. This allows the tagdata to be used as a default value for
or STATIC situations where the static tag doesn't return a useful value.
tag returns
an empty
string)

STATICTAG Yes (if This parameter can be used to specify one of a selection of
TAGDATA WebReports static tags that can be invoked. If the specified tag
is not returns a blank string, then the value of tagdata (if any) will be
specified) used instead, otherwise, the output from the statictag is used by
any sub-tags that have been specified. The static tag parameter
does not require the full WebReports syntax; only the static tag
name is used. For example, the [LL_REPTAG_USERID /] tag
would be invoked using:

&statictag=USERID
Note that WebReports services only supports a small subset of
the available static tags. In general, any static tags that are used
to return information about an executing WebReport will not be
valid as there is no WebReports object associated with a service
call. To find out which static tags are available, you can use the
liststatictags service type (described below).

Advanced WebReports Workshop Page 43


Ajax with WebReports

Specifies a list of sub-tags and their fields, just as they would be


SUBTAGS Yes
used in a WebReports reportview. E.g.

&subtags=NODEINFO:NAME UPPER

As with WebReports usage, these sub-tags are processed from


left to right with the output from the static tag (or the tag data)
being passed to the leftmost sub-tag.

Allows different formats to be specified for the data to be


RESPONSETYPE No
returned by a service request. Valid values are string, json or
(default is
xml. Assuming that a service has executed successfully (no
"string")
errors) and the service has returned the string: "This is a test",
the table below shows what each of the different formats would
return.

Format Example Mime Text Escaping


Type

string This is a test text/html No un-escaping


required
<?xml?>
xml <response> text/xml Content is HTML
<error> escaped. E.g.
false the character &
</error> = &amp; etc.
<content>
This is a test
</content>
</response>

json {"error":false, text/json If the content is


"content": text based (i.e.
"This is a test"} non-numeric and
enclosed in
quotes)
conventional
string escaping
is used. E.g.
back slashes (\)
are used before
any special
characters. See
the JSON
standard (RFC
4627) for more
details on
string/text
escaping.

This service returns all appropriate static values from the WebReports engine in a
getstatictags
data structure according to the responsetype parameter; however, only the json
responsetype is currently supported. Static tags are all of the tags in the
WebReports tag guide that come under the heading of "data tags" and which have
fixed names such as: [LL_REPTAG_DATETIME /].
This service provides a simple list of all the static tags that are available for usage in
liststatictags
the gettagdata and getstatictags services. It is primarily used for the convenience
of developers.

Page 44 Advanced WebReports Workshop


Ajax with WebReports

8.6.2 Using the Predefined JavaScript Function from ajax.js

The ajax.js file packaged with WebReports includes a function designed to aid in the use of
WebReport services in conjunction with AJAX technology. The ajax.js file is accessed using a
SCRIPT include like this:

<SCRIPT SRC="/<support dir>/webreports/library/ajax.js"></SCRIPT>

If this file is being included into a WebReport or ActiveView the LIBPATH tag can be used like
this:

<SCRIPT SRC="[LL_REPTAG_LIBPATH /]ajax.js"></SCRIPT>

This table describes the pre-defined function and its parameters.

executeWRService( serviceType, responseTarget, parmList, responseType, getPost)

servicetype Mandatory This parameter expects a string with one of the supported
servicetypes for running a WR service (as specified in the table
above).

responseTarget Mandatory This parameter expects either a JavaScript function that has
been created by the developer, or a string representing the ID
of an HTML object where the returned data should be inserted.
If a JavaScript function is created (and passed to this
parameter) it should be written to accept the http_request as a
parameter. For example:

function myHandlerFunction(httpRequest) {
alert('the response was: '+
httpRequest.responseText);
}

executeWRService( 'gettagdata', myHandlerFunction,


"&statictag=userid &subtags=USERINFO:GROUPID",
'json')

parmList Optional This parameter is used to specify a string containing additional


parameters to be added to the URL as required by each
servicetype. For example, the gettagdata service type uses a
combination of &tagdata, &statictag or &subtags as per the
syntax in the table above. The parms should be specified in the
&name=value type format. E.g.
"&tagdata=12345&subtags=CAT:myCategory:attr1:display"

getPost Optional This parameter can be used to specify whether the AJAX
request should be GET or POST. If omitted, the POST method
is used.

Advanced WebReports Workshop Page 45


Ajax with WebReports

8.7 Exercises
8.7.1 Creating a Dynamic PWS page

1. Create a basic WebReport that uses the LiveReport getMyLastLogin as a data source

2. Note that the data source returns two rows. Find a way to only display the last row (the
second most recent login) in the WebReport.

3. Change the formatting of the AuditDate column to be more user friendly. Use the DATE
sub-tag to achieve this.

4. Edit the reportview so that you have a WebReport that returns My Last Login Was:
<date>

5. Create a Customview in your personal workspace and call the WebReport using the ajax
library.

6. Open your personal workspace - notice you have two sets of Content Server headers and
footers. Edit the WebReport to exclude all the Content Server wrapper HTML

Consider how you might put a copy of the Customview into the personal workspace of every
user in a Content Server system.

8.7.2 Creating a Sub-tag Lookup Tool

This exercise can be completed using information from the WebReports online help,
Advanced Information->WR Services, example 1.

1. Create an HTML Text input field that allows a static tag name to be specified. E.g.:

Static Tag: &nbsp;<INPUT TYPE=TEXT ID="statictag" NAME="statictag">

2. Create an HTML Text input field that allows a list of sub-tags to be specified. E.g.:

Sub-tags: &nbsp;<INPUT TYPE=TEXT ID="subtags" NAME="subtags">

3. Create an HTML DIV field that can be updated with returned information from a
service call. Give this DIV a unique ID.

Response: &nbsp;<DIV ID="response"></DIV>

4. Create a JavaScript function that will initiate a WebReport service to return


information from Content Server (using the static tag and sub-tags from the form
fields). Setup this service call so that the DIV created in step 3 will be populated by
any returned results. This approach means that we will use a responsetype of
string.

5. Create a button that will trigger this JavaScript function. E.g.:

<INPUT TYPE=BUTTON VALUE="Submit" ONCLICK="submitRequest();">

6. Test the service using something like this: statictag USERID, subtags
USERINFO:FULLNAME

Page 46 Advanced WebReports Workshop


Data Source Parameters

9 Data Source Parameters

9.1 Overview
WebReport data sources (LiveReports, Search Queries, Forms, etc.) can be manipulated
using special parameters called data source parameters. These parameters are passed in the
URL when a WebReport is executed and control things like the maximum number of results
on each page:

Parameter Name Description


This parameter allows an alternative data source to be specified as a
Sourceid dataid. The dataid must correspond with one of the node types which
are currently supported by WebReports as data sources.
This parameter allows the starting row from the data source to be
specified using a number from 1 to N. This means that any rows prior to
the specified DSstartrow will not be used in the report. For example if
DSstartrow the data source normally had 100 rows of data and a DSstartrow of 21
was specified (without any DSendrow or DSmaxrows parameters),
then only rows 21 through 100 would be used. This parameter can be
combined with the DSendrow or DSmaxrows parameters.
This parameter allows the last row from the data source to be specified
using a number from 1 to N. This means that any rows after the
specified DSendrow will not be used in the report. For example, if the
data source normally had 100 rows of data and a DSendrow of 75 was
specified (without any DSstartrow or DSmaxrows parameters), then
only rows 1 through 75 would be used. This parameter can be used with
the DSstartrow or DSmaxrows parameters. When used with the
DSendrow DSmaxrows parameter, whichever parameter results in the most
limited set of data, will have precedence. For example, given the
parameters: DSstartrow=1, DSendrow=75 and DSmaxrows=20, only
rows 1 through 20 would be used. Given the parameters: DSstartrow=1,
DSendrow=20 and DSmaxrows=100, only rows 1 through 20 would be
used. If this parameter is specified as a negative number then zero (0)
rows are returned. If this parameter specifies a row number less than
the DSstartrow parameter then zero rows are also returned.
This parameter specifies the maximum number of rows to be used from
the data source using a number from 1 to N. This means that there will
never be more rows than the number specified in DSmaxrows. As
described for DSendrows, DSmaxrows specifies a maximum number
DSmaxrows
of rows but the actual number of rows may be less than DSmaxrows if
the DSstartrow and DSendrow parameters combine to specify a
smaller set of data. If this parameter is specified as a negative number
then zero (0) rows are returned.

Example of URL invocation:

?func=ll&objId=1234&objAction=RunReport&sourceid=12345&DSstartrow=11&DSendr
ow=100&DSmaxrows=50

In this example, the data source identified by nodeid 12345 will be used to supply data for the
WebReport. The data used will end at row 50 (despite the DSendrow parameter being set to
100) because the DSmaxrows parameter is set to 50.

Advanced WebReports Workshop Page 47


Data Source Parameters

9.2 Request as a Data Source - Parameters


Parameter Name Description
This is the parameter that contains the data that will be used by the
datasource. For any of the optional parameters that have not been
specified, defaults are used. The data in this parameter would normally
be formatted in a way that can be interpreted by the WebReport, e.g.
DSrequestData Comma Separated Values (CSV) or HTML table data. If no optional
parameters have been specified, the data is expected to be formatted
as CSV. The optional parameters can be used to specify any
differences in the parsing format. A common variation would be to use a
symbol such as | as the row separation character.
Acceptable values are: separatedvalue (default), htmltable. This
DSfileType parameter specifies how the data has been formatted and therefore how
it should be parsed.
Only appropriate for a filetype of separatedvalue. Acceptable values
are: somequotes (default), allquotes, noquotes. These settings refer to
DScontentType whether or not some of the data cells might be quoted to hide
characters that might interfere with parsing. If none of the cells are
quoted, a setting of noquotes provides faster processing.
Set to either true (default) or false. True specifies that the data has been
DSstrictSyntax strictly formed with no unexpected spaces or other ambiguous white
space.
Specifies a character or characters that are used to delimit (separate)
DScolumnSep
columns of data. Defaults to , (comma).
Specifies a character or characters that are used to delimit (separate)
DSrowSep
rows of data. Defaults to a carriage return followed by a line feed.
Specifies which character or characters have been used to quote cells
DSquoteChar
(if any). Defaults to "
Specifies which character or characters are used to escape any quotes
DSescQuoteChars
in the cell data (if any). Defaults to ""
Specifies true or false depending on whether the first row of data
DSheadingsInc includes heading names for each column. Defaults to true. If set to false
columns are automatically named as column1, column2, etc.

Page 48 Advanced WebReports Workshop


Data Source Parameters

9.3 Example
1. Create a new WebReport and name it Display request data with no data source and
the basic_report reportview

2. Create a new WebReport and name it Application with no data source and the
blank_report reportview

3. Add a LivelinkObject type Constant to the Application WR and select the Display
request data WebReport for constant value

4. Edit the Application ReportView; add delimited text in a textarea box; with two input
fields for Row Separator and Column Separator. Add a submit button that will call a
javascript function in the report header. The javascript will retrieve the form data and
send a request to Display request data WR, using the DSRequestData, DSRowSep
and DSColumnSep parameters

9.4 Exercises

9.4.1 Passing SourceId as Parameter

1. Create a new WebReport and name it Target Listing Report with no data source and
the basic_report reportview

2. Create a new WebReport and name it Selection Report with no data source and the
blank_report reportview

3. On the Constants tab of the Selection Report, add three LivelinkObject type
constants. The first constant will reference the Content Server User List document
in your Data Sources folder. The second constant will reference the Content Server
Doc List document in your Data Sources folder. The third constant will reference the
Target Listing Report WebReport

Edit the Selection Report reportview and create two hyperlinks. Using the constants above,
each hyperlink should call the Target Listing Report WebReport with objAction=RunReport
and pass in the sourceId parameter to reference each of the document constants.
Example:

<a href="?func=ll&objId=[LL_REPTAG_$targetWR
/]&ObjAction=RunReport&sourceid=[LL_REPTAG_$DocList /]" target="_blank">Open
the Document Listing Report</a>

4. Modify the URL to use URLPREFIX and LLURL WR tags for WebReport call:

5. Experiment with passing DSStartRow, DSEndRow and DSMaxRow parameters, as


well

Advanced WebReports Workshop Page 49


WR Trigger

10 WR Trigger

10.1 Overview
The WR Trigger feature allows WebReports to be initiated by specific events in Content
Server. For node types that have been enabled with the feature, which is off by default and
can be enabled per node type in the administration pages under WR Trigger Administration,
the WebReport developer can choose to initiate a WebReport for the following Content Server
events:

Add Version

Category Update

Create

Delete

Move

Update

10.2 General Usage


The feature is accessed via a new WR Trigger option in the properties section of the function
menu, which brings up a new tab. The menu and subsequent tab can only be accessed for
subtypes that have the WR Trigger feature enabled. Triggers can be set on individual objects
or they can be set on containers and cascaded down a hierarchy, which provides a
convenient way to set triggers on a large volume of items.

When an item is "Deleted" using the function menu one of two things can happen. The item
might be truly deleted and so completely removed from the database, or the item might be
moved to the Recycle Bin or Undelete Volume. The behavior will depend on how specific
subtypes (Documents vs. Folders etc.) are configured with these modules. The Delete trigger
only fires on a true database delete - i.e. when items are destroyed. If it is required to trigger a
WebReport based on a "function menu delete" that results in the item being moved to the
Recycle Bin or Undelete Volume, the Move trigger event must be used. Logic can then be
used in the WebReport (simply use NODEINFO:PARENTID /OWNERID) to determine
whether the item was moved to one of these locations or elsewhere in Content Server.

When a root node (a container with other items in it) is copied, moved or deleted, the trigger
occurs on the root node only. No WebReport will be initiated for individual sub items. If a
WebReport needs to be initiated for each specific item, it can be achieved using a query that
takes the node that initiated the trigger to find all the children, then use a subWebReport to
implement the specific behavior - e.g. trigger a workflow.

All triggers are initiated after the event has occurred with the exception of Delete. For
example, if using [LL_REPTAG_TRIGGERID NODEINFO:PARENTID /] in a WebReport that
has been initiated by a Move trigger event, the objectid of the new parent will be returned (see
[LL_REPTAG_TRIGGERORIGPARENTID /] for accessing the original). With the delete
trigger, the event is fired just before the delete so that we have the maximum meta data
available. Once a node is truly deleted, it no longer exists and so has no valid meta data.

Page 50 Advanced WebReports Workshop


WR Trigger

When a document is added to Content Server, both the Create trigger and the Add Version
trigger are fired. This is because Content Server sees this as two actions. First a node
creation occurs and once the node is created a new version (in this case version 1) is added
to that node. If a folder were added, only the Create trigger would fire.

10.3 WR Trigger tags


WR Trigger supports the following feature specific tags which are detailed in the tag guide:

[LL_REPTAG_TRIGGER /] the name of the trigger being processed

[LL_REPTAG_TRIGGERID /] The ID of the node that has triggered

[LL_REPTAG_TRIGGERNEWID /] The ID of any new node created

Advanced WebReports Workshop Page 51


WR Trigger

10.4 Exercises

10.4.1 Initiate Workflow with WR Trigger

Initiate a workflow and attach a document to it when a new item is created in a folder with a
WR Trigger applied.

1. Create a new WebReport and name it Item Created WR, with No Data Source and
Basic ReportView. Set the Destination of the WR to your workspaces
DestinationsWorkflow to be initiated by a trigger.

2. Edit the WebReport ReportView and add the following line in either the Header or Footer
section:

[LL_REPTAG_TRIGGERID SETWFATTACH:COPY:INHERITATTRS:MERGED /]

NOTE: TRIGGERID is the id of the object that initiated the event and
SETWFATTACH:COPY:INHERITATTRS:MERGED copies this node to the attachments folder
merging the categories of the node with those of the attachments folder.

3. Create a new Folder and name it Folder With Trigger

4. Select the WR Trigger tab (Properties WR Trigger) on the new folder. Select the
Create Event; choose this node and all children as Inheritance option; and select the
WebReport above.

5. Add a new document to the folder

6. Check your workflow assignments

Note: Rather than initiating a workflow, the WebReports destination tab could be set to send
an email. To attach the item that fired the event to the email destination use
[LL_REPTAG_TRIGGERID /]. It's worth noting that SETWFATTACH and SETEMAILATTACH
can be used multiple times to attach several items to the destination.

Challenge Questions

1. Why did you use the Header or Footer section of the ReportView and not the Row
Section?

2. Go back to the WR Trigger tab on the folder and check the Show WebReport checkbox
for your trigger event. What do you think will happen when you run the report again?

Page 52 Advanced WebReports Workshop


WR Power View

11 WR Power View

11.1 Overview and Objectives


WR Power View is an option available for form templates that allows developers of
WebForms to quickly leverage WebReports' unique ability to lookup and manipulate data from
different sources but in the context of a form.

By the end of this section you will be able to

Add a WR Power View to a form template

Understand the benefits of using a WR Power View over a standard form view

11.2 Adding a WR Power View


Forms developers are presented with the option to add a WR Power View to a form template
in addition to the traditional HTML view. The option is shown in the image below:

From the form template function menu select "Export as HTML" then save the file to
your desktop.

Go to Properties - Views tab of the from template and select "Add View" followed by
"WR Power View".

You are now presented with the regular add WebReport interface. When selecting
the reportview browse for the file saved to your desktop in the first step.

Open the WebReports tag guide and start making immediate use of the 100+ tags
inside your form view.

WebForms module
must be installed for WR Power
View to be selectable.

Advanced WebReports Workshop Page 53


WR Power View

11.3 Benefits of WR Power View


A WR Power View behaves in a similar way to an HTML view with the following useful
additions:

Native support for existing form tags like [LL_FormTag_1_1_2_1 /] and [LL_FUNC /]
meaning that WR Power Views are backwards compatible with HTML views.

Full support for WebReports static tags, constants and parameters which can be used
together with form tags.

Ability to call an unlimited number of WebReports (through sub-WebReports calls)


inside the view enabling dynamic population of lookup fields from data sources both
inside and outside Content Server.

Ability to apply a WR Data Source enabling you to include dynamic data to your form
display.

Ability to apply a WR Destination.

Select a WR Power View for a workflow form and use WebReports parameter tags,
[LL_REPTAG_& /], to access information about the executing workflow (e.g. workid,
subworkid, taskid, mapid) then use these to lookup further information specific to the
current step, user or workflow instance.

Below is an example of what you might use WR Power View to achieve. Its an example of a
forms step in a workflow that is being used to re-skin a whole section of workflow functionality.

11.4 WR Power View Usage


A WR Power View can be configured to process forms tags in two ways

Page 54 Advanced WebReports Workshop


WR Power View

Allow the forms module to process forms tags and the WebReports engine to process
the WebReports specific tags. This is default behavior and no action is required to
enable it.

Allow the WebReports engine to process both forms and WebReport tags. To enable
this functionality the [LL_WEBREPORT_FORMPARSEOFF /] tag must be included in
the reportview.

[LL_WEBREPORT_FORMPARSEOFF /] should be used when writing reports that have


contain multiple forms like in the screen shot shown in 11.3 because the forms code is not
designed to handle this type of parsing. In this mode WebReports will process all the basic
forms tags but is unable to deal with more complex processing like form loops and multi-
values. These situations can be remedied by using WebReports tags to achieve the
equivalent functionality. Using this mode the forms code will also no longer modify any HTML
code in the Power View. For example, forms code normally sets the default value for SELECT
form fields. When standard forms parsing is turned off, any forms tags are resolved but the
responsibility for setting up any HTML components lies with the developer of the Power View.

If allowing forms to
process a reportview with more
than one form various
behaviors up to as extreme as
SNDR (Server Did Not
Respond) may be observed

WebReports provides several sub-tags which are very useful in the context of workflow forms.
These are

Sub-tag Description

WFFORM Allows access to information in form package of the executing


workflow. Can access both sets and multi-values

WFATTR Allows access to information in the attribute package of the


executing workflow. Can access both regular and multi-value
attributes

WFINFO Allows access to various elements of workflow meta data including


the dataid of the attachments folder (this is useful for passing to a
sub WebReport to allow it to report on the contents of the
attachments folder)

These sub-tags are useful because they all take a subworkid id as an input and use that to
access meta data in the executing workflow. The key to this is knowing that the subworkid is
a parameter in the URL when looking at a WR Power View step. With this knowledge much
of the data in the workflow is accessible. E.g.

[LL_REPTAG_&SUBWORRKID WFINFO:ATTACHMENTFOLDER /]

Advanced WebReports Workshop Page 55


WR Power View

Tip: if you need to apply a WebReports sub-tag to a form tag, put the form tag inside a
WebReports literal tag to exploit the processing order. E.g.

[LL_REPTAG_[LL_FORMTAG_1_1. /] UPPER /]

11.5 Exercises

11.5.1 Adding a Power View to Content Server WebForms

In your 11.5.1 Exercise folder, you will find four prepared items:

Contract Submission Process Workflow Map

Contract Submission Template Form Template

Folder Content Display WebReport

Power View (html document that will later be used as your Power View)

You will create a PowerView as a View on the Form Template and create a new Form that will
use that View to submit form data.

When editing the form, you will select a Contract Type which will invoke a call to the Folder
Content Display webreport and pass in a sourceid value of a folder that contains the documents
for the selected contract type. You will then select a particular document template and the id will
be stored in the form data.

Lets get started

1. Download the HTML document named Power View and save it to your desktop

2. From the Contract Submission Template function menu, select PropertiesViews

3. From the Add View menu, select WR Power View. Name the View CS Initiation
Power View and Browse to select the Power View html file you saved to your desktop.
Without selecting a data source, select the Add button to create the View.

4. From CS Initiation Power View function menu, select PropertiesConstants

5. Extract the Constants from the content (blue down arrow icon on right)

6. Update the Constants as defined in the table below:

Name Value Type Description

RetrieveDataMsg Retrieving Data String Message


displayed when
list of docs is
refreshed

FolderContentsWR Browse to select LivelinkObject The Folder

Page 56 Advanced WebReports Workshop


WR Power View

the Folder Content Display


Content Display WebReport
WebReport in
your Exercise
11.5.1 folder

ReportTitle Contract Library String The Report Title

FinanceContractsFolderId Browse to find the LivelinkObject The Contracts -


Contracts Finance Data
Finance folder in Source Folder
your Data
Sources folder

HRContractsFolderId Browse to find the LivelinkObject The Contracts -


Contracts HR HR Data Source
folder in your Folder
Data Sources
folder

7. Select the Update button to save the Constants; then return to the Exercise folder

8. From the function menu of the Form Template, select Make Form

9. Make a new Form named Contract Submission Form. For now, select Livelink
Versions for both the Revision and Submission Mechanisms and select Continue button

10. Select the CS Initiation Power View as the Custom View and Add

11. Run the Contract Submission Form and toggle between the two contract type radio
buttons

Challenge

1. Modify the Form to submit to the Contract Submission Process

2. Modify the Contract Submission Process workflow form step to use a form with
Power View

Advanced WebReports Workshop Page 57


Administration and Debugging

12 Administration and Debugging


12.1 Overview and Objectives
This section contains information useful to the administrator when initially configuring
WebReports or when debugging WebReports.

By the end of this section you will be able to


Understand the available WebReports opentext.ini settings and know when to apply
each
Understand the tags which can assist in debugging either a problem with WebReports
or a problem with a given reportview
Know what information to send to the WebReports team when opening a bug or
requesting assistance

12.2 Configuring opentext.ini


The settings below are all available WebReports opentext.ini settings. They are used to
control a wide variety of things from presentation to security.

Field Name Type Description

Determines the optional columns available to WebReports


that use search data sources. Possible values include:
OTHotWords, OTSummary, parentRecord, Score,
shortOTSummary. These can be specified as strings within
a list or as a list of two element lists where the first element
List of strings
additionalSearchColumns is the column coming back from search and the second
or list of lists
column is what you want it to be called in the output. It
should be noted that these values are made available via
the search index. If the underlying structure of the index
were to change in future releases, these columns may no
longer be available.

Describes the label used for the button to launch a


WebReport from Content Server search. This should be
addSearchButton String or null set from the Admin pages in Content Server. Please refer
to the WebReports User Guide for more detail about this
feature.

Control whether WebReports can be added to form


templates as views. This feature is visible by navigating to
allowFormCustomview true / false the views tab of a form template. The options Add WR
Power View will be present if the feature is enabled. The
feature is enabled by default.

Specifies the output directory for a converter (e.g. AdLib


conversionDir String dir path eXpress). This should be changed via the Manage
WebReports Conversion administration page.

This the MIME type of the output that will be created by


WebReports. Depending on client settings this can
destinationMimetypes List of strings
determine what application is used to open the resulting
document.

Page 58 Advanced WebReports Workshop


Administration and Debugging

Enables or disables the WR Services feature. WR Services


disallowServices true / false
is enabled by default.

Controls whether Oscript is permitted within reportviews.


Default is true. When set to false no oscript within any
reportview will be compiled or executed. This turns the
enableOscriptReportviews true / false
scripting feature off completely on the Content Server
server. Please refer to the WebReports User Guide for
more detail about this feature. True by default.

This character is used to separate multivalue attributes in


livelinkCategory_attrDelimiter String
the output from the category as a data source feature.

Defines the maximum number of categories selectable via


livelinkCategory_maxNumCats Integer
the category as a data source feature.

Controls the maximum number of results that are retrievable


livelinkCategory_maxNumRows Integer
from the category as a data source feature.

Defines the maximum number of attributes that should be


livelinkCategory_numAttrAcross Integer displayed on a single line from the category as a data
source feature.

Controls the upper limit of how deep sub-WebReports may


maxNestedSubWebReports Integer
be nested. Default value is 5 if this field is absent.

A list of individual oscript package functions to be permitted


oscriptAllowFunction1 List of strings within a reportview. Please refer to the WebReports User
Guide for more detail about this feature.

A list of oscript packages to be permitted within a


oscriptAllowWholePkg List of strings reportview. Please refer to the WebReports User Guide for
more detail about this feature.

Turns on extra debug information in the thread log for


searchDebug true / false executing WebReports with search as a data source. False
by default.

Determines a maximum limit on the number of results that a


searchHardLimit Integer WebReport using search as a data source can return.
Default is 50,000.

Determines how many results are to be gathered in go from


the search API. Changing this setting will have an impact
searchSlice Integer on performance of WebReports that use search as a data
source. In general this setting should not be altered without
advice from OpenText support. Default is 300.

Specifies the input directory for a converter (e.g. AdLib


versionInput String dir path eXpress). This should be changed via the Manage
WebReports Conversion administration page.

Determines the list of MIME types that a WebReport node


itself may be set to. Effectively this is the MIME type of the
WRNodeMIMETypes List of strings reportview. Normally WebReports are assigned the
text/plain MIME type, but sometimes it may be useful to
permit text/html or other MIME types.

Advanced WebReports Workshop Page 59


Administration and Debugging

Controls the sub-types that are able to initiate WebReports


WRTriggerSubtypes List of integers from the WR Trigger feature. All sub-types are disabled by
default.

12.3 Tags for Debugging


The following table illustrates the tags that most useful for debugging in WebReports

Tag Description

[LL_WEBREPORT_SUPPRESSERRORLOG /] Prevents any run time errors being displayed

[LL_WEBREPORT_DEBUGON /] Turns off syntax validation when a WebReport is


added

[LL_WEBREPORT_DBCACHEOFF /] Turns off caching of any functions that need


database information

[LL_WEBREPORT_SUBVERSION /] Displays the exact version of WebReports being


used

[LL_WEBREPORT_DISPLAYTIMING /] Displays timing information for a WebReport in its


output

[LL_WEBREPORT_HIDDENTIMING /] Adds HTML comments with timing information in


the display output

12.4 Debugging Tips


When collecting information to open a WebReports ticket there are several pieces of
information that the support team will need:

Content Server version

Database type (Oracle or SQL Server) and version

WebReports version and patch level

From WebReports 4.0.0 onwards all this information, and a lot more, can be collected by
issuing a WebReports specific sysreport using the following URL.

?func=webreports.sysreport

Send the output of this to support when opening the ticket.

If working on an earlier version of WebReports where this functionality is not available, or


simply wishing to collect the information manually, [LL_WEBREPORT_SUBVERSION /]
should be used to determine the exact version of WebReports and its patch level.

Page 60 Advanced WebReports Workshop


Administration and Debugging

Debugging Step Description

Verify the data source Try running the data source (e.g. Search Query, or
LiveReport) on its own. Do you get the expected
results?

Simplify the destination Does the report work when running the output to the
browser? Make sure this works before sending report s
to more exotic destinations like forms and workflows.

Upgrade to latest version If possible upgrade to the latest version of WebReports.


If a problem is found and patched the first version of the
patch will generally be for the latest version of
WebReports.

The two most common mistakes when reporting WebReports bugs are:

Reporting an issue that is already patched

Upgrading to a new version of WebReports and leaving a patch in the patch folder
that relates to the old version of WebReports

WebReports patches can be found here:

https://knowledge.opentext.com/knowledge/llisapi.dll/open/3945818

Advanced WebReports Workshop Page 61


Help!

13 Help!
There are several resources to be aware of that can be very useful when working with
WebReports:

Resonate KT Support and Knowledge Base:

http://www.resonatekt.com

http://www.resonatekt.com/support.htm

Download soft-copies of this and other Resonate KT training manuals:

http://www.resonatekt.com/training.htm

OpenText Knowledge Centre:

WebReports Discussion:

https://knowledge.opentext.com/knowledge/llisapi.dll/open/WebReportsDiscussion

WebReports Documentation:

User Guide

Admin Guide

Release Notes

https://knowledge.opentext.com/knowledge/llisapi.dll/open/17655534 (v5.1.0)

Online Help:

From Content Server, select Help -> Contents -> WebReports +

Detailed Examples worked examples for Pagination, Cats & Atts, AJAX.

Advanced Information big list of advanced topics discussed in detail.

Page 62 Advanced WebReports Workshop


Appendix - LiveReport Extensions SQL Templates

14 Appendix - LiveReport Extensions SQL Templates

14.1 Overview and Objectives


LiveReport Extensions provides a convenient mechanism for building dynamic SQL
statements without the risks associated with SQL injection.

The template feature allows optional SQL clauses to be predefined in the LiveReport. Each
template is created so that only the pieces of data that need to be variable are passed as
parameters. Each template may be configured so that a predetermined condition must be
met in order for the template to be included.

Templates are useful when creating ad-hoc reporting tools where the ability to dynamically
add or remove filters or change the data set is important.

By the end of this section you will be able to

Create a LiveReport that makes use of templates

Understand the benefits of templates compared to SQL injection

Advanced WebReports Workshop Page 63


Appendix - LiveReport Extensions SQL Templates

14.2 Template Fields


A template with no data:

Additional templates
can be created using the
icon. Templates can be
removed by clearing any text in
the SQL source box and saving
the LiveReport.

Description of available fields

Field Description

# Shows the unique reference which is used to insert a template in the


main SQL query or within other templates. The tilde symbol (~) is used to
indicate where the template is to be inserted

Auto-Where Checking this box will automatically add the correct filter word (either
WHERE or AND or OR) to the beginning of a template

SQL Source The statement which will optionally be added to the SQL

Auto Comma Ensures that any comma separated variables (e.g. %1, %2, %3) have the
correct number of commas in place after the variables have been
resolved

Include IF The conditions for template inclusion are selected using this option

Possible values for the Include IF field

Include IF Value Description

Mandatory (no The template will always be inserted when this option is selected. This
condition) option is useful for breaking the SQL down into smaller pieces

URL Parameter This option specifies that this template will be inserted if a named
parameter is found in the URL

No Inputs set to The template is only included if none of the values in the user inputs

Page 64 Advanced WebReports Workshop


Appendix - LiveReport Extensions SQL Templates

flag are set to the flag value

Not all inputs set Similar to the previous option the template will be included, unless all
to flag input values have been set to the specified flag

Template The template will be included based on whether another template


condition true evaluates to true or not

Template The template will be included based on whether another template


condition false evaluates to false or not. This is useful when two templates are
mutually exclusive

For any template the


view template feature can be
used to help explain how the
template will behave. This
feature is accessed using the
icon.

14.3 Using URL Parameter


The URL Parameter condition is used to specify the name of a parameter in the URL that will
cause the template to be inserted. The simplest operation might be &someparm=true.

14.3.1 Adding an Order By Clause


This is an example of a template with a fixed ORDER BY clause that will be inserted if the
user parameter &nameorder=true is included in the URL.

Main SQL window


The Main SQL window specifies the fixed part of the SQL statement which will be executed
irrespective of any template conditions. The ~1 specifies the exact point at which the
template is inserted if the Include IF criteria are met.

The template definition

The SQL block order by Name will be inserted in place ~1 when the parameter nameorder is
present in the URL. If nameorder is not present in the URL or is set to false, the template will
not be inserted and ~1 will be replaced with an empty string.

Advanced WebReports Workshop Page 65


Appendix - LiveReport Extensions SQL Templates

Example URL

/livelink.exe?func=ll&objAction=RunReport&objId=32666&nameorder=true

Resulting SQL LiveReport Extensions


provides a new function menu
item View SQL Source. This
shows the statement that will be
executed after replacement of
the parameters and templates

14.4 Using Auto-Where


Although templates can be used to store any part of a SQL query, one obvious use is to allow
varying numbers of filter clauses. Some examples of which are

WHERE Name = test


AND DATAID > 2000
OR Name LIKE '%new%'

From looking at these examples it can be observed that they need to be joined together with
OR, AND or WHERE logic depending on the particular use. If Auto-Where is ticked and the
main SQL source doesnt include a WHERE statement, the first template to be added to the
source needs to be preceded by WHERE, instead of AND or OR.

The Auto-Where feature deals with all of these AND/WHERE/OR scenarios as follows

Auto-Where Rules

Any template without Auto-Where selected will be ignored by the Auto-Where feature, even
if one of the reserved words WHERE, AND, OR has been included in the template source

If the first word is WHERE, AND or OR and this is the first template to be included, then the
word is converted to or left as WHERE

If neither WHERE, AND or OR are found and this is the first template to be included, then
the word WHERE is added to the front of the template

If the first word is AND or OR and this is NOT the first template to be included, then the
template is left as is

Page 66 Advanced WebReports Workshop


Appendix - LiveReport Extensions SQL Templates

If the first word is WHERE and this is NOT the first template to be included, then WHERE is
replaced with AND

If none of these words are found and this is NOT the first template to be included, the word
AND is added to the front of the template

14.5 Re-Using Templates


In section 11.3 we saw how a URL parameter can be used to control template insertion for a
given execution of a LiveReport. The URL Parameter option for inserting templates can also
be used to specify which user input parameters (e.g. a date or a user) should be inserted into
the template itself.

This feature provides a mapping capability that allows users to insert the same template
multiple times with different inputs on each occasion.

Repeatedly inserting the same template using a different user inputs requires constructing
multiple OR clauses. The use of the Auto-Where feature allows the template to automatically
add WHERE instead of OR when the first template is inserted, and then to use OR for each
subsequent template that is inserted. An example:

Main SQL Window

Defines a simple SQL statement that has a single template inserted at the end of it.

Template configuration

Here the template is defined. The template is controlled by a URL Parameter called
nameclause. The SQL Source for the template contains a parameter reference #1. It is
important to note this is different to &1. Where &1 would always insert the contents of the
parameter &inputLabel1, #1 allows any of the user input parameters to be mapped into the
template using &namecause=Ux where x is the number of the user input parameter.

Inputs (different types could be used)

The user will be prompted for 3 inputs of type string.

Advanced WebReports Workshop Page 67


Appendix - LiveReport Extensions SQL Templates

Parameters

Example URL (only relevant parameters shown)

...&nameclause=U1&nameclause=U2&nameclause=U3&inputlabel1=cat&inp
utlabel2=dog&inputlabel3=frog...

In the URL the parameter nameclause (which controls the template insertion) appears three
times which means the template will be inserted three times. The value of nameclause is
different in each of the three occurrences. In the first case, nameclasue is equal to U1 which
has the effect of inserting the template and passing the first user input parameter
(&inputLabel1) to the template. The second time nameclause appears it has a value of U2
which has the effect of inserting the template with the value of the second user input
parameter.

Resulting SQL

Even though the word


true is not in the parameter, the
template will be included
provided the number of user
inputs specified in the URL
match with any required
parameters in the template
source

14.6 Re-Using Templates with Multiple Variable Inputs


In this scenario, if the URL parameter specifies less than the required number of user inputs,
the template will not be included.

Page 68 Advanced WebReports Workshop


Appendix - LiveReport Extensions SQL Templates

The following example shows two different templates. One supports a direct match using
equals (=) and the other supports a partial match using LIKE. Either one can be selected
using the appropriate parameter (likecompare or equalscompare). The two parameters are
passed with a value containing a list of which User Inputs to insert in the template.

Main SQL Window

Here we can see a simply query with two templates being inserted.

Template configuration

Inputs (parameters are not shown)

Example URL

...&likecompare=u1,u2&equalscompare=u3,u4&inputLabel1=name&inputLabel
2=%new%&inputLabel3=dataid&inputLabel4=12345

Resulting SQL

Advanced WebReports Workshop Page 69


Appendix - LiveReport Extensions SQL Templates

Graphical Illustration

#1 #2 #1 #2
&likecompare=u1,u2 &equalscompare=u3,u4

&inputlabel1=name &inputlabel2=%new% &inputlabel3=dataid &inputlabel4=12345

(AND) #1 LIKE #2 ~1 ~2 (AND) #1 = #2

URL parameter: likecompare URL parameter: equalscompare

select * from DTREE WHERE ~1 ~2

select * from DTREE WHERE name LIKE '%new%' AND dataid = '12345'

Template ~1 is included because likecompare is in the URL and there are two User inputs
specified (#1 & #2) as required by the template. #1 is replaced with U1 (inputlabel1) which
equates to name. #2 is replaced with U2 (inputlabel2) which equates to %new%

Template ~2 is included because equalscompare is in the URL and there are two User inputs
specified (#1 & #2) as required by the template. #1 is replaced with U3 (inputlabel3) which
equates to dataid. #2 is replaced with U4 (inputlabel4) which equates to 12345

Page 70 Advanced WebReports Workshop


Appendix - LiveReport Extensions SQL Templates

14.7 Using the Auto Comma feature


The Auto Comma feature is designed to helps to build comma delimited lists. Imagine the
following template:

%1, %2, %3

When these User Input parameters are resolved, if one of them resolves to an empty string,
e.g. &inputlabel2, then the output could end up looking like: apple,,pear. If the Auto Comma
feature is enabled then the output would be corrected to: apple,pear.

This feature does not


currently support comma
resolution when another
template is used to insert
values into a comma list

14.8 Additional Template Features


This section describes a few additional features of templates that warrant further description.

14.8.1 Using Templates within Templates


Besides specifying templates for inclusion in the main SQL field, it is also possible to use
templates within other templates. The syntax is the same, e.g. ~2 to insert template 2.

A template can only


use a template with a lower
number. For example, template
~2 can include a reference to
template ~1 but not to itself or

14.8.2 Using the Template View Icon


Each template includes a special icon which can be used to view template behavior.
Clicking on this icon opens a window that contains a series of statements about the template
in question. These statements attempt to clarify for each template how it will behave based on
the selected condition and the source that has been specified.

Advanced WebReports Workshop Page 71


Appendix - Server Side Scripting

15 Appendix - Server Side Scripting

15.1 Overview
Although WebReports provides a number of tags to control what is included and excluded in a
WebReport, there remain tasks that demand the power of a fully fledged scripting language at
the server (before the report reaches a client). In WebReports version 4.0 and onwards the
optional ability to embed a section of script within a reportview is provided.

This feature offers tremendous power and flexibility for reporting or web application
developers. As with many powerful features, it follows that this capability also has potential
risks if used improperly. To reduce these to a minimum WebReports scripting has been
carefully secured and constrained in a configurable way that allows each Content Server
instance to choose precisely which script features should be enabled and which not.

Presently the only script language supported is Oscript. Oscript has the advantage of running
natively on the Content Server platform and hence offers excellent performance. Although
technically it is not required for creating WebReports with Oscript, developers with access to
the Content Server SDK will benefit from the Content Server Builders debugging facilities. In
practice, for anything but relatively simple scripts access to the Content Server Builder
debugger will be essential to allow developers to step through their code and debug it.

This section explains how to implement a script within a WebReport, but does not cover how
to write Oscript or provide a reference for Oscript syntax. For more information about Oscript
consult the Content Server SDK documentation such as the Content Server Builder help, or
contact OpenText for details of Content Server SDK training.

15.2 Security
There are a number of layered security measures to ensure that WebReports scripting is as
safe as possible:

1. If not required, the entire feature can be turned off globally by the Content Server
Administrator. Users may wish to check with their Administrator that the feature is
active before attempting to use it.

2. Even if the feature is on globally, it must be enabled for each individual WebReport
that uses it, every time a new reportview version is added to the WebReport. Any
user who can create a WebReport can include the tags to define and call scripts but
the tags will remain disabled until a System Administrator reviews and enables
scripting for the report. Disabled reports will run but will ignore and not execute
scripts.

3. The functions available within Oscript are heavily restricted by default. For example
you may not access Global variables or many of the Builder built-in packages such as
CAPI, DAPI, File, etc. What is and is not available can be configured by the Content
Server Administrator.

15.2.1 Enabling Scripting for a WebReport

Only users with the system administration rights privilege have the ability to enable scripting
for a particular WebReport. There are three different ways of doing this:

Advanced WebReports Workshop Page 73


Appendix - Server Side Scripting

1. Add the new Reportview version. When a System Administrator adds a reportview
containing scripting it is automatically enabled.

2. Go to the Properties -> Specific tab for the WebReport and check the Oscript
Scripting Enabled checkbox which will appear if scripting is present in the reportview.

3. Use the WebReports administration page Manage WebReports Scripting to review


all WebReports that contain scripting and enable (or disable) them by checking (un-
checking) the check box.

Clearly, users without the system administration rights privilege will find developing a
WebReport that contains scripting a tedious process since each new version of their
WebReport will need to be enabled by someone who does have that privilege. This is one
reason why it make sense to develop scripted WebReports on a non-production instance
where the developer may be granted the system administration rights privilege. See 9.3.

The only exception to this is that any user may create a WebReport from a default reportview
that contains oscript and it will be enabled automatically without the need for a System
Administrator to enable it. If the reportview for the WebReport is later edited or a new version
added, then its oscript will be disabled unless re-enabled by a System Administrator.
Because default reportviews are pre-enabled it is essential that any reportviews containing
oscript that are to be made default reportviews (by placing them in the default reportview
folder See the WebReports Installation and Administration Guide) must be tested and
approved.

15.2.2 Oscript Restrictions

WebReports uses a scheme of restrictions to make Oscript in the reportview more secure.
These are:

No access to global variables via the $ symbol

No ability to declare Object, ObjRef or Frame variables

No ability to use parenthesis like this .() to evaluate the contents of a variable. For
example you cannot do this as .(s) is not permitted:

Assoc myAssoc
String s = 'item1'
myAssoc.item1 = 'first item'
echo ( myAssoc.(s) )

All Builder Packages are restricted except those listed below

Some functions within certain restricted Builder Packages are permitted (see list
below)

The following Builder Packages are permitted by default. However the Content Server
Administrator can chose to add anything to or remove anything from the permitted list of
Packages or Package functions.

Permitted packages: 'Assoc', 'Bytes', 'Date', 'List', 'Math', 'Pattern', 'RecArray', 'Str', 'String',
'Boolean', 'Undefined', 'Void', 'Integer', 'Real', 'Record'

Permitted functions within otherwise restricted packages: 'Scheduler.debugbreak',


'Web.CRLF', 'Web.Escape', 'Web.Unescape', 'Web.DecodeForURL', 'Web.EncodeForURL',

Page 74 Advanced WebReports Workshop


Appendix - Server Side Scripting

'Web.Format', 'Web.EscapeHTML', 'Web.EscapeXML'

15.3 Recommendations for Developing Scripted Reportviews


WebReports with server-side scripting should be developed on a non-production Content
Server instance. Preferably this instance would be running the Content Server Builder to aid
in debugging and the developer would have the system administration rights privilege. After
the WebReports have been developed and tested to ensure they are fit for use in production
they can be moved to the production instance using XMLExport and Import (or one by one,
using download reportview etc).

Once in place on the production instance, a System Administrator should use the WebReports
admin page Manage WebReports Scripting to review all the reports and enable them if they
are satisfied that the reports and in particular the scripting aspects are safe. The kinds of
pitfalls to check for are:

Possibility of infinite loops which could tie up threads on theContent Server server

Possibility of consuming too much memory through unrestrained data creation or


iterations

Lack of checks for undefined data or passed parameters (i.e. the script must check
for and handle undefined parameters)

Presence of the scheduler.debugbreak() statement which is useful during


development but not desirable for production.

The first two of these represent the risks with the greatest potential to impact Content Server.

15.4 Defining and Calling a Script


Scripts are both defined and called within a single reportview. The definition of a script may
appear anywhere in the reportview and calls to a script can occur before its definition. This is
because script definitions are parsed, compiled and cached before a WebReport runs, in
most cases at the time the new reportview version is added. However, to make reportviews
easier to understand it makes sense to locate the script definitions in the header section.

To define a script, use the following:

[LL_WEBREPORT_STARTSCRIPT NAME:myFunc /]
function String anyName(Dynamic c)
String s = 'Testing'
return s
end
[LL_WEBREPORT_ENDSCRIPT /]

When called this simple script returns the string Testing to the reportview. The string will be
inserted into the resulting report output where the call to the script was made. To call the
script use:

[LL_WEBREPORT_CALL NAME:myFunc /]

Advanced WebReports Workshop Page 75


Appendix - Server Side Scripting

This tag will cause the script named myFunc to be executed and any result returned by it to
be inserted into the report output in place of the tag. Scripts can be called from anywhere in
the reportview.

15.5 Passing Data to a Script


There are a number of ways to pass data to a script: by using the Context Assoc, by
passing explicit parameters, and by calling WebReports static data tags within the script
section. The last of these three methods will be discussed separately in section 9.6.

15.5.1 The Context Assoc

Data as passed to the WebReport from the data source may be accessed from within the
script. The first parameter passed to the first Oscript function declared in the script will always
be an Assoc called the Context. If there is a data source for the WebReport, the Context
Assoc will contain a key called data holding a RecArray (a two-dimensional array) which will
represent all the data passed to the WebReport by the data source.

[LL_WEBREPORT_STARTSCRIPT NAME:myFunc /]
function String anyName(Dynamic context)
String cell = ""
if isDefined (context.data) // check there is a data source
cell = context.data[1][1] // return the first cell of data
end
return cell
end
[LL_WEBREPORT_ENDSCRIPT /]

Note the check to determine if context.data is defined. If there had been no data returned by
the data source (or no data source at all) context.data would be undefined and failing to check
for it would result in the entire WebReport failing to continue processing. The script is always
responsible for checking that the data it expects has in fact been passed.

15.5.2 Passing Parameters

When calling a script you may explicitly pass any number of parameters. For example the
following passes three parameters:

[LL_WEBREPORT_CALL NAME:myFunc PARM:1234:"a string with spaces":more_data


/]

Parameters containing spaces can be delimited with double or single quotes. The parameters
are passed to the first function declared in the myFunc script. They appear as an Oscript List
of values in the second parameter (after the Context Assoc). For example:

[LL_WEBREPORT_STARTSCRIPT NAME:myFunc /]
function String anyName(Dynamic context, List args)
String s
s = args[1] + "-" + args[2] + "-" + args[3]
return s
end
[LL_WEBREPORT_ENDSCRIPT /]

This would return 1234-a string with spaces-more_data to the reportview.

Page 76 Advanced WebReports Workshop


Appendix - Server Side Scripting

Example

The following example reportview illustrates how to access the data in the Context Assoc and
also how to explicitly pass a parameter to a script. This report will display all the data from a
data source regardless of how many columns that data source might return.

[LL_WEBREPORT_STARTSCRIPT NAME:doRow /]
Function String doRow (Dynamic c, List args)
Integer row, col
String s =''
row = Str.StringToInteger(args[1])
if isDefined(row)
for col=1 to length(c.data[1])
s+= Str.Format( '<TD>%1</TD>', c.data[row][col])
end
end
return s
end
[LL_WEBREPORT_ENDSCRIPT /]

[LL_WEBREPORT_STARTSCRIPT NAME:doRowHeader /]
Function String doRowHeader (Dynamic c, List args)
String field
String s =''
List fields
if isDefined(c.data) // check there is data
fields = RecArray.FieldNames(c.data)
for field in fields
s+= Str.Format( '<TD>%1</TD>', field)
end
end
return s
end
[LL_WEBREPORT_ENDSCRIPT /]

<TABLE>
<TR>
[LL_WEBREPORT_CALL NAME:doRowHeader /]
</TR>

[LL_WEBREPORT_STARTROW /]
<TR CLASS="[LL_REPTAG_ROWNUM ODDEVEN:Browserow1:Browserow2 /]"
VALIGN="CENTER" NOWRAP ALIGN="LEFT">
[LL_WEBREPORT_CALL NAME:doRow PARM:[LL_REPTAG_ROWNUM /] /]
</TR>
[LL_WEBREPORT_ENDROW /]

</TABLE>

15.6 Calling Static Data Tags


It is sometimes useful to be able to obtain the value returned by a WebReport static data tag
inside a section of Oscript. Note that static data tags do not include tags such as
[LL_REPTAG=<column> /] or [LL_REPTAG_%<var name> /].

For example you may need to know the value of a WebReport constant or parameter.
Although you could arrange to pass these items as parameters at the time the script is called,

Advanced WebReports Workshop Page 77


Appendix - Server Side Scripting

you can also access them directly using the built-in dot function ._repTag which has the
following syntax:

String ._repTag( String tag )

Parameters:
tag - A string value representing the tag plus optional sub-tags
Returns:
A String value containing the final value of the specified tag and sub-tags.

Here are two examples which return the value of a WebReport constant called report:

String value1 = ._repTag('$report')


String value2 = ._repTag('[LL_REPTAG_$report /]')

Note that you may specify either the full tag name or a shortened version which omits the
opening [LL_RETAG_ and closing /]. Here are some further examples:

String value3 = ._repTag('&myNode NODEINFO:NAME')


String value4 = ._repTag('USERID USERINFO:MAILADDRESS')

Note that not all sub-tags are supported when used within ._repTag. Generally sub-tags that
cause some other action besides returning formatted data do not work. The following sub-
tags are not supported: ADDVAR, CONCATVAR, NEXT, PREV, SETFORM, SETVAR,
SETWFATTR, SETWFFORM.

15.7 Calling Sub-tags


It is possible to make use of sub-tags without also invoking a static data tag using the
following dot function:

String ._subTag(String data, String subtags)

Parameters:
data - A String value to be operated on by the sub-tags
subtags - A String containing the sub-tags to use on the data
Returns:
A String value containing the result of the data transformed by the sub-tags.

There follows an example:

String s = ._subTag('3','DECODE:1:Beginning:2:Middle:3:End:Other
UPPER')

In this case the string s is set to END.

Note that not all sub-tags are supported when called by ._subTag. Generally sub-tags that
cause some other action besides returning formatted data do not work. The following sub-tags
are not supported: ADDVAR, CONCATVAR, NEXT, PREV, SETFORM, SETVAR,
SETWFATTR, SETWFFORM.

15.8 Calling Sub-WebReports


A script can directly call another WebReport using the following dot function:

Page 78 Advanced WebReports Workshop


Appendix - Server Side Scripting

Assoc ._subWebReport(Dynamic nodeid, [String parms], [String option])

Parameters:
nodeid - A String or Integer value specifying the nodeid of the report to run
parms - An optional String containing the parameters to pass to the sub-
WebReport. The required format is
'PARM:myParm1:myVal1:myParm2:myVal2' etc.
option - An optional String value of either output, data or all selecting the
required form of the results (see below); defaults to output.
Returns:
In all cases an Assoc is returned with a key ok holding a Boolean value that
is TRUE if the call was successful. If unsuccessful there is a further key err
containing an error String. If successful, the additional keys are as follows:

If option = output or option is not specified an Assoc with a key


output is returned. The value for the output key is a String
containing the formatted output of the sub-WebReport.
If option = data an Assoc with a key data is returned. The value
for the key data is a RecArray containing the original data from the
sub-WebReports data source.
If option = all an Assoc with the both the keys output and data
are returned.

There follows an example which takes a nodeID (DataID) from the data source and uses it as
a parameter when calling a sub-WebReport. The script checks the sub-WebReport call was
successful and either outputs the result or an error message:

[LL_WEBREPORT_STARTSCRIPT NAME:callSWR /]
Function string callSWR(Dynamic c)
Assoc result
String parm = Str.Format('PARM:inputlabel1:%1', c.data[1].DataID)

result = ._subWebReport(._repTag('$report'), parm, 'output')

if result.ok
return result.output
else
return result.err
end

end
[LL_WEBREPORT_ENDSCRIPT /]

[LL_WEBREPORT_CALL NAME:callSWR /]

In this example ._repTag is used to return the value of a constant that points to the sub-
WebReport required.

15.9 Script Scope and Calling a Script From Within a Script


WebReports supports defining multiple scripts within the same reportview so long as each
script has a unique name within the reportview. A script can call another script from the same
reportview, but not a script defined in another reportview. Therefore script names do not need
to be unique across all reportviews in Content Server.

Advanced WebReports Workshop Page 79


Appendix - Server Side Scripting

Note that multiple oscript functions may also be declared within a single script block (i.e.
between [LL_WEBREPORT_STARTSCRIPT /] and [LL_WEBREPORT_ENDSCRIPT /]).
Functions within the same script block may call each other. However, only the first function
declared in any script block can be called from another script block (or from the reportview
using [LL_WEBREPORT_CALL /]). One can think of a script block as a discrete oscript
feature within the Content Server builder which behaves the same way in this respect.
Readers familiar with JavaScript should note that the rules described here are quite different
from those that apply to JavaScript.

To call another script in the reportview simply preface the name of the script block with a dot
.. This is illustrated in the following, somewhat contrived, example that performs an HTML
escape on every item of data in the Name column and concatenates them together
separated by semi colons:

[LL_WEBREPORT_STARTSCRIPT NAME:escape /]
function String escape(String input = '')
return Web.EscapeHTML(input)
end
[LL_WEBREPORT_ENDSCRIPT /]

[LL_WEBREPORT_STARTSCRIPT NAME:Main /]
function String anyName(Dynamic context)
String s
Integer i
if isDefined (context.data) // check there is a data source
for i = 1 to length (context.data)
s += .escape(context.data[i].Name) + '; '
end
end
return s
end
[LL_WEBREPORT_ENDSCRIPT /]

[LL_WEBREPORT_CALL NAME:Main /]

15.10 Exercises
15.10.1 Scripting Exercise

In this exercise you will create a report that outputs a comma separated values report for any
number of columns. As you are working on your reportview, cick Add Version & Continue
from time to time to save your work. This also has the benefit of identifying errors as you go
which often makes it easier to identify what is wrong.

1. Create a WebReport using a List DTree LiveReport as a data source and using the
basic_scripted reportview. If that reportview does not appear in the list of default
reportviews, it can be added by an administrator or supplied by your instructor. (It exists
along with other useful reportviews in the module\webreports_4_x_x\examplereportviews
folder in the module).

2. Edit the reportview and click on the Header Section to expand that section where most
of the code is. This report contains all the code to handle a variable number of columns
and output a simple HTML tabulated reported. Your task is to modify it to output CSV.

3. Find the script block called doHeading. Note how the string s is used to build up the
report output. We dont want any HTML tags so remove the s += '<TR>' and s +=

Page 80 Advanced WebReports Workshop


Appendix - Server Side Scripting

'</TR>' lines of code. Change the code inside the for-loop to read
s += Str.String(columnNames[col]) + ','

This give us a basic header row in CSV format. The only problem is we will have an extra
comma at the end of the header row, so add this code after the for-loop to drop the extra
comma:
if length(columnNames) > 0
s = s[1:-2]
end

4. Find the script block called doAllRows. Again make changes so that the string s is
building up a CSV report and not an HTML table. Remove the following lines of code:
s += '<TR CLASS="' + ((row%2==1)?'browseRow1':'browseRow2') + '"
VALIGN="CENTER" ALIGN="LEFT">'

s += '</TR>'

Change the code inside the inner for-loop to read:


s += Str.String(c.data[row][col]) + ','

Again add the following after the inner loop:


if length(c.data[1]) > 0
s = s[1:-2]
end

5. Change the last line of doAllRows to read as follows in order to make sure each row
ends with a newline character:
return Str.Catenate(rowArray,Str.CRLF)

6. Get rid of any other HTML code or spare carriage returns or line feeds in the header, row-
section or footer. Take care not to delete the [LL_WEBREPORT_CALL /] tags at the
bottom of the header. This is what actually calls the script blocks.

7. Save your reportview. If there are any compile errors correct them and save again.
Change the destination of the WebReport to Desktop (go to the function menu for your
WebReport and select Properties -> Destination. Select Desktop). Set the MIME type to
text/csv and the filename to data.csv.

8. Now run your report. It should download and invite you to open or save. Click open and
the report should open in Excel. Youll notice that in some places the data seems to
occupy more columns than there are headings. This is because there are commas in the
data causing Excel to get confused. Data that has commas or new line characters needs
to be escaped by wrapping it in quotes. There is a handy sub-tag that does this called
ESCAPECSV. Review the chapter on calling sub-tags from a script block and use it to fix
the problem.

Advanced WebReports Workshop Page 81


www.resonatekt.com
Copyright 2003-2011 Resonate KT Limited

The information in this document is subject to change without notice. All rights reserved.