Wednesday, December 31, 2014

PeopleTools 8.54 - Branding - Part 3

This post is a continuation of my previous articles on Branding PeopleTools 8.54 applications.

Part 1 detailed the basics of what's new with Branding in PeopleTools 8.54 and provided steps to change the logo of the application. Part 2 detailed steps to achieve several common branding requirements such as changing the background color of the branding header, changing the background color and the font color of the Navigation Drop-Down Menu, changing the font color of the Branding System Links, adding a hyperlink to the Branding Logo, moving branding elements (div) using css and adding database name to the Branding Header. We were able to perform all these tasks simply by using the online configuration pages for Branding provided as part of PeopleTools 8.54.

In this post we will dive into some of the more advanced Branding requirements that may potentially require the use of Application Designer.

Branding the Timeout Popup Warning Message:




What is this popup and where is it coming from? This popup message is the PeopleSoft delivered Timeout Warning Message that is displayed to warn the user of an impending timeout of their session (due to inactivity).

If we examine the URL of this Popup message we can see that it is generated by an IScript.

http://pt854.hcm92.com:8000/psc/ps/EMPLOYEE/HRMS/s/WEBLIB_TIMEOUT.PT_TIMEOUTWARNING.FieldFormula.IScript_TIMEOUTWARNING

This IScript is configured on the web profile which is currently being used by the web server.

PeopleTools > Web Profile > Web Profile Configuration (Security Tab)



In the screenshot above, we can see the configuration that triggers this popup message. A handy tip while testing changes to the timeout warning is to change the "Inactivity Warning" seconds to a shorter period like 120 or 180 seconds. This helps in triggering the popup without having to wait for extended periods of time (Note: Any changes to the web profile requires a reboot of the web server to take effect).

As this popup is generated through an IScript, I don't see a way we can override the Oracle Logo on the popup by overriding the stylesheet or by using other Branding Configuration.

There are two ways we can go about this customization:
1. Create a custom IScript that is a clone of the delivered IScript and then perform all customizations in the custom IScript. This option requires us to update the Web Profile to Override the Timout Warning Script to reference our custom IScript.
2. Simply customize the delivered IScript.

For the purposes of this post, I would be customizing the delivered IScript (second option) because I just want to replace the Oracle Logo with my custom logo.

- Update Timeout Warning IScript:

Open IScript Record PeopleCode using App Designer.



Change the reference to the Oracle Logo (Image.NEW_PS_LOGO) to use Custom Logo.

Customized Timout Warning IScript Code:

Declare Function SetDocDomainForPortal PeopleCode FUNCLIB_PORTAL.TEMPLATE_FUNC FieldFormula;
Declare Function PTGetStyleSheetURL PeopleCode FUNCLIB_PORTAL.PORTAL_GEN_FUNC FieldFormula;

Function IScript_TIMEOUTWARNING()
   &howLong = %Request.Timeout * 1000 - %Request.WarningTimeout * 1000 - 2000;
   &timeoutWarningMsg = MsgGetText(146, 91, "Your session is about to be timed out. As a security precaution, sessions end after ");
   &timeoutWarningMsg = &timeoutWarningMsg | " " | Integer(%Request.Timeout / 60) | " " | MsgGetText(146, 92, "minutes of inactivity. Click OK to continue your current session.");
   
   &domainScript = SetDocDomainForPortal();
   
   /* CSK - Timeout Warning Logo Customization - Start */
   
   rem commenting delivered code &HTML = GetHTMLText(HTML.PT_TIMEOUTWARNING, PTGetStyleSheetURL(), %Response.GetJavaScriptURL(HTML.PT_SAVEWARNINGSCRIPT), &howLong, %Response.GetImageURL(Image.NEW_PS_LOGO), &timeoutWarningMsg, %Request.ResetTimeoutURL, %Response.GetImageURL(Image.PT_OK), MsgGetText(146, 95, "Please - note"), &domainScript);
   &HTML = GetHTMLText(HTML.PT_TIMEOUTWARNING, PTGetStyleSheetURL(), %Response.GetJavaScriptURL(HTML.PT_SAVEWARNINGSCRIPT), &howLong, %Response.GetImageURL(Image.CSK_LOGO), &timeoutWarningMsg, %Request.ResetTimeoutURL, %Response.GetImageURL(Image.PT_OK), MsgGetText(146, 95, "Please - note"), &domainScript);
   
   /* CSK - Timeout Warning Logo Customization - End */
   
   %Response.Write(&HTML);
End-Function;

Notice that I commented the delivered line and replaced it with a custom line which references the custom logo image (Image.CSK_LOGO).

- Test Changes:



Display Dynamic and User Specific Greeting Message using Custom Branding Elements:


In this section we will examine how we can replace the delivered ptgreetingmessage Branding Element with a custom Branding Element.



We can see from the screenshot that the ptgreetingmessage element is using the Branding Element Type of Greeting Message.

The Branding Element Type Configuration can be found in the following navigation:

PeopleTools > Portal > Branding > System Data > Define Element Types



We can see that the delivered Greeting Message is being generated by the Application Class PTBR_BRANDING.SystemElements.GreetingText (review class implementation in App Designer to understand how the greeting message is generated).

Before we can go ahead and add a custom element (using a custom element type) to the Branding Header, we must create the custom branding element type and also develop the application class that supports this element type.

- Create Supporting Application Class for Custom Branding Element Type:

Create Custom Application Package.



