Thursday, February 28, 2008

Branding Component/Page Tabs

You can find documentation on Customer Connection about branding homepage tabs in Enterprise Portal. But, what about changing the tabs that separate pages in a multi-page component? If you've been through a few PeopleTools upgrades, you've noticed that PeopleSoft occasionally changes the tab colors and tab design, so it must be possible... right? If you save one of those tab images, you will notice that tab images follow a naming convention. Component tabs are called level 2 tabs and are prefixed with PT_TAB2. You will also notice that App Designer contains PT_TAB3 images. I'm not sure where these are used.

Component tabs are comprised of 7 images, all of them ending in a hexidecimal color. The seven images are

  • PT_TAB2BAIBBBBBBCCCCCC
  • PT_TAB2BIABBBBBBCCCCCC
  • PT_TAB2BIIBBBBBB
  • PT_TAB2LAXCCCCCC
  • PT_TAB2LIXBBBBBB
  • PT_TAB2RAXCCCCCC
  • PT_TAB2RIXBBBBBB

BBBBBB represents the hexadecimal inactive tab background color and CCCCCC represents the hexadecimal active tab background color. If you haven't changed your default stylesheet, then PTSTYLEDEF_DARKBLUE contains the definition for your active and inactive tab colors. The style classes are PSACTIVETAB and PSINACTIVETAB. If you change the background color of either of these classes, then be sure you have all 7 new images in your database with matching color names. If you don't then your app server session will crash. It appears that the C++ code on the app server determines which image to choose based on the background colors of PSACTIVETAB and PSINACTIVETAB (hence the naming convention). Note also that the images with AI and IA prefixes list the inactive color before the active color.

Level 3 tabs follow the same conventions as level 2 tabs except for the addition of the PT_TAB3MIXBBBBBB image which represents the middle of 2 inactive tabs.

If you choose to change your tab colors to something that isn't delivered, be sure to upload all 15 images (level 2 and level 3). Otherwise, your app server session will crash each time you navigate to a component.

Update Tuesday, March 4th, 2008

While finishing up a branding project, I noticed that the 2 in PT_TAB2 does not describe the level, but the row. A component's tab set is actually comprised of 3 rows of images, PT_TAB1, PT_TAB2, and PT_TAB3. PT_TAB3 images make up the bottom row of the tabs. You must create a new PT_TAB3 image for your new background color using the naming conventions above. PT_TAB1 images are shared by all background colors, so you do not need to create new PT_TAB1 images for each background color combination.

59 comments:

Ciphersbak said...

Hi Jim,

Great insight into the Branding. Thank you. However, i was trying to lookup the Image Names listed in your Blog, but was unable to locate them in my Db. I'm presently using FSCM 9.0/Tools 8.49.09.

Thank You
Prashant

Jim Marion said...

Prashant,

There are many PT_TAB2% images. The ones in my post were fictitious. I made up the names so I could show the 6 and 12 character color code suffixes. The actual name of your images will match the background color of the styles PSACTIVETAB and PSINACTIVETAB in your stylesheet PTSTYLEDEF_DARKBLUE.

An example name for an image you would find in your PT 8.49 FSCM is PT_TAB2BAI789CCA4A598C.

Jim

Ciphersbak said...

Hi Jim,

Thanks for correcting me out.

Prashant

ng said...

This may be a silly question but I've been somewhat thrown into Portal administration and I hope you can help. It appears that in enterprise Portal there is no way to have tabs show 'active' once a user has clicked on a link from a pagelet or nav collection even though the portal still provides the theming (the header and left menu). Is it true that a given tab will only show as 'active' when a user is viewing the single specific homepage tab that it is associated with, or can I have the tab remain 'active' even after the user clicks through to HCM for instance?

Thanks for any help

ng said...

Subscribing

Jim Marion said...

