Strict Standards: Declaration of Walker_Page::start_lvl() should be compatible with Walker::start_lvl(&$output) in /home/admtc/justcaldwell.com/blog/wp-includes/classes.php on line 576

Strict Standards: Declaration of Walker_Page::end_lvl() should be compatible with Walker::end_lvl(&$output) in /home/admtc/justcaldwell.com/blog/wp-includes/classes.php on line 576

Strict Standards: Declaration of Walker_Page::start_el() should be compatible with Walker::start_el(&$output) in /home/admtc/justcaldwell.com/blog/wp-includes/classes.php on line 576

Strict Standards: Declaration of Walker_Page::end_el() should be compatible with Walker::end_el(&$output) in /home/admtc/justcaldwell.com/blog/wp-includes/classes.php on line 576

Strict Standards: Declaration of Walker_PageDropdown::start_el() should be compatible with Walker::start_el(&$output) in /home/admtc/justcaldwell.com/blog/wp-includes/classes.php on line 593

Strict Standards: Declaration of Walker_Category::start_lvl() should be compatible with Walker::start_lvl(&$output) in /home/admtc/justcaldwell.com/blog/wp-includes/classes.php on line 687

Strict Standards: Declaration of Walker_Category::end_lvl() should be compatible with Walker::end_lvl(&$output) in /home/admtc/justcaldwell.com/blog/wp-includes/classes.php on line 687

Strict Standards: Declaration of Walker_Category::start_el() should be compatible with Walker::start_el(&$output) in /home/admtc/justcaldwell.com/blog/wp-includes/classes.php on line 687

Strict Standards: Declaration of Walker_Category::end_el() should be compatible with Walker::end_el(&$output) in /home/admtc/justcaldwell.com/blog/wp-includes/classes.php on line 687

Strict Standards: Declaration of Walker_CategoryDropdown::start_el() should be compatible with Walker::start_el(&$output) in /home/admtc/justcaldwell.com/blog/wp-includes/classes.php on line 710

Strict Standards: Redefining already defined constructor for class wpdb in /home/admtc/justcaldwell.com/blog/wp-includes/wp-db.php on line 58

Deprecated: Assigning the return value of new by reference is deprecated in /home/admtc/justcaldwell.com/blog/wp-includes/cache.php on line 99

Strict Standards: Redefining already defined constructor for class WP_Object_Cache in /home/admtc/justcaldwell.com/blog/wp-includes/cache.php on line 404

Deprecated: Assigning the return value of new by reference is deprecated in /home/admtc/justcaldwell.com/blog/wp-includes/query.php on line 21

Deprecated: Assigning the return value of new by reference is deprecated in /home/admtc/justcaldwell.com/blog/wp-includes/theme.php on line 576

Strict Standards: call_user_func_array() expects parameter 1 to be a valid callback, non-static method UltimateTagWarriorActions::ultimate_query_vars() should not be called statically in /home/admtc/justcaldwell.com/blog/wp-includes/plugin.php on line 163

Strict Standards: call_user_func_array() expects parameter 1 to be a valid callback, non-static method UltimateTagWarriorActions::ultimate_posts_where() should not be called statically in /home/admtc/justcaldwell.com/blog/wp-includes/plugin.php on line 163

Strict Standards: call_user_func_array() expects parameter 1 to be a valid callback, non-static method UltimateTagWarriorActions::ultimate_search_where() should not be called statically in /home/admtc/justcaldwell.com/blog/wp-includes/plugin.php on line 163

Strict Standards: call_user_func_array() expects parameter 1 to be a valid callback, non-static method UltimateTagWarriorActions::ultimate_posts_join() should not be called statically in /home/admtc/justcaldwell.com/blog/wp-includes/plugin.php on line 163

Strict Standards: call_user_func_array() expects parameter 1 to be a valid callback, non-static method UltimateTagWarriorActions::ultimate_search_join() should not be called statically in /home/admtc/justcaldwell.com/blog/wp-includes/plugin.php on line 163

Strict Standards: call_user_func_array() expects parameter 1 to be a valid callback, non-static method UltimateTagWarriorActions::ultimate_posts_groupby() should not be called statically in /home/admtc/justcaldwell.com/blog/wp-includes/plugin.php on line 163

