Introduction

Over the last year I’ve been blogging about various topics in OpenText Content Server development. In most of these blog posts I referred to a module called RHCore, which is the topic of this next post. So what exactly is RHCore?

RHCore is an Content Server application framework. It’s written in OScript, installs like any other module, and provides a new and fresh way to develop applications with OpenText Content Server.

The module works by simplifying many of the complex development patterns commonly used in Content Server development. It lets the developer write beautiful and elegant OScript, which results in a module that can be developed in less time with fewer bugs.

What motivated RHCore?

I’ve been developing with Content Server for over 14 years and often found myself writing the same code over and over again. It was this repetitiveness and realisation after working with other frameworks that much of this repetition could be abstracted away into something that’s reusable and easier to work with. It was during a break in my contract work that I prototyped RHNode (an abstraction of DTree nodes) and was delighted with the results. The rest of the framework snowballed from there.

I’m using the module as a basis for a few applications that are now running on production systems. The results have spoken for themselves: The applications were built in less time, are more feature rich, and are easier to maintain than anything I have ever worked on before.

What does RHCore do?

The last 14 blog posts have highlighted some of the key features of RHCore. In the remainder of this blog post I will summarise some of these features, throw in a bit more, and try to show how it fits together.

Let’s start with the fundamental concept.

An object-oriented programming approach

Much of RHCore is based on an object-oriented programming (OOP) approach. In simple terms, an “object” is a data structure that contains data and functions (or “methods”) to operate on itself. The beauty of this design is that most of what you need is self contained and doesn’t require referencing external functions in different places. RHCore introduces a number of classes (the “blueprint” for an object instance) to simplify common patterns and interaction with many Content Server data structures.

One such class is RHNode, which is used to interact with DTree nodes (it is analogous to the newly introduced CSNode, but more generic). An RHNode object contains the node data (e.g., DataID, User, Extendeddata, etc.), but also methods to fetch related information (DAPINODE, LLNode, user, parent, categories, etc.) and perform common tasks (e.g., copy, move, rename, etc.). Let’s look at an example.

Say you have the DataID of a node and want to get the URL to open it. With the standard Content Server API this looks something like the following (skipping error handling for brevity):

All the internal workings to generate the URL (getting the DAPINODE, WebNode representation, WebNode object, WebNodeCMD, etc.) is abstracted away. It’s a simple example, but demonstrates how an OOP approach can simplify some otherwise complex code. This pattern of simplification is used throughout RHCore.

Have a look at Part I of this blog series for more information on the OOP approach.

Table Schemas and Data Persistence

Creating a database table in Content Server is a tedious and manual process. The tables must be manually defined (accommodating variations among database flavours) and query, create, read, update, & delete operations require direct database calls. Writing inline SQL isn’t a good idea (it leads to repetition of code and little reusability), and building an API for these operations is another manual and repetitive process.

RHCore simplifies this with its RHModel framework. The framework allows a model to be defined, which automatically generates the table schema and an API for interacting with the data (e.g., setters, getters, and methods for querying independent of the database type). This allows a schema and API to be generated in mere minutes in what used to take hours by conventional means. Best of all, no SQL needs to be written and the generated API provides a natural place for business logic that is tied to the model (e.g., send an e-mail whenever the “status” field is changed to “Completed”).

Have a look at Part II of this blog series for more information on RHModel.

Templates with RHTemplate

RHCore provides a new template language called RHTemplate that can be used as an alternative to WebLingo (plus many other uses). The template syntax is simple and provides tools to quickly build pages with the most common layouts. In particular, it contains functionality to:

render your page in a style consistent with Content Server (without having to write extra CSS; read more in Part XI);

render interactive widgets (e.g., user picker, date picker, sort headers, paging controls, tabs, etc.) that “just work” without having to import or write any extra JavaScript or CSS (read about this in Part XII); and

traverse and resolve complex relationships (e.g., to get the display name of the owner on the parent node: {{ node.parent.user.displayname }}).

RHCore provides extensions to the standard request handlers (including WebNodeAction) to support RHTemplate, which makes the creation of requests with RHTemplate a simple task. As a bonus the extensions also abstract away guiComponents and pageManager so you don’t have to deal with those either.