@ng, Anything is possible... with enough time and money. This may fall into that category. You may be able to make this work. Using the query string parameters passed to the header IScript/App Class, you should be able to determine the menu and component that was called. The problem you will have is determining which tab was previously active. What I mean by this is that a menu/component combination may lead you to a CREF (by looking at the PSPRSMDEFN PeopleTools table), but it won't lead you to a tab. There is absolutely no relationship between a tab and a content reference (CREF). Tabs really represent home pages. Some of those home pages may have the enterprise menu and some might not. If you have the enterprise menu on multiple tabs, then either of those tabs could be the one to keep active. Now, if you have navigation collections or other pagelets that link off to components, then you may be able to work backwards to the correct tab given the menu/component (again, using the PeopleTools meta data). However, since multiple tabs can contain the same pagelets, it will be very difficult to create that one to one relationship to ensure you are showing the right tab.

Nevertheless, this is still possible. Thinking about it while typing... I think I would recommend you keep a separate table that maps menu/component combinations to tabs. Then, when constructing the tabs in the app class, you can look up the active tab for the requested component. As you know, this will require additional administrative overhead as well as some additional coding. The tabs PeopleCode can be overridden on a per-theme basis and you will need to do this if you want to pursue your active tabs idea.

Jim Marion said...

@ng, I was thinking about this some more... I don't know how stable/consistent it would be, but you could try to use a cookie to store the active tab. Cookies are available on the app server (PeopleCode), web server, and client (browser/JavaScript). To set a cookie for the active tab, you could add JavaScript to your header template, use PeopleCode in the branding app class, or use PeopleCode in the IScript that builds the homepage. Likewise, to set the active tab after navigating to a component, you could use JavaScript in the header template or modify the app class that builds the tabs.

Jim Marion said...

@ng, I don't know what I was thinking... take a look at the %HPTabName system variable in PeopleBooks. This variable contains the name of the last homepage visited. This should help you keep the last visited tab active.

ng said...

Thanks Jim - I'll take a look at the possible solutions you mentioned.

ng said...

Hi Jim - I really enjoyed your session on Thursday. Wanted to stay around a little longer after the presentation but I had to run to catch my flight out. Hate to be a bother, but now that I have the %HPTabName where can I leverage it to set the active tab?

Jim Marion said...

@ng, I need to find a "vanilla" system to test this on, but, if you are using Enterprise Portal, then I think you can add the following code to the Application Package EPPBR_BRANDING, class HTMLProcess, method HTMLProcess (constructor).

Local string &tempActiveTab = &strActiveTab;
If (None(&tempActiveTab)) Then
&strActiveTab = %HPTabName;
End-If;

Add this code immediately following the line:

&strActiveTab = &Request.GetParameter("tab");

As delivered, the EPPBR_BRANDING package uses the "tab" query string parameter to determine the active tab. That parameter doesn't exist on requests for PIA pages (non homepages). Since %HPTabName contains the name of the last homepage visited, this code will make EPPBR_BRANDING think the active tab is the last homepage tab that was visited.

Jim Marion said...

@ng, take a look at this post: Keep the Last Visited Homepage Tab Active.

Jennifer L.A. said...

Jim,

Very helpful and helped me understand how I "broke" the tabs! One question....do you only need to create the new PT_TAB images if you change the background color? If I want to leave the background color on the tabs as is and change the font color, will that work without creating new images?

Thanks,
Jennifer

Jim Marion said...

@Jennifer L.A., that is how I figured it out... I broke the tabs too. I changed the background color, logged in, then saw, "An error has occurred." I found this quite annoying because I couldn't find any information describing the cause of the error, not even in the app server log files.

Yes, you can change the font color without issue. The background color is the only thing that affects the chosen image name.

Abhishek said...

Hi Jim.. I have a question.. We have a default home TAB but for the new development we will have a new TAB called Welcome. There are a different set of people who wil have acces to only Welcome TAB nothing else in the portal. Is there a way we can define home tab as welcome. I was trying to pay with secuirty but not giving acess to HOME tab and only to Welcome TAB but the system doesnt let me in because in the URL it looks for the DEFAULT table which I dont have access. Is there a way we can get it?