Create Custom Application Class.

Note: The custom Application Class CSKGreetingText is cloned and improvised from PTBR_BRANDING.SystemElements.GreetingText.

import PTBR_BRANDING:Elements:BaseElement;

/**
  * CSKGreetingText Class
  */
class CSKGreetingText extends PTBR_BRANDING:Elements:BaseElement
   /* --- Properties --- */
   
   /* --- Methods --- */
   method CSKGreetingText(&pId As string);
   method clone() Returns PTBR_BRANDING:Elements:BaseElement;
   
   method getHTML(&pPreview As boolean) Returns string;
  
end-class;

/**
  * Constructor
  *
  * @param pId ID of the object.
  *
  */
method CSKGreetingText
   /+ &pId as String +/
   
   %Super = create PTBR_BRANDING:Elements:BaseElement(&pId);
   
   %This.setElementType("CSKGreetingText");
   rem %this.setAdvancedOptionsPage (Page.);
   
   /* Initialize attributes */
   %This.StyleClass = "cskgreeting";
   
end-method;

/**
  * Make an exact copy of this object.
  * NOTE: Only create the object here, do not copy any class properties.
  *       If there are new class properties, override the copyProperties
  *       method and do it there.  Should invoke the %Super.copyProperties
  *       in that method though.
  *
  * @return BaseElement New object exactly matching this object.
  *
  */
method clone
   /+ Returns PTBR_BRANDING:Elements:BaseElement +/
   /+ Extends/implements PTBR_BRANDING:Elements:BaseElement.clone +/
   
   Local CSK_BRANDING:SystemElements:CSKGreetingText &newObj = create CSK_BRANDING:SystemElements:CSKGreetingText(%This.ID);
   
   /* Call the copy properties function */
   %This.copyProperties(&newObj);
   
   Return &newObj;
   
end-method;


/**
  * Get HTML of the element
  *
  * @param pPreview  True - preview mode.
  *
  * @return String - HTML
  *
  */
method getHTML
   /+ &pPreview as Boolean +/
   /+ Returns String +/
   /+ Extends/implements PTBR_BRANDING:Elements:BaseElement.getHTML +/
   
   Local string &getHTML = "";
   
   Local ApiObject &portalObj;
   
   If (&pPreview) Then
      &getHTML = EscapeHTML(MsgGetText(25000, 3, "<message not found> Sample Greeting Text"));
   Else
      
      <* Commenting Delivered Greeting
      &portalObj = %This.Utility.PortalRegistry;
      If (All(&portalObj)) Then
         &getHTML = EscapeHTML(&portalObj.Homepage.Greeting);
      End-If;
      *>
      
      &getHTML = EscapeHTML("Welcome to CSK " | %UserDescription);
      
   End-If;
   
   &getHTML = GetHTMLText(HTML.PTBR_ELM_CONTAINER_SPAN, EscapeHTML(%This.ID), EscapeHTML(%This.StyleClass), &getHTML);
   
   Return &getHTML;
   
end-method;

In the custom PeopleCode above, we have added logic to generate a dynamic and personalized greeting message that displays the text "Welcome to CSK " appended with the User's Description text using the %UserDescription system variable. Note: The type of greeting could vary significantly from organization to organization and this can be addressed appropriately in the getHTML method implementation.

- Create Custom Branding Element Type:

PeopleTools > Portal > Branding > System Data > Define Element Types



We can see in the screenshot that we are referencing our custom CSKGreetingText Application Class in the new Element Type (CSK_GREETING_TEXT).

- Create custom style for Custom Greeting Message:



#pthdr2container.pthdr2container #cskgreetingmessage.cskgreeting {
    position: absolute;
    right: 0;
    bottom: 0;
    color: #426a92;
    font-family: Arial,Helvetica,sans-serif;
    font-size: 12pt;
    font-weight: normal;
}

- Delete delivered ptgreetingmessage element from the Branding Header:



- Add custom greeting element to the Branding Header:





- Test Changes:

Recommendations if you are experiencing caching issues:
  1. Clear local browser cache.
  2. Shutdown, purge cache and reboot the web server(s).








We can see in the screenshot that some of the links on the Branding Header such as MultiChannel Console are not specifically useful for a majority of the users. Links such as Process Monitor and Report Monitor would be a lot more useful on the Branding Header (this requirement is well documented in the PeopleSoft Wiki blog post).

Let us see how we can remove the 'MultiChannel Console' link and add links to Process Monitor and Report Monitor on the header in PeopleTools 8.54.

- Create Custom Supporting Application Classes for Process Monitor and Report Monitor:



Application Class Implementation for Process Monitor: 

Note: This Application Class was cloned and improvised from PTBR_BRANDING.SystemElements.WorklistLink Application Class.

import PT_BRANDING:HeaderLinkPIA;

import PTBR_BRANDING:Elements:BaseElement;
import PTBR_BRANDING:SystemElements:SystemLink;
import PTBR_BRANDING:UTILITY:Utility;

/**
  * ProcessMonitorLink Class
  */
class ProcessMonitorLink extends PTBR_BRANDING:SystemElements:SystemLink
   /* --- Properties --- */
   
   /* --- Methods --- */
   method ProcessMonitorLink(&pId As string);
   method clone() Returns PTBR_BRANDING:Elements:BaseElement;
   
protected
   /* --- Protected properties --- */
   
   /* --- Protected Methods --- */
   method setupLink(&pPreview As boolean);
   
private
   /* --- Private Properties --- */
   Constant &cstCTIConsole = "PopupCTIConsole();";
   Constant &cstMCFConsole = "PopupMCFConsole();";
   
   /* --- Private Methods --- */
   
end-class;

/**
  * Constructor
  *
  * @param pId ID of the object.
  *
  */
method ProcessMonitorLink
   /+ &pId as String +/
   
   %Super = create PTBR_BRANDING:SystemElements:SystemLink(&pId);
   
   %This.setElementType("ProcessMonitorLink");
   rem %this.setAdvancedOptionsPage (Page.);
   
   /* Initialize attributes */
   %This.Label.setMessageText(25000, 1, "Process Monitor");
   
end-method;

/**
  * Make an exact copy of this object.
  * NOTE: Only create the object here, do not copy any class properties.
  *       If there are new class properties, override the copyProperties
  *       method and do it there.  Should invoke the %Super.copyProperties
  *       in that method though.
  *
  * @return BaseElement New object exactly matching this object.
  *
  */
method clone
   /+ Returns PTBR_BRANDING:Elements:BaseElement +/
   /+ Extends/implements PTBR_BRANDING:SystemElements:SystemLink.clone +/
   
   Local CSK_BRANDING:SystemElements:ProcessMonitorLink &newObj = create CSK_BRANDING:SystemElements:ProcessMonitorLink(%This.ID);
   
   /* Call the copy properties function */
   %This.copyProperties(&newObj);
   
   Return &newObj;
   
end-method;

/*****************************
*   Protected methods
*****************************/

/**
  * Setup the link properties
  *
  */
method setupLink
   /+ &pPreview as Boolean +/
   
   Local ApiObject &crefObj;
   
   Local PTBR_BRANDING:UTILITY:Utility &utility = %This.Utility;
   
   Local string &linkUrl = "";
   
   If (&pPreview) Then
      %Super.setupLink(&pPreview);
   Else
      
      &crefObj = &utility.PortalRegistry.FindCRefByName("PT_PROCESSMONITOR_GBL");
      
      If (All(&crefObj) And
            &crefObj.Authorized And
            &crefObj.IsVisible) Then
         
         If ((&utility.HeaderLink As PT_BRANDING:HeaderLinkPIA) <> Null) Then
            &linkUrl = &crefObj.AbsolutePortalURL;
         Else
            &linkUrl = &crefObj.RelativeURL;
         End-If;
         
         %This.URL = &linkUrl;
         
      End-If;
      
   End-If;
   
end-method;

Application Class Implementation for Report Manager:

import PT_BRANDING:HeaderLinkPIA;

import PTBR_BRANDING:Elements:BaseElement;
import PTBR_BRANDING:SystemElements:SystemLink;
import PTBR_BRANDING:UTILITY:Utility;

/**
  * ReportManagerLink Class
  */
class ReportManagerLink extends PTBR_BRANDING:SystemElements:SystemLink
   /* --- Properties --- */
   
   /* --- Methods --- */
   method ReportManagerLink(&pId As string);
   method clone() Returns PTBR_BRANDING:Elements:BaseElement;
   
protected
   /* --- Protected properties --- */
   
   /* --- Protected Methods --- */
   method setupLink(&pPreview As boolean);
   
private
   /* --- Private Properties --- */
   Constant &cstCTIConsole = "PopupCTIConsole();";
   Constant &cstMCFConsole = "PopupMCFConsole();";
   
   /* --- Private Methods --- */
   
end-class;

/**
  * Constructor
  *
  * @param pId ID of the object.
  *
  */
method ReportManagerLink
   /+ &pId as String +/
   
   %Super = create PTBR_BRANDING:SystemElements:SystemLink(&pId);
   
   %This.setElementType("ReportManagerLink");
   rem %this.setAdvancedOptionsPage (Page.);
   
   /* Initialize attributes */
   %This.Label.setMessageText(25000, 2, "Report Manager");
   
end-method;

/**
  * Make an exact copy of this object.
  * NOTE: Only create the object here, do not copy any class properties.
  *       If there are new class properties, override the copyProperties
  *       method and do it there.  Should invoke the %Super.copyProperties
  *       in that method though.
  *
  * @return BaseElement New object exactly matching this object.
  *
  */
method clone
   /+ Returns PTBR_BRANDING:Elements:BaseElement +/
   /+ Extends/implements PTBR_BRANDING:SystemElements:SystemLink.clone +/
   
   Local CSK_BRANDING:SystemElements:ReportManagerLink &newObj = create CSK_BRANDING:SystemElements:ReportManagerLink(%This.ID);
   
   /* Call the copy properties function */
   %This.copyProperties(&newObj);
   
   Return &newObj;
   
end-method;

/*****************************
*   Protected methods
*****************************/

/**
  * Setup the link properties
  *
  */
method setupLink
   /+ &pPreview as Boolean +/
   
   Local ApiObject &crefObj;
   
   Local PTBR_BRANDING:UTILITY:Utility &utility = %This.Utility;
   
   Local string &linkUrl = "";
   
   If (&pPreview) Then
      %Super.setupLink(&pPreview);
   Else
      
      &crefObj = &utility.PortalRegistry.FindCRefByName("PT_CONTENT_LIST_GBL");
      
      If (All(&crefObj) And
            &crefObj.Authorized And
            &crefObj.IsVisible) Then
         
         If ((&utility.HeaderLink As PT_BRANDING:HeaderLinkPIA) <> Null) Then
            &linkUrl = &crefObj.AbsolutePortalURL;
         Else
            &linkUrl = &crefObj.RelativeURL;
         End-If;
         
         %This.URL = &linkUrl;
         
      End-If;
      
   End-If;
   