Have a look at Part III of this blog series for more information on RHTemplate.

Form Lifecycle with RHForm

Writing a form in Content Server to present, capture, and persist a value is a tedious and repetitive process. It involves:

fetching the initial values and passing them to the WebLingo;

hardcoding the form in the WebLingo (including the initial values, layout, UI widgets, etc.);

writing a request handler to consume, validate, and persist the submitted values;

spending lots of time debugging and maintaining it; and

presenting a jarring error page if anything goes wrong (as in the following screenshot).

Little of this is reusable and doing something small like adding a new field requires modifying code in multiple locations.

RHCore introduces RHForm, which consolidates the definition, rendering, and validation of the form into a single object. This is quite useful since it makes it possible to programmatically control the behaviour of the form at runtime without having to write any logic in the WebLingo or RHTemplate.

RHForm also supports a validation pattern that displays errors inline, which the user can correct and resubmit:

This is far more user friendly than the Content Server error page that requires the use of the back button to recover.

Have a look at Part IV of this blog series for more information on RHForm.

Generic Admin Configuration Pages

Many modules have a configuration page linked from the admin.index page. Configuration pages are often a set of form fields that allow preferences to be configured and persisted in the KINI table or opentext.ini file. Most configuration pages are built by hardcoding everything (although the lesser-known LLConfig OSpace is available to help here) and creating these pages often means a lot of copy and pasting.

RHCore introduces a framework for defining, rendering, and persisting a configuration page without having to write any HTML and a minimal amount of OScript. What used to take hours to write, debug, and maintain can now be done in minutes. The following is a screenshot of a sample admin page created with RHCore:

Have a look at Part VII of this blog series for more information on Generic Admin Configuration Pages.

Override System

I always attempt to minimise the intrusiveness of my code by minimising the number of overrides of core functionality. However, overrides are sometimes unavoidable and it’s unfortunate how often developers will override entire scripts or WebLingo files just to make a small change. The problem with this approach is that it’s not forward compatible: If OpenText changes the original script or WebLingo in a patch or subsequent release then these changes will no longer be reflected in the override.

RHCore provides tools to minimise the impact of overrides by allowing the original script or Weblingo to be called from the override. This doesn’t satisfy every override scenario, but when it does (and it often does) it provides forwards compatibility in the event the original script or WebLingo gets changed.

RHCore also provides a way to monkey patch a script at run time. Sometimes a script is available that does exactly what you want except for a hardcoded value or assumption in the middle of it. A monkey patch allows you to take that script at run time, modify it with a search and replace, and recompile it for execution. This isn’t always failsafe, but until now has worked well and has prevented me from having to inherit hundreds of lines of code from somebody else.

Other Utilities

RHCore does a lot more, and the following is a short overview to highlight some of the other features:

Categories and Attributes are notoriously difficult to develop with. RHCore provides an extended API to make this easier (i.e., no more traversing the fData structure; read about it in Part VI).

An add-on HTTPClient library is available (based on Apache HTTPClient), which provides a robust interface for making HTTP requests from Content Server.

Sending HTML e-mails to users or groups has been simplified to one line of code (read about it in Part XIII).

Enumerated types are available for some syntactic sugar (read about it in Part VIII).

Documents can be Base64 encoded in one line of code.

A messaging framework is available for one-time notifications (this will get its own blog post someday).

A framework is available to create custom function menus.

Custom Views can be augmented to contain dynamic content and logic (via RHTemplate).

Documentation for your project can be generated directly from the OScript source code (in the same spirit as javadoc).

Help pages for your module can be generated from markdown (no more copy and pasting the help page template).

Scripts and workflow event callbacks can be edited directly in the Web UI (read about it in Part XIV).

and much more…

Wrapping Up

RHCore simplifies many areas in Content Server development. What I also find nice is that modules built on RHCore are easier to migrate to newer versions of Content Server since most of the upgrade logic is rooted in RHCore.

I say it again: RHCore simplifies development and makes it possible to build richer applications with fewer bugs in less time.

If you’re interested in an evaluation, demonstration, or more information about RHCore then please get in touch! I also welcome comments below.

Need help developing for Content Server or interested in using RHCore? Contact me at cmeyer@rhouse.ch.