Jim Marion said...

@Abhishek, changing security is the correct approach. After you make your changes, you have to clear app and web server cache and restart both. Then it will start looking for the new tab. The same thing happens if you change the tab sequence order.

Abhishek said...

Its not working.. I cant change the seq of the tab because this is for a specific set of users and for other users the seq wll be the same.. The new set of user will only have access to the welcome tab whereas other users will have access to all the other TAB.

The other things I notice that when I logged in. In the adderss bar it has /EMPL/h/?tab=DEFAULT... And since this new user will not have access to the DEFAULT tab its not letting them in.... I was looking where we set the default TAB which appears in the URL when you logon.

The other way I was thinking to have a pagelet in the DEFAULT TAB for this new user and the pagelet will somehow call the new TAX Welcome but I need to hide the DEFAULT TAB so that they see only Welcome TAB.. Basically I am faking that there is only one tab.. but not sure how to hide a tab.

And I cant have the pagelet in my HOME page and handle with security because the Home TAB has 3 column and new tab has 1 column. I talked to you about this in your other blog if you remember...

Please suggest

Jim Marion said...

@Abhishek, if you change security and clear your app server cache, it will stop putting DEFAULT in the URL. I know this because that is how the GUEST works in Enterprise Portal. When you log in as GUEST in Enterprise Portal, the URL has PAPP_GUEST, not DEFAULT.

Abhishek said...

ok.. Earlier my ID had security to DEFAULT TAB and WELCOME TAB.. Now I have removed that role from DEFAULT Tab... my profile has 2 roes one if Peoplesoft User and other is for the new WElcome tab..

I bounched the app and web server and cleared cache.. cleared browser cache... but its not letting me in.. where else when i try to logon as differnt user who has acess to DEFAULT table I can logon ..

Any idea?

Jim Marion said...

@Abhishek, as long as your user has access to the WELCOME tab, then yes, it will work after clearing cache.

Abhishek said...

Yes.. you are correct Jim.. I tried that in our development env and it took the TAB name...

Not our DEV is different from other Env bcz we have a layer of dotnet page then OIM then Peoplesoft Portal.. wndering why its not working in test env...

Abhishek said...

Hi Jim.. After talking to our dotnet team I figured that they are redirecting to a url that has a TAB hardcoded so now I need to find a way to hide the tab with Peoplecode... Is there a way we can hide tab with Peoplecode?

Please suggest.

Abhishek said...

Hi Jim,

Can you please suggest a way to hide TAB thru Peoplecode or something.

Thanks
Abhishek

Abhishek said...

Jim... I have another question.. Everything else worked out by changing css and all.. This probably is the last time in this development...

When I have secuirty to only one TAB I dont see the tab on portal.. only my HTML is coming but there is GAP between my HTML and header becuase tabs are not displaying.. I looked at the HTML that is used for Header.. It has %bind(:5) which is generated by pplcode... I compared the FRame source code and when the secuirty is given to one tab value of %bind(:5) is not coming... thats they there is a game between header and pagelet... Is there a way or setup.. where I can display the tabb even its one?

Can you please suggest

Jim Marion said...

@Abhishek, what you are seeing is the delivered behavior. I have not attempted to change this before. Of course it can be done. I just haven't looked, so I'm not sure where to send you.

Abhishek said...

If I modify the code to pass the a value in %bind(:5) when it blank then it should work.. I need to figure out the code where its generating that value.

Abhishek said...

Here is the code we need to modify to show the TAB even if they have access to only one TAB..

Application Package: EPPBR_BRANDING.HTMLProcess.Onexecute

If &ValidTabCount <= 1 Then
rem &strTabHTML = "";

Abhishek said...

Hi Jim,

When we are accessing HR Page from Portal as Pagelet the stylesheets are not working.. When we access the page from HR it works fine but when access from Portal its not...

Would you please suggest on this..

Jim Marion said...

