Generally speaking, IT organizations like to keep development code separate from production code. When development code is ready for production, good change management rules dictate a graduation/migration path, usually something like DEV > TEST > QA > PRO. Likewise, on occasion, a development team may request a fresh copy of a production database. With PeopleTools managed objects, we can easily migrate Application Designer projects between our environments without much concern for environment specific code. Pagelet Wizard created pagelets, however, are not managed objects and need to be migrated using Data Mover Scripts. Some pagelets, like Query pagelets, require managed objects in order to function. Other pagelets, like HTML pagelets may contain hard coded URL references to other DEV/TEST/QA/PRO servers. How can we effectively manage these URL's? Can we, as PeopleSoft developers, automate the process for updating these URL's?
As we know from experience, HTML data sources typically use the Passthru display format. Passthru means the HTML content from step 2 is displayed in the Pagelet without any processing or modification. Therefore, we can't leverage Meta-HTML or any other PeopleTools functionality to simplify the management of our HTML based pagelet. We can, however, create a new transformer and display type and have this new transformer perform additional processing to help us resolve this URL maintenance problem.
Now that we have a method for implementing additional processing, how shall we maintain the actual URL's? I recommend using node definitions. Node definitions contain a portal tab where we can enter a content and a portal URL. As delivered, PeopleTools uses these node URL's when creating real URL's from portal registry content references (CREF's). Using a custom transformer, we can leverage this existing Meta-data to dynamically generate the URL's included in HTML Pagelets.
What we need is a custom Transformer that can convert a URL placeholder into a full URL using database driven Meta-data. Keeping with PeopleTools convention, the solution below will demonstrate the creation of a transformer that resolves custom Meta-HTML tags. This custom transformer will expand the text %NodePortalURL(NODE_NAME)
into the Portal URL for that node. This will allow us to write Pagelet Wizard HTML like:
<img src="%NodePortalURL(NODE_NAME)/images/dynamic-chart.png"/>
And our custom transformer will translate this HTML into:
<img src="http://other.server.name:8080/images/dynamic-chart.png"/>
To implement this solution we need an Application Package to store our custom App Class. For demonstration purposes, we will call this Application Package CUSTOM_TRANSFORMERS
. I expect in your environment, you will prefix this new Application Package with your site specific prefix. In this new Application Package, we will add a new package called Transform
. And, to this new package, we will add the class NodePortalUrlTransformer
. This new class, NodePortalUrlTransformer
will contain the code required to implement our URL transformation feature. The path for our new Application Class should look something like CUSTOM_TRANSFORMERS:Transform:NodePortalUrlTransformer
. Here is the code you will need to paste into this new Application Class:
import PTPPB_PAGELET:UTILITY:*;
import PTPPB_PAGELET:Transformer:*;
import PTPPB_PAGELET:*;
/**
* Transforms Text by replacing %NodePortalURL(NODE_NAME) with the Portal URI
* of the node NODE_NAME.
*/
class NodePortalUrlTransformer extends PTPPB_PAGELET:Transformer:Transformer
method NodePortalUrlTransformer(&ID_param As string);
method execute(&pageletID As string) Returns string;
method Clone() Returns PTPPB_PAGELET:Transformer:Transformer;
end-class;
/**
* Constructor.
*
* @param id_param ID of this object. Should be unique.
*/
method NodePortalUrlTransformer
/+ &ID_param as String +/
%Super = create PTPPB_PAGELET:Transformer:Transformer(&ID_param);
end-method;
/**
* Replaces%NodePortalURL(NODE_NAME) with the Portal URI
* of the node NODE_NAME.
*
* @param pageletID ID of the pagelet being executed.
*/
method execute
/+ &pageletID as String +/
/+ Returns String +/
/+ Extends/implements PTPPB_PAGELET:Transformer:Transformer.execute +/
Local JavaObject &pattern;
Local JavaObject &matcher;
Local string &sourceText = %This.DataToTransform.Value;
Local string &transformedText = &sourceText;
Local string &nodeName;
Local string &nodeUrl;
REM ** Resolve %NodePortalURL tags;
&pattern = GetJavaClass("java.util.regex.Pattern").compile("(?i)%NodePortalURL\((\w+)\)");
&matcher = &pattern.matcher(CreateJavaObject("java.lang.String", &sourceText));
While &matcher.find()
&nodeName = &matcher.group(1);
If (&nodeName = "LOCAL_NODE") Then
&nodeName = %Node;
End-If;
SQLExec(SQL.GET_NODE_URI, &nodeName, "PL", &nodeUrl);
&transformedText = Substitute(&transformedText, &matcher.group(), &nodeUrl);
End-While;
&pattern = Null;
Return &transformedText;
end-method;
/**
* Make an exact copy of this object.
*
* @return Text Exact copy of this object
*/
method Clone
/+ Returns PTPPB_PAGELET:Transformer:Transformer +/
/+ Extends/implements PTPPB_PAGELET:Transformer:Transformer.Clone +/
Return create CUSTOM_TRANSFORMERS:Transform:NodePortalUrlTransformer(%This.ID);
end-method;
Keeping with good PeopleTools coding practices, the code above references a managed SQL object named GET_NODE_URI
. Here is the SQL for that SQL definition:
SELECT URI_TEXT
FROM PSNODEURITEXT
WHERE MSGNODENAME = :1
AND URI_TYPE = :2
Now that we have our code in place, we need to register our new Transformer so we can use it in our HTML pagelets. Rich Manalang wrote up an excellent transformer tutorial following the same steps, but his includes pictures. You can find a link to his tutorial below.
We will start by registering the Transform Type. Navigate to:
Portal Administration > Pagelets > Pagelet Wizard > Define Transform Types > Add
On this page, you will need to give your Transform Type a name, a description, and specify the implementing Application Class. If you have been following this example, then use the following values:
Transformation Type: NODE_PORTAL_URL
Description: Resolve Node URL Meta-HTML
Package Name: CUSTOM_TRANSFORMERS
Path: Transform
Application Class ID: NodePortalUrlTransformer
Next, you will need to define a Display Format that corresponds to your new Transform Type. Navigate to:
Portal Administration > Pagelets > Pagelet Wizard > Define Display Formats > Add
You can use the following values to define your new display format. Again, the Define Display Formats graphic on Rich's post applies. In fact, the only values you need to change are the Display Format ID, Description, and Transform Type. For reference, I've repeated the values below:
Display Format ID: NODE_PORTAL_URL
Description: Resolve Node URL Meta-HTML
Transform Type: NODE_PORTAL_URL
Page Name: PTPPB_WIZ_DISP_PST
Package Name: PTPPB_PAGELET
Path: TransformBuilder
Application Class ID: PassthroughBuilder
The last step is to associate our new Display Format with the HTML Data Type. Navigate to:
Portal Administration > Pagelets > Pagelet Wizard > Define Data Types
Select the HTML
Data Type. At the bottom of this page, in the section titled Display Formats to use with this Data Type, we need to add our new Display Format: NODE_PORTAL_URL
. After you save, your configuration and development for your new transformer is complete. You may now use this new Meta-HTML character sequence in your Pagelet Wizard HTML Pagelets.
The Enterprise Portal's Pagelet Wizard is one of my favorite productivity and usability tools. One of it's key features is its extensibility. The Pagelet Wizard contains components that allow you to register your own data sources, display types, and transformations. Likewise, the Internet Technology PeopleBook contains a section devoted to Pagelet Wizard configuration, customization, and usage. If you prefer examples over PeopleBooks, you can open and view the delivered Pagelet Wizard Application Packages in Application Designer. If you are interested in creating your own data source, tranformer, or display type, you may find a delivered Application Class you can copy and modify.
Additional resources: