Showing posts with label Branding. Show all posts
Showing posts with label Branding. Show all posts

Tuesday, September 03, 2019

Changing the Search Page Operator Version 2

In 2011, just after PeopleTools 8.50 released, I wrote the post Changing the Search Page Operator. In that post, I demonstrated how to Monkey Patch PeopleSoft to do something you can't do with core PeopleTools: change the default advanced search page operator from Begins With to Between. A lot has changed since I wrote that initial post:

  • PeopleSoft switched from net.ContentLoader to net2.ContentLoader,
  • PeopleSoft released Branding System Options, which supports global JavaScript injection,
  • We began using RequireJS to manage JavaScript dependencies, and
  • The default user experience switched from Classic to Fluid.

Let's create a new version. Before writing any code, let's discuss that last bullet point. This post will focus on Classic. Why? Two reasons:

  1. Fluid doesn't use traditional search pages built from search record metadata and
  2. Roughly 95% of the components in PeopleSoft are still Classic.

This new version of the code will take advantage of Branding System Options and JavaScript dependency management. Our scenario will use the Job Data component (Workforce Administration > Job Information > Job Data. We will cause the Name search operator to default to between:

Let's start by creating JavaScript definitions for each library. Download the following libraries directly from their sources:

In your PeopleSoft system online, navigate to PeopleTools > Portal > Branding > Branding Objects. Switch to the JavaScript tab and create a JavaScript definition for each item. So that your names match our RequireJS configuration, use the names JSM_JQUERY_JS and JSM_REQUIRE_JS. For compatibility reasons, we should also protect our version of jQuery from any other versions of jQuery that may be loaded by PeopleTools. To do this, we create a library named JSM_PRIVATE_JQ_JS that contains the following code:

Next we need a RequireJS configuration that tells RequireJS how to locate each library we intend to use. I named mine JSM_REQUIREJS_CONFIG_JS, but this name is less important because we will select it from a prompt when configuring Branding System Options. Here is our RequireJS configuration:

Note: I snuck an extra library into the RequireJS configuration. Can you figure out what it is? I will be demonstrating this extra library at my session for OpenWorld 2019. Don't worry about removing it, however. As long as we don't reference it, RequireJS will never attempt to load it.

We must create one more JavaScript library to "listen" to page changes, waiting for PeopleSoft to load an advanced search page. Create a library containing the following code. As with the previous, name isn't as important because we will select the name from a list of values during configuration. But in case you are struggling with a creative name, I named mine JSM_SEARCHOP_JS.

Your list of JavaScript files should now look something like:

After uploading our libraries, we can turn our attention to configuration. Navigate to PeopleTools > Portal > Branding > Branding System Options. In the Addtional JavaScript Objects (this should really be named libraries) section, insert the following three libraries in order. Order matters. We first want RequireJS. We then configure RequireJS. Finally, we use RequireJS.

  1. JSM_REQUIRE_JS
  2. JSM_REQUIREJS_CONFIG_JS
  3. JSM_SEARCHOP_JS

About the code that makes all of this happen (JSM_SETSEARCHOP_JS)... It is incredibly similar to the first version. One important difference is that this version is loaded globally whereas the prior iteration was locally scoped to the component. We therefore include a component-specific test. The %FormName Meta-HTML in our JavaScript helps us derive the HTML element that contains the component name. The fieldMap variable contains the mapping between component names and fields that should be changed.

Will this work in Fluid? Unfortunately, no. Fluid does not use search record metadata to generate search pages. It can (with a little work), but not in the same fashion. Fluid also doesn't support branding system options Additional JavaScript Objects. JavaScript automation is still possible, but requires a different approach (Event Mapping to inject, different variables, etc).

Are you interested in learning more about PeopleTools, JavaScript, and HTML? Attend one of our courses online or schedule a live in-person training session.

Thursday, March 07, 2019

Branding Shortcut

Starting with his post PeopleTools 8.55.x - Branding - Part I - What has changed, Sasank Vemana provides a series of articles describing how to brand Fluid. If your organization supports multiple branding themes, then the PeopleTools delivered branding module and branding macros concept described by Sasank are a perfect fit. Although a fair amount of effort to configure, I didn't mind the macro concept provided in PeopleTools 8.55. But when PeopleTools delivered 8.56 with a brand new macro set and guidance suggesting we either start over with the new macro set or update ours with their new macros (which included evaluating all of our other macro changes), I folded. The scale had tipped. I realized that branding macros were not a "once and done" proposition. It was clear that maintaining branding macros would be more time consuming than injecting a little CSS into Oracle delivered stylesheets. I have this rule: If a configuration alternative exists, but that configuration alternative requires significantly more ongoing maintenance effort than customizing, I will choose the customization. Why? the point of configuration is to simplify Lifecycle Management. If the configuration alternative is more effort, complicating Lifecycle Management, then it is not a good alternative. It is counterproductive. PeopleTools includes very good compare tools for managed definition customizations. It is these great compare tools that sometimes make customizations simpler to maintain than configuration alternatives. This is not the case (yet -- I say "yet" because I believe this will change in the future) for configuration options that may become invalid (or broken) during an update/upgrade/selective adoption.

If your organization has just one global branding theme, you may find this approach much simpler. This is the approach I used with PeopleTools prior to the attribute-based branding module:

  1. Open a Fluid homepage.
  2. Using your browser's developer tools, mock up the changes desired.
  3. Be sure to make your selector more qualified than Oracle's. I suggest including the ID of a higher level element, but do NOT use an ID that starts with win0div as these IDs change with every New Window launched from the base PeopleSoft window.
  4. Copy these changes into a new PeopleSoft free-form sub stylesheet.
  5. Add this new stylesheet to PSSTYLEDEF_FMODE.
  6. Test.
  7. Visit a Fluid transaction page to identify further changes required to finalize the Fluid branding theme.

Here is some sample CSS to get you started:

How does this work? Unlike the branding module, which replaces and/or changes Oracle-delivered CSS, we allow Oracle's CSS to be sent to web browsers unchanged. Just as before the customization, a user's web browser will parse Oracle's CSS, building a list of rules. But when the browser reads our rules injected at the very end, the browser will ignore Oracle's rules because ours will be both more specific and interpreted last.

What about Classic and Classic Plus? Same principle, just a different stylesheet. Classic uses PSSTYLEDEF_TANGERINE and DEFAULT_THEME_FLUID. I prefer PSSTYLEDEF_TANGERINE because it is a structured stylesheet, allowing us to inject one object, very minor customization.

What about Lifecycle Management? When applying PeopleTools patches and updates, it is very likely Oracle will replace PSSTYLEDEF_FMODE, erasing your one-line customization. Restoring the customization, however, is trivial. Just re-insert the free form sub stylesheet. It is possible that Oracle may change the HTML structure of Fluid and Classic pages resulting in CSS selector modifications, etc. We, therefore, must test after every update and be prepared to modify accordingly. However, I have used this approach with Fluid from 8.55 through 8.57 with no updates necessary.

Did you find this article helpful? Are you interested in learning more about PeopleTools, including productivity shortcuts such as this one? Take your PeopleTools skills to the next level by registering for one of our courses at jsmspros.com

Wednesday, February 11, 2015

Using RequireJS to Manage Dependencies

I have a handful of blog posts describing how to deal with JavaScript dependency conflicts such as multiple library inclusions, namespace conflicts, etc. These workarounds are necessary in portal environments that mash up content from various providers that may use the same libraries. On a portal (Interaction Hub) homepage, for example, you may have a Pagelet Wizard pagelet that uses the jQuery Cycle plugin as well as a Pagelet Wizard pagelet that uses jQuery UI. Both of these pagelets will include the jQuery library, but different jQuery plugins. As each pagelet loads, it will load jQuery and then its required plugins. Both pagelets will try to put $ and jQuery into the global (window) namespace. The last pagelet to load will reload window.$ and window.jQuery causing the browser to drop any previously loaded jQuery plugins.

One technique JavaScript developers use to manage dependencies in a scenario like this is to use RequireJS with Asynchronous Module Definitions (AMD). With RequireJS and AMD, you would define a RequireJS configuration file pointing to each JavaScript library and plugin and then write JavaScript that uses these libraries with a RequireJS closure. This approach keeps custom libraries out of the global namespace and ensures that libraries only load once (not once for each pagelet). PeopleTools 8.54 makes implementing this really easy through the new Branding Objects module and Branding System Options. Let's review an example. Let's say that I have RequireJS, jQuery, and jQuery UI loaded into JavaScript objects in the Branding Objects module as shown in the following image

Now let's say you have your Branding System Options configured to include RequireJS and the RequireJS configuration file as described in the following screenshot:

You could then create a Pagelet Wizard pagelet containing HTML like the following and not worry about dependencies or namespace pollution. Everything would just work

<div id="NAA_DIALOG_TEST_html">
  <style type="text/css">
    @import url(%StyleSheet(NAA_JQ_UI_1_11_2));
    #NAA_DIALOG_TEST_html .dialog { display: none };
  </style>
  <script>
      require(['jquery', 'jqueryui'], function ($) {
        $(document).ready(function() {
          console.log("dialog pagelet is using version " + $.fn.jquery);
          $("#NAA_DIALOG_TEST_html").find("button")
              .button()
              .click(function( event ) {
                event.preventDefault();
                $("#NAA_DIALOG_TEST_html .dialog").dialog();
              });
          });
      });

  </script>
  <button>Show Dialog</button>
  <div class="dialog" title="Basic dialog">
    <p>This is the default dialog which is useful for displaying information.
    The dialog window can be moved, resized and closed with the 'x' icon.</p>
  </div>
</div>

Of course, this assumes that your RequireJS configuration file looks something like this:

/**
 * RequireJS global configuration. Include after RequireJS in branding settings
 * 
 * @returns {undefined}
 */
(function () {
  /**
   * Build a URL based on the current component's URL
   * @param {type} scriptId
   * @returns {String} derived URL for JavaScript
   */
  var getScriptUrl = function (scriptId) {
    var mainUrl = /*window.strCurrUrl ||*/ window.location.href;
    var parts =
        mainUrl.match(/ps[pc]\/(.+?)(?:_\d)*?\/(.+?)\/(.+?)\/[chs]\//);
    return window.location.origin + "/psc/" + parts[1] + "/" + parts[2] +
        "/" + parts[3] +
        "/s/WEBLIB_PTBR.ISCRIPT1.FieldFormula.IScript_GET_JS?ID=" + scriptId;
  };

  require.config({
    paths: {
      /* Using non-standard name because 1.6.2 is not AMD compliant whereas
       * later versions are compliant. Don't want conflict with later version
       */
      'jquery': getScriptUrl("NAA_JQ_1_11_2_JS"),
      'jqueryui': getScriptUrl("NAA_JQ_UI_1_11_2_JS"),
      'jquery-private': getScriptUrl("NAA_JQ_PRIVATE_JS")
    },
    map: {
      // '*' means all modules will get 'jquery-private'
      // for their 'jquery' dependency.
      '*': { 'jquery': 'jquery-private' },

      // 'jquery-private' wants the real jQuery module
      // though. If this line was not here, there would
      // be an unresolvable cyclic dependency.
      'jquery-private': { 'jquery': 'jquery' }
    }
  });
}());

And your jQuery-private module looks something like this:

// http://requirejs.org/docs/jquery.html#noconflictmap
define(['jquery'], function (jq) {
    return jq.noConflict( true );
});

What's up with the getScriptUrl function? JavaScript HTML definitions do not yet support %JavaScript Meta-HTML. The getScriptUrl JavaScript function attempts to perform the same task, but using client-side JavaScript.

Why do we need a jquery-private module? The point is to hide all of our dependencies and just expose them within the RequireJS closure. That way we avoid conflicts with older code that uses jQuery as well as any PeopleTools delivered JavaScript that may user

This technique also works well for loading dependencies. I often use a JavaScript library in a pagelet, with JavaScript executed directly in the pagelet. One challenge I have had is ensuring that my browser parses and processes any JavaScript libraries before JavaScript embedded in a pagelet. RequireJS solves this by first loading the dependencies, and then executing the JavaScript within the define/require function.

Note: For this to work properly, it is important that your JavaScript libraries are either AMD compliant or can be appropriately shimmed. Current versions of jQuery and jQuery UI are AMD compliant. The older version of jQuery UI that ships with PeopleTools 8.54 and earlier is NOT AMD compliant. Instead, I downloaded the latest jQuery UI and uploaded it using the new Branding Objects module. To work successfully, the jQuery UI CSS must be updated to use %Image() for each image resource and each image must be uploaded using the Branding Objects component.

Friday, November 15, 2013

10 PeopleSoft Interaction Hub CSS Tricks

If you have been to one of my PeopleSoft user experience sessions, you have likely seen a good handful of interesting CSS ideas in my designs. Ever wanted to implement some and need a few pointers? Here is a little Q&A that I hope you find useful.

Q: How do you keep a PeopleSoft or content provider stylesheet from overriding your Interaction Hub (portal) pagelet styles?

A: Higher specificity. I make sure my styles have a more specific CSS selector than the delivered CSS selector. This is actually pretty easy because the delivered CSS selectors for pagelet elements (ptpageletheader, ptpageletbody, ptpgltlabel, etc) just use class names. To make your selector more specific, just include .ptpagelet in front of your selectors. Here is a sample from one of my free formed stylesheets:

#ptpglts .ptpagelet .ptpageletheader {
  border-radius: 10px 10px 0 0;
}

The delivered selector is .ptpageletheader. I make my CSS selector more specific by adding #ptpglts .ptpagelet to the selector.

Q: How did you make the pagelets on your green/grass theme have a semi-transparent background?

A: There are actually a couple of ways to accomplish this. I created this theme back before rgba support in IE, so the approach I took was to create a 2x2 pixel PNG image with a semi-transparent background. I then set that to be my pagelet's background. Here is an example:

#ptpglts .ptpagelet td.ptpageletbody {
  background: url("opacity-bg.png") repeat scroll 0 0 transparent;
}

Today we can reduce our downloads and accomplish this much more easily using the rgba color syntax:

#ptpglts .ptpagelet td.ptpageletbody {
  background: none repeat scroll 0 0 rgba(255, 255, 255, 0.5);
}

Q: How did you create rounded corners for your pagelets?

A: I used the border-radius CSS attribute:

#ptpglts .ptpagelet .ptpageletheader {
  border-radius: 10px 10px 0 0;
}

I set the top left and right radius on the ptpageletheader class and the bottom left and right radius on the ptpageletbody CSS class.

Q: How do you make some pagelets have a transparent background while others have a color or image as a background?

A:Some pagelets, such as the accordion, look better with no header, border, or background. Through Pagelet wizard (or the new 8.53+ Pagelet Branding), you can hide the border and header, but you can't change the background. The technique I use is to first create, save, and add the pagelet to a homepage. Next, I find the pagelet's ID in HTML (firebug is very helpful for this). With the ID in hand, I write a custom CSS selector, setting the background to transparent. Here is an example:

#ptpglts #ADMN_COMPANY_DIRECTORY_IMG.ptpagelet td.ptpageletbody {
  background: transparent;
}

Q: How do you make the drop-down menu's bar semi-transparent?

A: Set a semi-transparent background on #pthnavcontainer. You can either use a semi-transparent image or RGBA colors. Here is an example. As with other examples, use a highly qualified selector (specificity) to ensure your selector wins over the delivered CSS selector.