@Abhishek, what behavior are you experiencing with HRMS pagelets in your portal? Are you seeing the HRMS stylesheet override the portal stylesheet or do you have custom styles in HRMS that are not appearing when you try to view the pagelet in portal?

Abhishek said...

Jim: I dont seee the style sheets.. The other issue is we are opening modal component using java script and it works fine on CORE but when we are trying from Portal thats also not working.. The reason is one of the markup is not coming on the DOM... When we see the souce code for CORE it shows the markup but on protal its not...

Is there any specific reason the mark up is overwritten or get deleted.... or any specific place I can look to debugg...

Jim Marion said...

@Abhishek, I'm sorry, but it still isn't fully clear to me. Did you import the pagelets as portal registry items or as WSRP? WSRP strips all styling and CSS.

I have nav collections on my homepage that open HRMS pages in a modal dialog. I use jQuery with an iframe. The content inside the modal dialog is all from HRMS and is not proxied into the portal, so it is not styled or modified in any way by portal. How does this differ from your modal content?

Abhishek said...

Jim How did you do this? Any sample code for jquery?

I have nav collections on my homepage that open HRMS pages in a modal dialog. I use jQuery with an iframe. The content inside the modal dialog is all from HRMS and is not proxied into the portal, so it is not styled or modified in any way by portal. How does this differ from your modal content?

Jim Marion said...

@Abhishek, I have not posted any samples of this, but I will. What I did was start with a nav collection published through Pagelet Wizard and write my own XSL to display the nav collection. In the XSL, I used the isNewWindow attribute to determine whether to open the link in a new window or in a modal dialog. My JavaScript appends a hidden iframe and sets the URL for the iframe to the URL from the nav collection, and then displays the iframe in a jQuery UI dialog.

I've done the same thing with Thickbox, but was not as happy with the result.

Abhishek said...

Thanks Jim... Whenever possible plz post some sample it will be a big help... We have an requirment where we want to open HR component as popup when user logs in on portal... Its kinda of modal window and user need to eneter infomation frst...

Jim Marion said...

@bhishek, right, exactly. It works very well with self service components like setting your emergency contact info, etc.

Abhishek said...

Thanks Jim.. Waiting for sample code...

Abhishek said...

Jim.. I have another questions.. I am trying to embed Video on Peopelsoft page.. I used the code avaliable on internet to embed the video it has video.js and all.. When I use the HTML on page and how it like page it works fine but when I use the same HTMl code on Pagelet vizard till preview it fine but when I publish the pagelet it doesnt work...

Is there anything specific we need to.. I have created simple pagelets but never faced this kinda of issue.

Will you please suggest me???

Jim Marion said...

@Abhishek, I am very familiar with this. Take a look at my post Google Gadgets for your PeopleSoft Enterpise Portal. You will have a similar issue with Facebook social gadgets, twitter feeds, etc. The solution is to wrap the video's script tag in a div tag.

Abhishek said...

Thanks Jim... I looked at the source code of the page.. The Scritp which is in head of my HTML is coming under body of the Portal Page.. I tried div tag still its not working... Would you please suggest where should I use the tag I tried just able the script on head.

Abhishek said...

Jim I again read you post and checked my portal page source... In my case the script from head is coming on body.. Everything is coming on body..
The pagelet has video using flowplayer.. and above that a image.. When I created the pagelet and in preview everything is fine. When published the pagelet the image is coming down which should be above the player and the video is not working...

Abhishek said...

i think I am confused.. I did view page souce on google crome and IE both.. everything looks okay... Scripts are on head but I noticed one things... that my video tag is not there.. I have
div class="video-js-box" then
vedio tag which has scr of the vedios ...

video id="example_video_1" class="video-js" width="500" height="264" controls="controls" preload="auto" poster="/cs/prtstg90/Videofile/OEVideo.JPG"

Jim Marion said...

@Abhishek, the other issue that causes problems with pagelet wizard (or any page, for that matter) is empty elements. See this blog post Page Assembler Strips Empty Elements -- This is Good!. By empty elements, I mean div elements that are placeholders, but have no content. The resolution is to put an nbsp or HTML comment in between the empty tags.