11 Responses to “Part XV: What is RHCore?”

I have been involved with oScript for some time (since 1999) so I like to think I know a thing or two, but when I see the kind of stuff folks like you (and Patrick V.) do it reminds me how much further there is to go! Thank you for sharing…

Hi John, thanks. It’s been a fun learning experience and I love the ease at which I can do things now. I met Patrick a few years ago for lunch when he was just starting his company. I like his fresh view and challenge to conventional approaches. His results have been amazing.

Thank you very much Chris, I love your stuffThank you very much Chris, as you know, I love your work as well. Many thanks also to you John, was really nice to meet you at EW14 (you know it), and many thanks also to you John

Hi Chris,
I really like the forms example of actually seeing the error inline. It’s amazingly more user friendly! I am now wondering how this plays into or not with GCI’s methods for giving a customized look and feel to forms, reports, and workflow user steps. Guess, I’ll have to investigate.

Dumb question: does RHCore stand for Request Handler Core?
Really dumb question: Does Open Text ever recommend that a person use RHCore, as you have done?
Really, really dumb question: does RHCore get changed with every release of CS, you the 90 day releases? Is overriding RHCore, more of a safe bet than other overrides?

Hi Tammy: There are no dumb questions. I’m happy to give you some more information.

I really like the forms example of actually seeing the error inline. It’s amazingly more user friendly! I am now wondering how this plays into or not with GCI’s methods for giving a customized look and feel to forms, reports, and workflow user steps. Guess, I’ll have to investigate.

These are likely very different implementations. Do the CGI Tools allow inline form validation? What’s cool about RHForm is that validation can be as complex as you need and the error will display inline. For example, in one recent project I validated the form against an online Web Service to ensure the input was correct and the error displayed inline.

Does RHCore stand for Request Handler Core?

The letters “RH” are the initials of my company Red House Consulting GmbH. I use the prefix often to minimise naming conflicts and to quickly identify my code.

Does Open Text ever recommend that a person use RHCore, as you have done?

I’ve received great feedback from some OpenText employees, but haven’t received a public endorsement.

RHCore get changed with every release of CS, you the 90 day releases?

RHCore doesn’t have a formal release cycle because it hasn’t been necessary yet. The code doesn’t rely too much on stuff that changes in Content Server with each release. There are a few exceptions, but I deal with them as they come (and it’s usually something small and easy to handle).

Is overriding RHCore, more of a safe bet than other overrides?

RHCore provides a few tools for overriding core code, but the best tool always depends on the situation (which usually comes from experience). But let me give you an example: I’m working with an OpenText Partner to create a complex module with many overrides. I made a point of keeping the intrusiveness of the overrides as minimal as possible (using the tools from RHCore). The result has been great: We development on CS10 and it all works on CS10.5 as well. This means having only one code stream to maintain (instead of one for CS10 and another for CS10.5), which has saved us an immense amount of time and money.

Thanks for your comment and questions! I’d be happy to show you and your team a demo if you’d be interested.

Like John I am forever amazed by the great capabilities of Oscript and really happy to know you and Patrick.It is a pity that Oscript did not receive its due in mainstream programming.I was trying hard to find a link a great OT guy gave me Chris Webster,I am pretty sure you all know him,but could not find it However I did find something similar in this link http://en.wikipedia.org/wiki/Frame_language.
To me it looks like Oscript has many many more years of useful life in this world 🙂

Thanks a lot for your today’s presentation. Two and a half hours of pure motivation – elegance and effectiveness of coding is possible in OScript even for seasonal developers like myself. If my next client will require development in OScript my answer will be – only with RHCore Framework!

This could be a very late comment
First this is for sure a good work as it is OO approach

But there is a more efficient approach in terms of transparency to the running environments, simplicity of use / manipulation, no dependency on OTCS version, fast (no extra layers of parsing & compilation) and no extra learning.

I am suggesting here using an xml representation for the
Node and its nested/related child nodes (actually I am using this approach without using a single OScript line).

To create code blocks or other preformatted text, indent by four spaces:

This will be displayed in a monospaced font. The first four
spaces will be stripped off, but all other whitespace
will be preserved.
Markdown is turned off in code blocks:
[This is not a link](http://example.com)