body.PSPAGE #pthnavcontainer {
  background: none repeat scroll 0 0 rgba(0, 0, 0, 0.2);
}

Q: How do you set a background image for the entire PeopleSoft page?

A: Set a background image on .PSPAGE like this:

body.PSPAGE {
  background: url("background-photo.jpg") repeat fixed 0 0 transparent;
}

Make sure that:

  • Your background image size extends far beyond the expected page size so the image doesn't repeat.
  • You use the fixed attribute so your image doesn't have to extend passed the scrollable area of a page.
  • Your chosen background doesn't make transactions difficult to read.

Q: How do you make the main header area's background show through the transaction area?

A: There are a couple of ways to accomplish this. If you are OK with a semi-transparent appearance, then the easiest way is to add the following to your role based branding header's CSS:

#ptifrmtgtframe {
  opacity: 0.9;
}

This will make the transaction area semi-transparent. This includes the buttons, text, and every other element within the transaction area. A value of .9 seems to be opaque enough to view the entire transaction area while still allowing a small amount of the background to show through. Just for fun, use Firebug or Chrome tools to try smaller values. Once you get down to .5, the transaction area should be noticeably transparent.

Q: How do you set a background for just the pagelet region of a homepage?

Set a background image on the #ptpglts element. Here is an example:

.pspage #ptpglts {
  background: url("my-favorite-background.jpg") repeat fixed 0 0 transparent;
}

Q: How do I center the pagelet area and reduce the size to something like 1024 pixels wide?

A: As long as you are using a browser other than IE 8 (PeopleSoft 8.53- requires IE Quirks mode), you can do this using the margin auto CSS centering technique. Here is an example:

.pspage #ptpglts {
  margin: 0 auto;
  width: 1024px;
}

Q: How do you round the right top and bottom corners of the SES scope drop-down in the global search area of the header?

A: The SES search scope drop-down has the ID selsrchgrp. Here is some CSS that rounds the right side of the search scope drop-down. Since this drop-down is paired to a text field that has the same height, I only round the right side, not the left side.

.pspage #selsrchgrp {
  border-radius: 4px 0 0 4px;
}

Friday, June 21, 2013

New PeopleTools 8.53 Branding Tools

If you have an instance of PeopleTools 8.53, you may have noticed a new component at PeopleTools > Portal > Branding > Branding Objects. This new component allows you to upload images, HTML definitions, JavaScript definitions, and Stylesheet (CSS) definitions. The uploaded definitions become managed definitions in Application Designer. The point is to make it possible for customers to create and maintain user experience definitions online rather than having to log into App Designer to create and maintain these definitions. Once uploaded, if you prefer, you can still view and maintain these same definitions with Application Designer (but it is recommended that you maintain them using the Branding Objects component instead of App Designer). Note: the image upload does not yet support PNG (can you imagine a beautiful web without PNG? Me neither). I hope to see PNG in a future release. You can still create PNG's in App Designer, just not through the new Branding Objects component.