Abhishek said...

Here is the code I have... on my pagelet.... Sorry if its not readable... In this code this part I dont see on my page sounce... I got this code from videojs.com

---video id="example_video_1" class="video-js" width="500" height="264" controls="controls" preload="auto" poster="/cs/prtstg90/Videofile/OEVideo.JPG"---


html
head
meta charset="utf-8"
titleHTML5 Video Player /title



script src="/cs/prtstg90/Videofile/video.js" type="text/javascript" charset="utf-8"
/script

script type="text/javascript"
VideoJS.setupAllWhenReady();
/script


script type="text/javascript" src="/cs/prtstg90/Videofile/jwplayer.js"
/script

link rel="stylesheet" href="/cs/prtstg90/Videofile/video-js.css" type="text/css" media="screen" title="Video JS"

head
body

!-- Begin VideoJS --
div class="video-js-box"
!-- Using the Video for Everybody Embed Code
!-- This comment will force the page assembler to render this element --
video id="example_video_1" class="video-js" width="500" height="264" controls="controls" preload="auto" poster="/cs/prtstg90/Videofile/OEVideo.JPG"
!-- This comment will force the page assembler to render this element --
source src="/cs/prtstg90/Videofile/7099_OpenEnrollment_v1_092711.mp4" type='video/mp4; codecs="avc1.42E01E, mp4a.40.2"'
source src="/cs/prtstg90/Videofile/7099_OpenEnrollment_v1_092711_VP8.webm" type='video/webm; codecs="vp8, vorbis"'
source src="/cs/prtstg90/Videofile/7099_OpenEnrollment_v1_092711.ogg" type='video/ogg; codecs="theora, vorbis"'
!-- Flash Fallback. Use any flash video player here. Make sure to keep the vjs-flash-fallback class. --

object id="flash_fallback_1" class="vjs-flash-fallback" width="500" height="264" type="application/x-shockwave-flash"
data="/cs/prtstg90/Videofile/flowplayer-3.2.7.swf"
param name="movie" value="/cs/prtstg90/Videofile/flowplayer-3.2.7.swf"
param name="allowfullscreen" value="true"
param name="flashvars" value='config={"playlist":["/cs/prtstg90/Videofile/OEVideo.JPG", {"url": "/cs/prtstg90/Videofile/7099_OpenEnrollment_v1_092711.flv","autoPlay":false,"autoBuffering":true}]}'
!-- Image Fallback. Typically the same as the poster image. --
img src="/cs/prtstg90/Videofile/OEVideo.JPG" width="640" height="264" alt="Poster Image"
title="No video playback capabilities."
!-- Image Fallback. Typically the same as the poster image. --
img src="/cs/prtstg90/Videofile/OEVideo.JPG" width="640" height="264" alt="Poster Image"
title="No video playback capabilities." /
/object
/video

/div


/body
/html

Abhishek said...

Jim.. I have opened a case with Oracle for this. Lets see what they say...

Meanwhile can you post some sample code for other popup things?

Thanks a lot for all you help on solving so many issues for me,

Abhishek said...

Thanks Jim, We are having issues with Reverse proxy, Is there any thing we can do at peoplesoft side? Can we have any template which wroks the same as DEFAULT TEMPLATE but does not go to HR and change the URL?

Jim Marion said...

@Abhishek, are you saying you would like to be able to view the content with one template inside the network, and a different template outside the network? I know that you already know how to view it through the no frames template, so I'm sure you aren't asking about that.

A single CREF can only have one template. I'm not aware of any URL parameters to specify a template. An alternative is to create a second CREF with the same target (just add 1=1 to the additional URL info or something to make it unique). Then you can specify separate templates for each cref.

Abhishek said...

Hi Jim,

Is there any way we can emved video on protal pagelet?

Thanks
Abhishek

Jim Marion said...