Strict Standards: call_user_func_array() expects parameter 1 to be a valid callback, non-static method UltimateTagWarriorActions::ultimate_tag_templates() should not be called statically in /home/admtc/justcaldwell.com/blog/wp-includes/plugin.php on line 311

Warning: Cannot modify header information - headers already sent by (output started at /home/admtc/justcaldwell.com/blog/wp-includes/classes.php:576) in /home/admtc/justcaldwell.com/blog/wp-includes/feed-rss2.php on line 8
justcaldwell http://www.justcaldwell.com/blog Just another WordPress weblog Mon, 21 Jul 2008 18:11:14 +0000 http://wordpress.org/?v=2.5.1 en Faking arrays in idoc script, part 1 http://www.justcaldwell.com/blog/site-studio/faking-arrays-in-idoc-script-part-1/ http://www.justcaldwell.com/blog/site-studio/faking-arrays-in-idoc-script-part-1/#comments Mon, 21 Jul 2008 17:59:34 +0000 justcaldwell
Strict Standards: call_user_func_array() expects parameter 1 to be a valid callback, non-static method UltimateTagWarriorActions::ultimate_add_tags_to_rss() should not be called statically in /home/admtc/justcaldwell.com/blog/wp-includes/plugin.php on line 163
idocoraclesite stuidostellentuniversal content management http://www.justcaldwell.com/blog/?p=13 Oracle Universal Content Managment suite, the sparse feature set and lack of things like user-defined functions and arrays often result in a cut-paste-tweak approach to problem-solving that's a real pain to maintain. In this post, I cover how to simulate a simple, one-dimensional array with a ResultSet created with the rsMakeFromString() function.]]> Strict Standards: call_user_func_array() expects parameter 1 to be a valid callback, non-static method UltimateTagWarriorActions::ultimate_the_content_filter() should not be called statically in /home/admtc/justcaldwell.com/blog/wp-includes/plugin.php on line 163

Strict Standards: Non-static method UltimateTagWarriorActions::regExEscape() should not be called statically in /home/admtc/justcaldwell.com/blog/wp-content/plugins/UltimateTagWarrior/ultimate-tag-warrior-actions.php on line 669

Strict Standards: Non-static method UltimateTagWarriorActions::regExEscape() should not be called statically in /home/admtc/justcaldwell.com/blog/wp-content/plugins/UltimateTagWarrior/ultimate-tag-warrior-actions.php on line 669

Strict Standards: Non-static method UltimateTagWarriorActions::regExEscape() should not be called statically in /home/admtc/justcaldwell.com/blog/wp-content/plugins/UltimateTagWarrior/ultimate-tag-warrior-actions.php on line 670

Strict Standards: Non-static method UltimateTagWarriorActions::regExEscape() should not be called statically in /home/admtc/justcaldwell.com/blog/wp-content/plugins/UltimateTagWarrior/ultimate-tag-warrior-actions.php on line 670

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

rsMakeFromString( string rsName, string valueList[, string columnName] )

Parameters:

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

]]>
http://www.justcaldwell.com/blog/site-studio/faking-arrays-in-idoc-script-part-1/feed/
Easy idoc breadcrumbs with ssNavNodeList http://www.justcaldwell.com/blog/site-studio/idoc-breadcrumbs/ http://www.justcaldwell.com/blog/site-studio/idoc-breadcrumbs/#comments Thu, 20 Sep 2007 19:31:58 +0000 justcaldwell
Strict Standards: call_user_func_array() expects parameter 1 to be a valid callback, non-static method UltimateTagWarriorActions::ultimate_add_tags_to_rss() should not be called statically in /home/admtc/justcaldwell.com/blog/wp-includes/plugin.php on line 163
http://www.justcaldwell.com/blog/site-studio/site-studio-recipes-build-idoc-breadcrumbs-with-ease/ ssNavNodeList makes quick work of building idoc-based breadcrumbs.]]> Strict Standards: call_user_func_array() expects parameter 1 to be a valid callback, non-static method UltimateTagWarriorActions::ultimate_the_content_filter() should not be called statically in /home/admtc/justcaldwell.com/blog/wp-includes/plugin.php on line 163

Strict Standards: Non-static method UltimateTagWarriorActions::regExEscape() should not be called statically in /home/admtc/justcaldwell.com/blog/wp-content/plugins/UltimateTagWarrior/ultimate-tag-warrior-actions.php on line 669