Being able to upload and create App Designer images, JavaScripts, and CSS files through an online component is nice, but where can you use these definitions? Just about anywhere that you see an image prompt. Here are some examples:

  • Navigation Collections
  • Pagelet icons
  • Pagelet Wizard HTML and XSL

Navigation Collections are pretty self explanatory. You use the prompt to select an image. Pagelet Wizard, on the other hand, is quite open. One way you can use these images is with Pagelet Wizard's custom XSL PSIMG tag:

<PSIMG ID="MY_UPLOADED_IMAGE" BORDER="0" />

Another way to use these definitions (and any other JavaScript, CSS, or image definition in App Designer) with Pagelet Wizard is through a collection of new iScripts (with examples):

  • IScript_GET_JS: http://your.peoplesoft.server/psc/ps/EMPLOYEE/EMPL/s/WEBLIB_PTBR.ISCRIPT1.FieldFormula.IScript_GET_JS?ID=PT_JQUERY_1_6_2_JS
  • IScript_GET_CSS: http://your.peoplesoft.server/psc/ps/EMPLOYEE/EMPL/s/WEBLIB_PTBR.ISCRIPT1.FieldFormula.IScript_GET_CSS?ID=PSJQUERY_BASE_1_8_17
  • IScript_GET_IMAGE: http://your.peoplesoft.server/psc/ps/EMPLOYEE/EMPL/s/WEBLIB_PTBR.ISCRIPT1.FieldFormula.IScript_GET_IMAGE?ID=PT_LOCK_ICN

I avoid hard coding server names in URL's if at all possible. To avoid hard coding the server name, start your URL with /psc/, skipping the server portion. When using this relative approach, though, keep in mind the pagelet's runtime context. If this is a local pagelet in a content provider or Interaction Hub, a relative URL will work just fine. However, if the pagelet is a remote pagelet, coming from a content provider, this relative approach will not work. Another thing to keep in mind when using these iScripts is your instances site name. Even with a relative URL, you still have to hard code your instance's site name, which usually differs between development, test, QA, and production instances.

Sunday, February 21, 2010

Page Assembler Strips Empty Elements -- This is Good!

With the new release of PeopleTools and Enterprise Portal, I find myself modifying my old branding themes to incorporate new features. While testing a header, I noticed that it appeared correctly on homepages, but not on transaction pages. Upon further inspection, I noticed that certain HTML elements I included in my HTML definition appeared on homepages, but not on transaction pages. Specifically, if an HTML element had a bind variable as its only content and that bind variable was only relevant on a homepage, then the page assembler would strip my hard-coded empty element from the transaction page. This caused me a bit of concern because I was actually using those elements to provide layout and styling. Consider the "Personalize Content | Layout" links that usually appear underneath the tabs in a standard Enterprise Portal implementation. Those links only appear on homepages, not on transaction pages. The PeopleSoft branding/assembly code uses designated bind variables to insert those links into a header HTML definition. If you wrap a block element, such as an HTML div around that bind variable, then your div will appear on a homepage, but not on a transaction page.