@Abhishek, yes, absolutely. The portal is just HTML. Embedding video on a PeopleSoft portal page is no different than embedding video anywhere else on the internet. The most common example is embedding a YouTube video. To embed a YouTube video, find the YouTube video you want to embed, click the share button, and then the embed button. Then grab the HTML and paste it into Pagelet Wizard's HTML editor. Place &nbsp; in between the iframe tags to keep Tidy from stripping the iframe tag (see Page Assembler Strips Empty Elements). Publish the pagelet just like any other pagelet.

For all other types of videos, embed them just like you would on any other web page: Create some HTML and paste it into the Pagelet Wizard's HTML data type.

Pras said...

Hi Jim,

Your PeopleSoft journal is very nice. Thanks for posting all this information.

I have a question, is there any feature available is PeopleSoft portal where we can allow the users to select default homepage tab (where there are multiple homepage tabs available). i.e., if a user X logs in he should be able to select a homepage tab as default tab and if a user Y logs in he should be able to select different homepage tab.

-Vasu

Jim Marion said...

@Pras, no, it is not possible. There really is no "default" tab. The first tab shown is the one with the lowest Seq No, and then Alpha sorted by label if they have the same Seq No.

I don't believe the tab is necessarily as important as the tab content. You can relabel tabs by user. That is configurable, so the name of the tab is not an issue. Instead, the tab content would be the issue. If your users want to have different content and have that content configured, by user, then can they just use the "Personalize Content" link to change what appears on the first (default) tab?

Pras said...

Thanks so much Jim for your response.

Pras said...

Hi Jim,

how do we enable pagelet drag and drop. I'm on PeopleTools 8.51 and pagelet drag and drop doesn't seem to work.

Any insight is appreciated.

-Vasu

Jim Marion said...

@Vasu, I thought Drag and Drop was enabled by default. If you have pagelets that are required, optional, or optional default, then you should be able to drag/drop without any additional configuration. If that is not what you are seeing, then you may have to open a case with Oracle Support.

Becca said...

Jim,

We're having a problem that I'm told has been referenced before elsewhere, but I can't find it. We have multiple homepage tabs and a login through the Guest tab. When a user logs into the system, the user is directed to the Guest tab (no elements show on it), even if they don't have access to it. In fact, if I remove the access, we get an unauthorized page access error.

Any ideas of what I could look at to remove the extra tab?

Regards,

Becca

Jim Marion said...

@Becca, first thing you want to do is remove access, just like you said. Then you will get the error, just like you said. Final step: clear web and app server cache. If it doesn't work the first time, do it again. Clear cache with both app and web server down. Then restart them.

I have this trouble ALL THE TIME but it is usually because someone creates a tab and leaves the sequence # set to 0, then they restrict access. Then I get the error.

divya s said...

Hi Jim,

Is there any way to identify the difference between a modified delivered peoplesoft object and a new object created if no naming convention is followed. Checking the lastupdoprid field in PSRECDEFN,PSDBFIELD,PS_PRCSDEFN etc..records doesn't help because in both the cases the lastupdoprid would be changed.

Thank you
Divya S

Jim Marion said...

@Divya, Last time I checked, LASTUPDOPRID was set to PPLSOFT for delivered items. Is that not the case for you?

divya s said...

Thanks for your response Jim.

I want to differentiate between custom and customized objects when no naming convention is followed.

Custom Objects are those which are created by the user whose LASTUPDOPRID would be the user's id

Customized Objects are those which are delivered by peoplesoft but are modified by the user. In this case also the LASTUPDOPRID would be the user's id.

So i cannot use LASTUPDOPRID field to differentiate these two and in my case i even cannot use dblinks.

I just would like to find out if there is any way we could do this.

Jim Marion said...

@Divya, if you aren't using a prefix for all custom objects, then you are right, it will be difficult to find what is new versus what has changed. An alternative would be to use your demo DB to create a table containing the names of every definition within the demo database, and then copy that table to the instance you want to compare. Then write a "not in" query. This will give you all your custom objects.