Idoc Hacks:Faking arrays in idoc script, part 1
Idoc script is a simple beast. This simplicity makes easy to learn — minimal syntax to memorize; few constructs to understand.
On the flip side, idoc is pretty limited. It can feel like a blunt instrument to anyone with even moderate experience in a modern scripting language. The lack of features often results in scripts that employ line-after-line of cut-and-paste code. Difficult to read. Painful to maintain.
At the top of my wish list for additions to the language (just above user-defined functions and REAL booleans) would be support for arrays.
No arrays. Bummer. What to do?
Fake it with ResultSets
Enter the ResultSet, typically a multi-row and/or multi-column representation of data — often the results returned from executing a query. There are a number of functions for creating and manipulating ResultSets. Additionally, idoc’s loop construct makes it easy to iterate over a ResultSet and access values from the current row on each pass. Sort of array-like, yes? Sorta.
To simulate a simple, one-dimensional “array,” use idoc’s rsMakeFromString() function. It’s signature is:
rsName: The name of the ResultSet to be created, as a string
valueList: A comma separated list of strings to be parsed for values, or a variable containing same. Each item will become a row (or value in our fake array).
columnName: [optional] The column name. The defualt is “row”. (In an associative array or dictionary, this would be the key.
A call might look like:
[!--$ rsMakeFromString( "myRecordSet", "red, green, blue", "color" ) --]
Successful execution would create the variable myRecordSet. It would have a single column named “color”, and three rows, each containing one of the values provided. Now we can easily iterate over the “array” and extract values like so:
[!--$ loop myRecordSet --] value [!--$ CURRENT_ROW --] = [!--$ number --] [!--$ endloop --] value 0 = red value 1 = green value 2 = blue
A simple example
Imagine we need to build a “next page” navigation for every primary page on a Site Studio site. To do this, we’ll link to the current node’s first child node. If no child is present, we’ll link to the node’s next sibling node. Failing that, we’ll just link to the parent node.
Without arrays, this (somewhat contrived) scenario might result in multiple, hard-coded calls to ssGetRelativeNodeId(). Before each call, we’d need to manually set the type of relative node to look for ( child, next or parent ). Each time we’d use very similar conditional logic to check results and determine what to do next. Scale this kind of cut-paste-tweak approach to more complicated scripts, and you quickly have a maintenance nightmare.
With our ResultSet pseudo-array, though, we can build much cleaner code that looks something like this:
[!--$ relativeId = '' --] <!-- create our fake array --> [!--$ rsMakeFromString( 'nodeTypes', 'child,next,parent', 'nodeType' ) --] [!--$ loop nodeTypes --] [!--$ relativeId = ssGetRelativeNodeId( siteId, nodeId, nodeType ) --] <!-- if we get something back, break out of the loop --> [!--$ if not strEquals( relativeId, '' ) --] [!--$ break --] [!--$ endif --] [!--$ endloop --]
After this executes, relativeId will contain the nodeId for either the immediate child, next sibling or parent node of the current node, whichever it finds first. We can use that nodeId to build our “next” link like so:
<!-- ensure there's something in relativeId --> [!--$ if not strEquals( relativeId, '' ) --] <!-- get the node's label to use as link text --> [!--$ relativeLabel = ssGetNodeLabel( siteId, relativeId ) --] Next: <a href="ssNODELINK/[!--$ relativeId --]">[!--$ relativeLabel --]</a> [!--$ endif --]
That’s all for now, but stay tuned…
Simple, right? ResultSets-cum-pseudo-arrays have a number of potential uses. They’re handy when you need to iterate over a number of nodeId’s, for example. Anytime you find yourself repeatedly calling the same function, with slight parameter modifications, consider using a pseudo-array.
Coming soon in part 2, I’ll demonstrate how to fake multi-dimensional arrays and provide a somewhat more in-depth example.
Idoc script is the default server-side scripting language in Oracle Universal Content Management Suite (formerly known as Stellent Content Server / Site Studio).