When I saw this behavior the other day I was quite surprised... and then I remembered I had seen it before. Several years ago while working with page level HTML Areas and Ajax, I noticed the same behavior. It is quite common to insert empty, hidden div elements and other structural elements into HTML to act as containers for dynamic content. The only problem with this approach is that the page assembler seems to eliminate these empty elements. Here is the workaround I contrived for this issue: Add an HTML comment inside an empty HTML element as follows:

<div id="jjm_dynamicContent" style="height: 10px; background-color: blue;">
<!-- This comment will force the page assembler to render this element -->
</div>

The page assembler will see content (the comment) inside the element and will allow it to pass through to the browser. Since the content is a comment, the browser will ignore the content and treat the element as if it were empty, giving us our much desired empty element.

Now that we have a solution for creating empty elements, let's consider how to turn this seemingly annoying behavior into a positive feature. The PeopleTools branding makes extensive use of HTML definitions. These HTML definitions contain bind variables that may or may not have values, depending on the execution context. I've already given the example of the Personalize links on a homepage. Wrapping items like these in HTML containers, such as div elements, provides us with conditionals that otherwise might not exist. For example, by wrapping the Personalize bind variable in a named div, you create a div that will exist on homepages, but not on transaction pages. Using JavaScript, you can test for the existence of this named element and execute code accordingly. Likewise, you can use CSS to attach layout and design instructions to these elements that the browser will only apply if the element exists (conditions are met).

There was a time when I thought this was a bug that should be fixed. But, now that I am enlightened to the possibilities of conditionals, I see the benefits of this feature and would be very sorry to see this behavior change.

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.

Thursday, February 07, 2008

Portal Template Settings

PeopleSoft uses Content References (CREF's) to describe how to display content within the PeopleSoft Portal (Enterprise or standard PeopleTools Portal). A very important setting for describing how to display a CREF is the CREF's template. The template describes how the content should be wrapped or "framed." Some templates proxy content into a single HTML page. Other templates use frames to display content. The most common frames template is the template that displays the header at the top, a menu on the left, and a content window on the right. If a CREF does not specify a template, then the Portal will use the default template. The default CREF template is set in PeopleTools > Portal > General Settings. If you haven't changed this setting, then your template is DEFAULT_TEMPLATE, also known as Portal default template. After looking up the default template, we can navigate to PeopleTools > Portal > Structure and Content to view the definition for this template. Templates are stored in the portal registry under Portal Objects > Templates. If your template has a storage type of "Local (in HTML Catalog)", then you can modify your template's HTML directly in this CREF. CREF's with a storage type of "Remote by URL", like the Portal default template, usually retrieve dynamic content from an IScript. Theoretically, you could store your template definition in any format or system as long as it is accessible by a URL (think of the possibilities for dynamic or even hosted templates). The IScript for the delivered Portal default template reads its settings from a different Content Reference. The name of this settings content reference is stored in the field PT_PORTAL_PROFILE of table PS_PTPP_OPTIONS.

SELECT PT_PORTAL_PROFILE FROM PS_PTPP_OPTIONS

With just a CREF name, you will have a hard time changing the template's values. The post Query for Component and/or CREF Navigation contains SQL to help you find the Structure and Content navigation for the CREF stored in PT_PORTAL_PROFILE. If you haven't customized your system, the settings CREF is PT_PORTAL_PROFILE (or PAPP_PORTAL_PROFILE if you are using Enterprise Portal). The PT_PORTAL_PROFILE CREF is stored in the Portal Registry's structure and content at Tools - Hidden > PeopleTools Portal Profile (For Enterprise Portal: Enterprise Portal - Hidden > Enterprise Portal Profile). From this CREF's attributes, you can specify the frame header height, whether to display the menu title, whether to show Search in the menu, as well as many other portal related settings. For example, if you wanted to change the frame header height from the default of 65 to 48 to give you more space for content, you would change the value of the attribute HEADER_FRAME_ROWS from 65 to 48.