end-method;

- Create custom Branding Element Types for Process Monitor and Report Manager Links:





Note: Each Branding Element Type is referencing its corresponding custom supporting Application Class.

- Delete 'MultiChannel Console' and 'Performance Trace' links from Branding Header:





- Add Process Monitor and Report Monitor Elements to Branding Header:









- Test Changes:

Recommendations if you are experiencing caching issues:
  1. Clear local browser cache.
  2. Shutdown, purge cache and reboot the web server(s).





Implementing Google Analytics:


Google Analytics is a free service that is offered by Google that helps us gather statistics on traffic, traffic sources, conversions, page visits and other useful information about websites.

There are some good presentations on the Higher Education User Group (HEUG) forum for more details on how organizations are using Google Analytics to track, monitor and analyze PIA traffic in PeopleSoft Applications.

To enable Google Analytics we need to create a new property using a google account. This would generate a tracking id that is specific to our website (property).

The tracking id is a string like UA-XXXXXX-Y where XXXXXX represents the account number and Y represents the property number.

Once we obtain the tracking id it is very easy to enable Google Analytics in a PeopleSoft Application. All we need to do is inject the Google Analytics javascript into our PeopleSoft Application.

Google Analytics JavaScript:

<script type="text/javascript">

  var _gaq = _gaq || [];
  _gaq.push(['_setAccount', 'UA-XXXXX-Y']);
  _gaq.push(['_trackPageview']);

  (function() {
    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
  })();

</script>

In the past (prior to PeopleTools 8.54), we would have had to insert the Google Analytics into our Branding Header or even at the template level (E.g.: PT_HNAV_TEMPLATE, PT_HNAV_TEMPLATE_INCLUDE).

With PeopleTools 8.54, it is very easy to inject JavaScript without any customizations.

- Create JavaScript Object for Google Analytics:



- Include Custom JavaScript Object on the Branding Systems Options Page:



Note: In this example, I am using the latest Asynchronous Syntax provided by Google which allows us to place/inject the JavaScript at any location (including the head) in the html without any page rendering performance issues.

- Test Changes:







Note: This post is only intended to provide information on how to implement Google Analytics in a PeopleSoft Application. This post does not cover details on how to use Google Analytics. There are several online resources that are available to understand the various ways to use the statistical data captured by Google Analytics both from a functional and technical point of view.

Migrating Branding to other environments:


Over the three part series of blogs, we have seen how we can achieve several Branding requirements in PeopleTools 8.54. Now let us look at how we can migrate all the objects we created using both app designer and online configuration pages.

Let us take stock of all the objects that we created and include them in project for migration.

- Include all the Images created for Branding:





- Include all the Style Sheets created for Branding:





- Include all the JavaScript Objects created for Branding:





- Include any URL definitions created for Branding:



Note: This URL definition was used as the Hyperlink URL for the Logo Image (in Part 2).

- Include all Application Classes created for Branding:



- Include Weblib Customization for Timeout Warning:



- Include all Message Catalog Entries created for Branding:



Note: These message catalog entries are referenced in the Application Classes created for supporting Branding Element Types.

- Migrating configuration that are not PeopleTools Managed Objects:

In all the posts detailing Branding in 8.54 we have tried to use the Branding Configuration Pages wherever we could. This is great from a quick development turn around and maintenance point of view. But how do we migrate these configurations (themes, headers, footers, branding element types, etc)? These configurations are not PeopleTools Managed Objects (yet!).

To overcome this challenge, PeopleSoft has delivered export/import dms scripts for these configurations. The scripts can be found in the following location on the app server:

/$PS_HOME/scripts/
    ptbr_setup_exp.dms
    ptbr_setup_imp.dms
    ptbr_theme_exp.dms
    ptbr_theme_imp.dms



Migrating Branding Element Types and User Attribute Types:

Use ptbr_setup_exp.dms to export these configurations from the source environment and ptbr_setup_imp.dms to import these configurations to the target environment.

The main tables that store these configurations are:
PS_PTBR_ETYPE
PS_PTBR_ETYPE_LN
PS_PTBR_UATYPE
PS_PTBR_UATYPE_LN

In our examples we created 3 custom Branding Element Types for the following:
- Greeting Message
- Process Monitor Link
- Report Manager Link

Note: We will need to update the exports scripts appropriately to include our custom Branding Element Types.

E.g.:

EXPORT PS_PTBR_ETYPE WHERE PTBR_ETYPE_ID IN ('CSK_GREETING_TEXT', 'CSK_PROCESSMONITOR_LINK', 'CSK_REPORTMANAGER_LINK');

Migrating Themes, Header and Footer Definitions:

Use ptbr_theme_exp.dms to export these configurations from the source environment and ptbr_theme_imp.dms to import these configurations to the target environment.

The main tables that store these configurations are:
PS_PTBR_THEME
PS_PTBR_THEME_LN
PS_PTBR_THMATTR
PS_PTBR_THMATTR_LN
PS_PTBR_THEME_CSS
PS_PTBR_THEME_DEL
PS_PTBR_LAYOUT
PS_PTBR_LAYOUT_LN
PS_PTBR_LTATTR
PS_PTBR_LTATTR_LN
PS_PTBR_LTELT
PS_PTBR_LTELT_LN
PS_PTBR_LTELTAT
PS_PTBR_LTELTAT_LN