Strict Standards: Non-static method UltimateTagWarriorActions::regExEscape() should not be called statically in /home/admtc/justcaldwell.com/blog/wp-content/plugins/UltimateTagWarrior/ultimate-tag-warrior-actions.php on line 669

Strict Standards: Non-static method UltimateTagWarriorActions::regExEscape() should not be called statically in /home/admtc/justcaldwell.com/blog/wp-content/plugins/UltimateTagWarrior/ultimate-tag-warrior-actions.php on line 670

Strict Standards: Non-static method UltimateTagWarriorActions::regExEscape() should not be called statically in /home/admtc/justcaldwell.com/blog/wp-content/plugins/UltimateTagWarrior/ultimate-tag-warrior-actions.php on line 670

The under-documented ssNavNodeList is a result set baked in to all Site Studio pages. While it shows up in at least one sample fragment, there’s no mention of this handy little tool in the documentation. I was forever recreating something similar using loops and some flavor of GET_RELATIVE_NODE_ID, until I stumbled on ssNavNodeList and a better way.

ssNavNodeList provides a list of nodeId’s representing the site hierarchy from home page down to the current page — its single column is simply named ‘nodeId.’ So, if the current page fits in the site like so:

  - Home (101)
    - AncestorPage (111)
      - ParentPage (119)
        - CurrentPage (175)

ssNavNodeList for CurrentPage would contain “101,111,119,175.”

This makes creating Idoc script based breadcrumbs a piece of bread cake. Give the same site structure, we want to produce something like:

Home » AncestorPage » ParentPage » CurrentPage

Here’s a simple version of my favorite recipe for doing just that:

The code

[!--$ thisNodeId = nodeId --]
 
<!-- create the crumb delimiter  -->
[!--$ delimiter=" » " --]
 
[!--$ loop ssNavNodeList --]
  <!-- grab the node label -->
  [!--$ nodeLabel = ssGetNodeProperty( nodeId, "label" ) --]
  [!--$ if not strEquals( nodeId, thisNodeId ) --]
      <!-- not the current node, so just write a link + delimiter -->
      <a href="ssNODELINK/[!--$ nodeId --]">
        [!--$ nodeLabel --]
      </a>[!--$ delimiter --]
  [!--$ else --]
      <!-- we've reached current node so check for primary/secondary layout -->
      [!--$ if isTrue( isSecondaryPage ) --]
        <!-- this is a secondary page, so use the dDocTitle of a contributed item -->
        <!-- first write the current nodeId's label as a link -->
        <a href="ssNODELINK/[!--$ nodeId --]">
          [!--$ nodeLabel --]
        </a>[!--$ delimiter --]
 
        <!-- get the dDocTitle for the contributed item and use it -->
        [!--$ dDocName = region1 --]
        [!--$ executeService("SS_DOC_INFO_LATEST") --]
        [!--$ myPageName = DOC_INFO.dDocTitle --]
        <em>[!--$ myPageName --]</em>
      [!--$ else --]
        <!-- primary page, so just write the current node label -->
        <em>[!--$ nodeLabel --]</em>
      [!--$ endif --]
    [!--$ endif --]
[!--$ endloop --]
 
<!-- / #crumb -->

The details

In a nutshell, as we loop over the ssNavNodeList, nodeId gets the value of a node in the list. We compare that to the current page’s nodeId that we saved in thisNodeId — as long as they’re not equal we’re dealing with an ‘ancestor’ page, and we just write a link followed by the delimiter.

<a href="ssNODELINK/[!--$ nodeId --]">[!--$ nodeLabel --]</a>[!--$ delimiter --]

When nodeId and thisNodeId do become equal, we’ve reached the current node. At this point we want to determine whether we’re on a primary or secondary layout. If it’s a primary page (lines 26-28), we can just spit out the node label and we’re done. If it’s a secondary page, though,

[!--$ if isTrue( isSecondaryPage ) --]

we’re likely dealing with dynamic content in a replaceable region and we might want to go a bit further to get an appropriate label.

Secondary pages

A typical implementation in my shop has secondary layouts displaying contributed content items in replaceable regions — we consistently use ‘region1′ as the identifier for these ‘main content’ regions. In these cases, we want to use the value of title (dDocTitle) in the content item’s metadata for the crumb label. That code, one more time, looks like:

<a href="ssNODELINK/[!--$ nodeId --]">[!--$ nodeLabel --]</a>[!--$ delimiter --]
 
<!-- get the dDocTitle for the contributed item and use it -->
[!--$ dDocName = region1 --]
[!--$ executeService("SS_DOC_INFO_LATEST") --]
[!--$ myPageName = DOC_INFO.dDocTitle --]
<em>[!--$ myPageName --]</em>

Here we’re first writing out the label for the current node as a link that would take us to the primary page for the section.

Next we assign the content ID stored in ‘region1′ to dDocName in preparation for getting the DOC_INFO for that item — the executeService call in line 23. Now we can grab the value of dDocTitle and display it as the last label in the crumb in lines 24 & 25.

]]>
http://www.justcaldwell.com/blog/site-studio/idoc-breadcrumbs/feed/
What’s all this, then? http://www.justcaldwell.com/blog/blogging/blogging-at-last/ http://www.justcaldwell.com/blog/blogging/blogging-at-last/#comments Mon, 06 Aug 2007 17:50:56 +0000 justcaldwell
Strict Standards: call_user_func_array() expects parameter 1 to be a valid callback, non-static method UltimateTagWarriorActions::ultimate_add_tags_to_rss() should not be called statically in /home/admtc/justcaldwell.com/blog/wp-includes/plugin.php on line 163
http://www.justcaldwell.com/blog/uncategorized/blogging-at-last/ Strict Standards: call_user_func_array() expects parameter 1 to be a valid callback, non-static method UltimateTagWarriorActions::ultimate_the_content_filter() should not be called statically in /home/admtc/justcaldwell.com/blog/wp-includes/plugin.php on line 163

Strict Standards: Non-static method UltimateTagWarriorActions::regExEscape() should not be called statically in /home/admtc/justcaldwell.com/blog/wp-content/plugins/UltimateTagWarrior/ultimate-tag-warrior-actions.php on line 669

Strict Standards: Non-static method UltimateTagWarriorActions::regExEscape() should not be called statically in /home/admtc/justcaldwell.com/blog/wp-content/plugins/UltimateTagWarrior/ultimate-tag-warrior-actions.php on line 669

Strict Standards: Non-static method UltimateTagWarriorActions::regExEscape() should not be called statically in /home/admtc/justcaldwell.com/blog/wp-content/plugins/UltimateTagWarrior/ultimate-tag-warrior-actions.php on line 670

Strict Standards: Non-static method UltimateTagWarriorActions::regExEscape() should not be called statically in /home/admtc/justcaldwell.com/blog/wp-content/plugins/UltimateTagWarrior/ultimate-tag-warrior-actions.php on line 670

So it’s been a long time coming, but my blog is finally live.

The theme.

Always the control freak, I decided to roll my own theme. A redesign is already perpetually in the works, but I finally realized that obsessing over the design was getting in the way of the goal — blogging.

No doubt I’ll write more about that process in the future, but I’ll just mention some of the great resources and plugins I discovered along the way:

  • Breadcrumb plugin
  • Ultimate Tag Warrior
  • SEO Title Tag
  • more soon

Oh yeah, and the thing runs on (the excellent) Wordpress.

The plan.

Expect to see my general musings on web design and development, PHP, javascript, Stellent content management — especially Site Studio and IdocScript development — and whatever else strikes my short-attention-spanned fancy.

Stellent? Site Studio? IdocScript?

At my day job, I spend quite a bit of time and effort working with Stellent web content management solutions. Site Studio is Stellent’s site design and management tool, and IdocScript is their home-grown, server-side scripting language. Good information about Site Studio and IdocScript development can be difficult to find, so I plan to share some of my hard-won knowledge and solutions here. (Update: Oracle recently acquired Stellent, and the content management system and tools are being re-branded as part of Oracle Fusion Middleware, or some such. Quite a mouth-full, you ask me. We’ll see how much luck I have switching to the new terminology).

And you are?

Right. My name is Michael. As the world (and my workplace, in particular) is lousy with Michaels, many call me by my last name — just Caldwell.

I pay the bills as a web designer/developer at the University of Texas at Austin, and I manage a small team that serves the Office of Admissions and the Office of the Registrar.

In short,

Hello world.

]]>
http://www.justcaldwell.com/blog/blogging/blogging-at-last/feed/