In our examples we created a custom Theme and a custom Header Definition.

Note: We will need to update the exports scripts appropriately to include our custom Branding Definitions.

E.g.:

-- Export theme definitions

EXPORT PS_PTBR_THEME WHERE PTBR_THEME_ID IN ('CSK_THEME_TANGERINE');
-- EXPORT PS_PTBR_THEME_LN WHERE PTBR_THEME_ID IN ('CSK_THEME_TANGERINE');
EXPORT PS_PTBR_THMATTR WHERE PTBR_THEME_ID IN ('CSK_THEME_TANGERINE');
-- EXPORT PS_PTBR_THMATTR_LN WHERE PTBR_THEME_ID IN ('CSK_THEME_TANGERINE');
EXPORT PS_PTBR_THEME_CSS WHERE PTBR_THEME_ID IN ('CSK_THEME_TANGERINE');
EXPORT PS_PTBR_THEME_DEL WHERE PTBR_THEME_ID IN ('CSK_THEME_TANGERINE');


-- Export header/footer definitions

EXPORT PS_PTBR_LAYOUT WHERE PTBR_LAYOUT_ID IN ('CSK_HEADER_TANGERINE');
-- EXPORT PS_PTBR_LAYOUT_LN WHERE PTBR_LAYOUT_ID IN ('CSK_HEADER_TANGERINE');
EXPORT PS_PTBR_LTATTR WHERE PTBR_LAYOUT_ID IN ('CSK_HEADER_TANGERINE');
-- EXPORT PS_PTBR_LTATTR_LN WHERE PTBR_LAYOUT_ID IN ('CSK_HEADER_TANGERINE');
EXPORT PS_PTBR_LTELT WHERE PTBR_LAYOUT_ID IN ('CSK_HEADER_TANGERINE');
-- EXPORT PS_PTBR_LTELT_LN WHERE PTBR_LAYOUT_ID IN ('CSK_HEADER_TANGERINE');
EXPORT PS_PTBR_LTELTAT WHERE PTBR_LAYOUT_ID IN ('CSK_HEADER_TANGERINE');
-- EXPORT PS_PTBR_LTELTAT_LN WHERE PTBR_LAYOUT_ID IN ('CSK_HEADER_TANGERINE');

Message Catalog Entries created for Reference:


54 comments:

  1. Excellent Post Sasank.. It was very useful.. Thanks for all the Branding 8.54 lessons

    ReplyDelete
    Replies
    1. You are welcome! Thanks for the feedback. :)

      Delete
  2. @Sasank - How can we bring in our own HTML tags for the branding 8.54 header? For ex : If we define headers in the Branding Page of PIA. we get div tags for the pthdr2links etc. I want that div to be changed as ul. Can you please advice me on the HTML definition name to be used in this case.

    ReplyDelete
    Replies
    1. Very good question and use case.

      If we use Basic HTML then it will always enclose everything in a DIV element. This is because of the app package code that references the html object PTBR_ELM_CONTAINER_DIV.

      Refer App Package: PTBR_BRANDING.Element.BasicHTML.OnExecute
      method getHTML
      /+ &pPreview as Boolean +/
      /+ Returns String +/
      /+ Extends/implements PTBR_BRANDING:Elements:BaseElement.getHTML +/

      Local string &getHTML = "";

      &getHTML = GetHTMLText(HTML.PTBR_ELM_CONTAINER_DIV, EscapeHTML(%This.ID), EscapeHTML(%This.StyleClass), %This.HTML.getRuntimeValue());

      Return &getHTML;

      end-method;

      For your requirement, you will have to first create your own 'Branding Element Types' and call it something like BASIC_UL (instead of BASIC_HTML).
      Navigation: PeopleTools > Portal > Branding > System Data > Define Element Types

      This should be fairly easy process (similar to how I cloned the WORKLIST_LINK element in this post) and you can use BASIC_HTML as your reference and modify your custom app class accordingly.

      Once you create your own 'Branding Element Type' (BASIC_UL), you can then use that in your header definition to create your UL elements.

      Hope this helps!

      Delete
  3. Hi Sasank,
    We have recently upgraded the Tools to 8.54 and we are seeing the HCM top main menu navigation on top of branding in PORTAL environmnet. We are getting these enabled only when we try click on any links on portal like Job Information and Personal Information pages. Please let me know if these can be handled at any configuration or setup level.
    I am also thinking of the security permission lists which might have got overridden or defaulted. Please advice!!

    Thanks,
    Sid

    ReplyDelete
  4. @Siddharth M - I apologize for the delay in responding. I was on leave for a few weeks.

    I have not tried integrating HCM with PORTAL (Interaction Hub) yet.

    What version of Tools is your PORTAL environment currently on? Is it on a lower release compared to your HCM?

    If so, from my understanding I believe the PORTAL environment should always be on the highest Tools release. That might explain the problem you are facing.

    Also, can you share a screenshot of the issue?
    Thanks,
    Sasank

    ReplyDelete
  5. I thought I would update everyone about an issue with migrating the Branding Objects (e.g.: Style Sheets, Javascripts, HTML and Images) created using PeopleTools > Branding > Branding Objects.

    When we migrate the project containing these branding objects to another environment (say TST, PRD, etc), the objects are no longer available online for updates.

    While I understand that this is working as per PeopleTools design, I believe that there should be an option for branding objects created/migrated via App Designer to be made available for online updates (via a setting in App Designer?). Otherwise, we would need to go through a lot of manual object creation/update via the PIA for migrations.

    I raised a Service Request with Oracle on this topic.

    Initially, I was advised to use Data Migration Workbench for this task. This did not make sense at all (why would we reinvent the wheel when we have a perfectly alright migration process using App Designer?). Also, I cannot imagine all the work we need to put in to use the Data Migration Workbench if it was possible (creating data sets, exporting and importing data). I can completely understand having to use Data Migration Workbench for Branding Theme, Header and Footer definitions which are considered as configuration data. But to use it for PeopleTools managed objects like style sheets, javascripts, images and html does not seem like a good idea.

    I also brought it to their attention that there are no delivered data sets available for “Branding Objects” even if we were to consider using Data Migration Workbench. Only data set that is available (as delivered) is for Branding Element Types (PTBR_ELEMENT_TYPE).

    Latest update we received from Oracle Support is that they recognize the problem and are awaiting further feedback from Development. As of now, “seems that the only way to copy the objects from Branding Objects is to manually create them in the target database.”

    ReplyDelete
  6. If any of you think that you would also benefit from this feature then please raise a service request with Oracle. The more people requesting an enhancement the more chances of it being addressed. Thanks!

    ReplyDelete
  7. I found a workaround for the migration issue I mentioned above. Please refer:
    http://pe0ples0ft.blogspot.com/2015/04/peopletools-854-branding-objects.html

    ReplyDelete
  8. Please refer to the following Oracle Doc ID:
    E-PORTAL: Managed Branding Objects are not Accessible in the Target Environment After Migration (Doc ID 2011383.1)

    I finally managed to get Oracle to log this as a bug and also provide a workaround based on some of the SQLs I provided.

    ReplyDelete
  9. Great post Sasank!

    Thanks for putting the information out there :-)

    ReplyDelete
  10. Hi Nicholas - Great to hear from you. :)

    Thanks for the feedback!

    ReplyDelete
  11. Hi Sasank
    I am working on branding implementation for our client. We have upgraded our system to PT8.54.13 and PIH 9. We are using some third party javascript and stylesheets for our pagelet content display. We have those third party js and css files in the web server. In the earlier version, we used to include them in the branding header html. But now we got away from Application branding and started implementing the branding which comes along with PeopleTools 8.54. Now my question is how can I insert the third party js and css files into the head tag of the html document.

    In the earlier branding, we had inserted the js like below.

    <script type="text/javascript" src="%bind(:52)/third_party/xxx/utils/xxx.js";gt;</script>

    But in new Tools branding how can I achieve the same? Please help me.

    Thanks in advance,
    Muthukumaran M R

    ReplyDelete
  12. @Muthukumaran - Great question.

    First thing you need to check is whether you really need to place those js and css files on the web server. If not, you can actually create these objects under PeopleTools > Portal > Branding > Branding Objects and then inject them using PeopleTools > Portal > Branding > Branding System Objects. Simple as that.

    If for some reason you still need to place the js and css files on the web server then you can use the following steps. FWIW, I had a similar requirement where a javascript had to be placed on the web server itself.

    - Place the js file under the domain directory on the web server:
    e.g.: /home/psadm2/psft/pt/8.54/webserv/peoplesoft/applications/peoplesoft/PORTAL.war/ps/

    - Create a new javascript object (call it something like CSK_INJECT_EXTERNAL_OBJ) using PeopleTools > Portal > Branding > Branding Objects. The javascript should have the following contents:
    document.write(unescape("%3Cscript src='/ps/csk_external_script.js' type='text/javascript'%3E%3C/script%3E"));

    - Now inject the javascript object (CSK_INJECT_EXTERNAL_OBJ created above) either using PeopleTools > Portal > Branding > Branding System Objects or by adding a Basic Javascript Element Type on your Header Definition (PeopleTools > Portal > Branding > Define Headers and Footers)

    Hope this helps!

    ReplyDelete
  13. Thanks for the reply Sasank.

    The third party plugin is a very big one with more than 4000 files and 600 folders. So I can't add all these files under Branding objects.

    I tried the above method of using JavaScript object. I also tried injecting <script> and <link> by adding 'Basic HTML' Element type on the Header definition. It is working fine. But one thing I found is that these included scripts and link tags go inside the body tag instead of head tag. How can I place them under head tag of HTML document. Is it right choice to place these third party js and css files inclusions in PORTAL_HP_USER_TEMPLATE and PT_HNAV_TEMPLATE which are high level HTML objects?

    ReplyDelete
  14. Muthu Kumaran,

    I don't think it matters if the scripts are placed in the head section or the body section of the HTML. There are several scripts that actually run on the body section also.

    Right now, when the scripts are in the body section, are you having any issues because of that? If not, I would not worry about it.

    Alternatively, you can inject your js object on the Branding System Objects. This would place the scripts in the head section of the HTML. Basically similar to what I detailed in my previous comment:

    I would suggest that if you can then you should try to avoid making any changes to PORTAL_HP_USER_TEMPLATE or PT_HNAV_TEMPLATE.

    ReplyDelete
  15. Hi Sasank,

    These blog posts have been really helpful. One thing that I am surprised with regards to the new Branding Framework is the inability to easily add Content References to the header. In your case, you ended up having to create 2 element types for Report Manager and Process Monitor. I wonder if there was a way to define a more generic element type like 'Portal Object' or 'Content Reference' that could take the CRef ID or the Portal Object ID as an attribute value

    Just a thought.

    Thanks,
    Tom

    ReplyDelete
    Replies
    1. @Tom - Great question! Thanks for asking.

      I originally went with the approach of creating custom Branding Element and associated App Classes to demonstrate the process of creating our own custom Branding Elements.

      If you want to just reference an existing Content Reference then you can do that using a 'Basic Link' element and referencing the appropriate CREF.

      Here is an example of how you can do just that:
      http://pe0ples0ft.blogspot.com/2015/09/peopletools-854-branding-part-4c.html

      Let me know if you have any other questions.
      Thanks!

      Delete
  16. How do we change the color of Greeting Text in PT8.54.

    ReplyDelete
    Replies
    1. If you are referring to the delivered "greeting message" then it is part of the ptgreetingmessage element.

      Navigation: Main Menu > PeopleTools > Portal > Branding > Define Headers and Footers
      Select DEFAULT_HEADER_TANGERINE

      You should see ptgreetingmessage under DEFAULT_HEADER_TANGERINE > pthdr2container.

      You can see that the style class for ptgreetingmessage is 'greeting'.

      So you can override this style with something like:
      #pthdr2container.pthdr2container .greeting {color: #000000;}

      Thanks!

      Delete
    2. Thanks Sasank. I just changed the color of the greeting text.
      If i want to migrate the changes to target environment. Do i need to export header/footer definitions through dms scripts or can i just go the target environments and add the CSS line to the style definition. What is the better way?Please advice.

      Delete
    3. If you are doing just a small style change, then you can just use your judgement and do the online configuration change.

      But if you are migrating a whole bunch of header changes and/or migrating a new theme for branding then you are almost always better off doing it via the delivered dms scripts (or improvised SQL scripts).

      Hope this helps!

      Delete
    4. Thanks Sasank.

      Delete
  17. Sasank, thanks for sharing the 8.54 branding information - it's proved very helpful as we upgrade! I don't know if you have experience with setting up a Candidate Gateway site for external applicants on HCM 9.2, but we want to show our standard logo on the portal header on the external applicant CG site component, but suppress the dropdown menu, links and portal search box using a style setting of display-none. Since component-level branding doesn't appear to work, do you have any thoughts on an alternative way to do this?

    ReplyDelete
    Replies
    1. @Criss - You are welcome! Glad to hear these posts were useful.

      I am familiar with the Candidate Gateway external site for HCM 9.2. In most cases that I have seen, the Candidate Gateway set up is such that it has a different hostname and/or is set up as a different site. Basically, there will be a difference in the URI with regards to the hostname and/or sitename.

      Off hand, I can think of one option which is to use the request URI to differentiate the external site and hide the branding element in javascript.

      Here is a quick post I wrote on this topic which might be easier to explain with screenshots (which is not possible in the blogger comments).
      http://pe0ples0ft.blogspot.com/2015/11/peopletools-854-branding-part-4d.html

      I am sure there are other options as well. If there is concern over DOM manipulation using javascript and all the associated code running on the client side, you could also figure out a way to conditional hide this using PeopleCode on the server side (based on the %Request class). This might involve a little more effort and potential customizations to the Branding app packages/IScripts.

      Let me know your thoughts/suggestions! Thanks!

      Delete
    2. Thanks, Sasank. I'm experimenting with your suggested approach now and so far, so good!

      Delete
  18. Sasank, thanks for sharing the branding information.

    Quick question - we wanted to add an external link and new window link on the home page. Tried same way as your Report manager but it's opening in the current window, Is there a way we can open in a new window.

    Thanks in advance .

    ReplyDelete
    Replies
    1. @Mike - Yes. This can be done easily.

      You might want to review the following post where I describe how to use a 'Basic Link' element type instead of using a custom branding element (such as the one we created for Report Manager using custom app package).

      http://pe0ples0ft.blogspot.com/2015/09/peopletools-854-branding-part-4c.html

      Your steps will be very similar. While selecting the 'Attribute Type' for the URL attribute you might want to use either a 'Static URL' or 'URL Object' instead of 'Portal URL'. This will allow you to reference an external link per your requirement.

      You will also notice that there is an attribute called 'Target' which is defaulted to '_top'. You will need to change that to '_blank' to open the link in a new window.

      Let us know if you still run into issues getting this to work. Thanks!

      Delete
  19. Thanks Sasank.

    Still no luck. Changed to static link and changed 'Target' with '_blank' , still opens in the same window.

    ReplyDelete
    Replies
    1. Mike - I just tested the 'Static URL' with target = '_blank' and it seems to work.

      Here are some screenshots:
      http://pe0ples0ft.blogspot.com/p/branding-steps-to-add-external-link-to.html

      Wonder if it is caching. Did you try clearing your browser and web server cache?

      Delete
  20. Sasank - Thanks for the screenshots. I have tried same as your screenshots, also recycled the cache. Still no luck,opening in the same window. Also we wanted to add "Newwindow" as a link next to the Home button to open another Tab. Any help is very much appreciated. Thanks

    ReplyDelete
    Replies
    1. Mike - Can you share some screenshots? The steps I mentioned should work.

      With the "newwindow", what content should open in the new tab? Are you expecting the new window to display the homepage or the previous content page?

      Delete
    2. I am facing the same issue as Mike mentioned. It is still opening in same window ( in stead of new). If any of you figured out further on this, please help to share. thanks much in advance.

      Delete
    3. Not sure what is the cause for the issue you are experiencing. I have demonstrated here: http://pe0ples0ft.blogspot.com/p/branding-steps-to-add-external-link-to.html that an external URL opens in a new window. Further, I tested this now in all browsers and it works as expected on IE, FireFox and Chrome. Are you setting the Target attribute to _blank?

      Delete
    4. @Mike and @newbee - If I understand your requirement correctly, you want to add the 'New Window' functionality on the Branding Header to open the current URL on a new window? Is this correct?

      Here is how I tried to add such functionality to my Classic Branding Header in 8.54. Hope this helps!
      https://pe0ples0ft.blogspot.com/2016/05/peopletools-854-branding-part-4e.html

      Delete
  21. We just now (6/2016) upgraded to 8.54 at my new gig so this info has been super-helpful. Thanks for making me look good! - Jason G

    ReplyDelete
  22. Excelent Post !
    But what if I've to display both 'Process Monitor' & 'Report Manager' under a single drop-down menu?

    Cheers,
    Tom.

    ReplyDelete
    Replies
    1. Hi Tom - It should be possible. You may want to take a look at how the 'Add To' functionality works on DEFAULT_THEME_TANGERINE_ALT theme in PeopleTools 8.54.

      https://pe0ples0ft.blogspot.com/2015/06/peopletools-854-branding-part-4b.html

      Delete
  23. my requirement is create a TEXT{example. ORACLE(font color blue)} upside of "Main Menu" and if i click "ORACLE" Oracle Page will open in new tab, can i know how to link a URL to TEXT(Oracle). plz contact amanp1419@gmail.com and its urgent. Thank-you.

    ReplyDelete
    Replies
    1. I don't have a direct solution to your requirements. You will need to configure/develop it on your own.

      I would recommend that you read this post (and the preceeding posts - Part 1 and Part 2) to understand how to update the Branding Header HTML as per your own custom requirements.

      Delete
  24. Hi i selected Type:"Basic html" and given "static html":abcdefghijkl in preview its working. but not in PIA page?? plz give solution ASAP.

    ReplyDelete
    Replies
    1. sorry.... in "static html" i have given HTML code(for header text)with URL its working in preview if i click TEXT another tab is opening, but not in PIA page?

      Delete
  25. Hi Sasank,

    In my DEV environment, I have a configuration setting I would like to migrate to my TEST environment.

    In DEV, within Branding, under Branding System Options, I have set "Additional Style Sheet Objects" to (a custom style sheet name). When I run the PSOFT scripts, it brings all the branding/styling stuff over to TEST but it does not set the (custom style sheet) under Additional Style Sheet Objects. Do I have to set that manually after a migration or is there some table I can DMS that will set it automatically. I am working in 8.55 if that makes a difference. Thank you!

    ReplyDelete
    Replies
    1. Great question! I am not aware of a delivered dms script for the Branding System Options configuration.

      But the table that you are looking for is PSOPTIONSADDL. Basically, you would need to export/import the data from this table. Alternatively, write insert statements or similar dml SQL to update the PSOPTIONSADDL appropriately.

      Hope this helps!

      Delete
    2. Worked perfectly. Thank you for your help and for sharing all this branding knowledge!

      Delete
  26. Hi Sasank, I should really appreciate your posts. These are very helpful in different aspects.

    I've a question.
    Can we able to display a test message in a box as soon as the user logs in the Home Page using iscripts? - User see the message and click on OK button or "donot show this again" like the one the below link. If so, can you please help us out. Thanks,

    http://docs.oracle.com/cd/E41340_01/crm92pbr0/eng/crm/ccrm/concept_UnderstandingPeopleSoftCRMSecurity-0964d7.html

    ReplyDelete
    Replies
    1. You could try the Signon Event Message functionality and see if it works for you.

      https://docs.oracle.com/cd/E41633_01/pt853pbh1/eng/pt/tsvt/task_UsingAdministrationUtilities-07109c.html#pt00240e8_s

      If you need something that remembers the status of whether the user viewed it or not, you may need to create your own custom functionality (redirect page, signon peoplecode to redirect users based on conditions, etc.).

      Hope this gives you ideas.

      Delete
    2. Thanks Sasank. Event messages would be on separate page (PT_EVENTSDISPLAY). But, I was actually looking something on Home landing page which is like in the below link with OK/continue button/links (with iscripts)

      http://docs.oracle.com/cd/E41340_01/crm92pbr0/eng/crm/ccrm/concept_UnderstandingPeopleSoftCRMSecurity-0964d7.html

      Delete
    3. Gotcha. Perhaps you could use a javascript popup but I am not sure how you will maintain the state of the OK/CANCEL (at the browser/client level or at the server level?).

      Delete
    4. Yeah, that's the issue. I could able to display a message something like below within an HTML object and iScript but not sure how to put a OK button/continue link over there. Not sure if we can put alert on the browser level. Thanks though for looking into this.

      {"Capture": "%bind(:1)", "MessageHTML": "%bind(:2)"
      }

      Delete
    5. You could try adding a couple of hyperlinks/buttons - OK and Cancel - in your HTML? And perhaps point them to other IScripts which take care of the OK and Cancel? I am just throwing out some ideas, not sure if it will work for you.

      I will let you know if I can think of any other options. Thanks!

      Delete