27
SAP NetWeaver How-To Guide How To... Apply Custom Branding Using the AJAX Framework L-Shape APIs Applicable Releases: SAP NetWeaver 7.3 SP2 and above IT Practice : User Productivity Enablement IT Capability: Running an Enterprise Portal Version 1.0 June 2011

How To Apply Custom Branding Using the AJAX Framework L ... · This tutorial walks you through the steps needed for creating a new framework page using the Ajax Framework L-Shape

  • Upload
    others

  • View
    10

  • Download
    0

Embed Size (px)

Citation preview

SAP NetWeaver

How-To Guide

How To... Apply Custom Branding

Using the AJAX Framework L-Shape

APIs

Applicable Releases:

SAP NetWeaver 7.3 SP2 and above

IT Practice :

User Productivity Enablement

IT Capability:

Running an Enterprise Portal

Version 1.0

June 2011

© Copyright 2011 SAP AG. All rights reserved.

No part of this publication may be reproduced or

transmitted in any form or for any purpose without the

express permission of SAP AG. The information contained

herein may be changed without prior notice.

Some software products marketed by SAP AG and its

distributors contain proprietary software components of

other software vendors.

Microsoft, Windows, Outlook, and PowerPoint are

registered trademarks of Microsoft Corporation.

IBM, DB2, DB2 Universal Database, OS/2, Parallel

Sysplex, MVS/ESA, AIX, S/390, AS/400, OS/390,

OS/400, iSeries, pSeries, xSeries, zSeries, z/OS, AFP,

Intelligent Miner, WebSphere, Netfinity, Tivoli, Informix,

i5/OS, POWER, POWER5, OpenPower and PowerPC are

trademarks or registered trademarks of IBM Corporation.

Adobe, the Adobe logo, Acrobat, PostScript, and Reader

are either trademarks or registered trademarks of Adobe

Systems Incorporated in the United States and/or other

countries.

Oracle is a registered trademark of Oracle Corporation.

UNIX, X/Open, OSF/1, and Motif are registered

trademarks of the Open Group.

Citrix, ICA, Program Neighborhood, MetaFrame,

WinFrame, VideoFrame, and MultiWin are trademarks or

registered trademarks of Citrix Systems, Inc.

HTML, XML, XHTML and W3C are trademarks or

registered trademarks of W3C®, World Wide Web

Consortium, Massachusetts Institute of Technology.

Java is a registered trademark of Sun Microsystems, Inc.

JavaScript is a registered trademark of Sun Microsystems,

Inc., used under license for technology invented and

implemented by Netscape.

MaxDB is a trademark of MySQL AB, Sweden.

SAP, R/3, mySAP, mySAP.com, xApps, xApp, SAP

NetWeaver, and other SAP products and services

mentioned herein as well as their respective logos are

trademarks or registered trademarks of SAP AG in

Germany and in several other countries all over the world.

All other product and service names mentioned are the

trademarks of their respective companies. Data contained

in this document serves informational purposes only.

National product specifications may vary.

These materials are subject to change without notice.

These materials are provided by SAP AG and its affiliated

companies ("SAP Group") for informational purposes only,

without representation or warranty of any kind, and SAP

Group shall not be liable for errors or omissions with

respect to the materials. The only warranties for SAP

Group products and services are those that are set forth in

the express warranty statements accompanying such

products and services, if any. Nothing herein should be

construed as constituting an additional warranty.

These materials are provided “as is” without a warranty of

any kind, either express or implied, including but not

limited to, the implied warranties of merchantability,

fitness for a particular purpose, or non-infringement.

SAP shall not be liable for damages of any kind including

without limitation direct, special, indirect, or consequential

damages that may result from the use of these materials.

SAP does not warrant the accuracy or completeness of the

information, text, graphics, links or other items contained

within these materials. SAP has no control over the

information that you may access through the use of hot

links contained in these materials and does not endorse

your use of third party web pages nor provide any warranty

whatsoever relating to third party web pages.

SAP NetWeaver “How-to” Guides are intended to simplify

the product implementation. While specific product

features and procedures typically are explained in a

practical business context, it is not implied that those

features and procedures are the only approach in solving a

specific business problem using SAP NetWeaver. Should

you wish to receive additional information, clarification or

support, please refer to SAP Consulting.

Any software coding and/or code lines / strings (“Code”)

included in this documentation are only examples and are

not intended to be used in a productive system

environment. The Code is only intended better explain and

visualize the syntax and phrasing rules of certain coding.

SAP does not warrant the correctness and completeness of

the Code given herein, and SAP shall not be liable for

errors or damages caused by the usage of the Code, except

if such damages were caused by SAP intentionally or

grossly negligent.

Disclaimer

Some components of this product are based on Java™. Any

code change in these components may cause unpredictable

and severe malfunctions and is therefore expressively

prohibited, as is any decompilation of these components.

Any Java™ Source Code delivered with this product is only

to be used by SAP’s Support Services and may not be

modified or altered in any way.

Document History

Document Version Description

1.00 First official release of this guide

Typographic Conventions

Type Style Description

Example Text Words or characters quoted

from the screen. These

include field names, screen

titles, pushbuttons labels,

menu names, menu paths,

and menu options.

Cross-references to other

documentation

Example text Emphasized words or

phrases in body text, graphic

titles, and table titles

Example text File and directory names and

their paths, messages,

names of variables and

parameters, source text, and

names of installation,

upgrade and database tools.

Example text User entry texts. These are

words or characters that you

enter in the system exactly as

they appear in the

documentation.

<Example

text>

Variable user entry. Angle

brackets indicate that you

replace these words and

characters with appropriate

entries to make entries in the

system.

EXAMPLE TEXT Keys on the keyboard, for

example, F2 or ENTER.

Icons

Icon Description

Caution

Note or Important

Example

Recommendation or Tip

Table of Contents

1. Business Scenario ............................................................................................................... 1

2. Background Information ..................................................................................................... 1

3. Prerequisites ........................................................................................................................ 2

4. Step-by-Step Procedure ...................................................................................................... 2

4.1 Create Your Own Framework Page ............................................................................. 2

4.1.1 Create a Portal Application .............................................................................. 2

4.1.2 Using the LSAPI ............................................................................................... 2

4.2 Steps to Perform in SAP NetWeaver Portal ............................................................... 12

4.2.1 Create an iView and a Layout ........................................................................ 12

4.2.2 Create Your Own Copy of the Ajax Framework Page ................................... 14

4.2.3 Create a Desktop ........................................................................................... 15

4.2.4 Create a Display Rule .................................................................................... 17

5. Some Notes about the Provided Sample Code .............................................................. 19

5.1.1 Enhanced Portal Response ........................................................................... 19

5.1.2 JavaScript Coding Style ................................................................................. 20

How To... Apply Custom Branding Using the AJAX Framework L-Shape APIs

July 2011 1

1. Business Scenario

This guide provides an overview about fully customizing your own Ajax framework page using the L-

Shape APIs of SAP NetWeaver Portal 7.3.

Note

This document does not discuss customizing the Ajax Framework Page for enterprise workspaces.

2. Background Information

The Ajax Framework Page (AFP) is provided with SAP NetWeaver Portal 7.3. Based on Ajax

technology, this framework page provides improved performance, enhanced user experience and a

wide set of client side-based APIs (also known as “L-Shape APIs”) to consume and modify its content.

Architectural outline:

For more information, visit http://wiki.sdn.sap.com/wiki/display/AFP/SAP+Portal+-

+Ajax+Framework+Page

How To... Apply Custom Branding Using the AJAX Framework L-Shape APIs

July 2011 2

3. Prerequisites

You need the following for developing your custom framework page:

SAP NetWeaver 7.3 SP2 and NWDS.

A basic knowledge of configuring SAP portal desktops.

Some basic experience with the Ajax Framework Page, for example by working through the AFP

tutorials provided in the wiki page http://wiki.sdn.sap.com/wiki/display/AFP/SAP+Portal+-

+Ajax+Framework+Page.

4. Step-by-Step Procedure

This tutorial walks you through the steps needed for creating a new framework page using the Ajax

Framework L-Shape API.

4.1 Create Your Own Framework Page

4.1.1 Create a Portal Application

1. Connect SAP NetWeaver Developer Studio with the Code Exchange subversion repository

https://code.sdn.sap.com/svn/sap-portal-ajax-framework and download the source code that is

located in the "ExampleFromScratchJQuery" folder that contains the component required for this

tutorial.

2. The package you downloaded includes two folders: i.

An .ear file ready to be deployed on your SAP NetWeaver Portal (if you do not want to make

changes to this example).

A folder containing the source code of the example.

Note

If you do not intend to modify this code sample, continue to section 4.2.

3. Copy the folder com.customer.afp.fromscratch to your Developer Studio workspaces

folder.

4. Open the NetWeaver Developer Studio and import this portal application (from the File menu

Import Existing Projects into Workspace).

4.1.2 Using the LSAPI

4.1.2.1 Using the Ajax Framework APIs

Starting from NW Portal 7.3, before using the Ajax Framework APIs, you must register to the following

event:

EPCM.subscribeEventReliable('urn:com.sapportals:navigation',

'AFPisLoaded',

function _afpLoaded() {...}

);

How To... Apply Custom Branding Using the AJAX Framework L-Shape APIs

July 2011 3

Once the Ajax Framework is ready for use, the AFPisLoaded event will be raised and you can start

using the Ajax Framework APIs. This step was added to prevent a situation where the Ajax

Framework scripts are loaded after the custom code, and are not yet accessible. Using this event

ensures that the custom implementation only starts using the Ajax framework APIs when they are

ready to be used. It is sufficient to use the above line of code. You do not need to wait for the window

onload or document ready event (such as in jQuery syntax: $(document).ready(<the event

handler>);).

Important

The APIs are not accessible and cannot be used until this event is raised.

4.1.2.2 Create the Content Area and Initialize the Ajax Framework Page

To create a valid content area you must include the following HTML elements at the desired place in

the page layout:

<div id="divContentArea"></div>

Once the HTML is rendered, call the following API (from within the AFPisLoaded event handler):

LSAPI.AFPPlugin.service.initAjaxFrameworkPage();

This will initialize the portal content area frame and allow you to navigate between the different portal

pages.

4.1.2.3 Render the Navigation Tree

Use the following method to get the list of initial nodes assigned to the current user:

LSAPI.AFPPlugin.model.getNavigationSubTree(null, renderNavigation);

renderNavigation is a callback method to which the result is returned. The callback function will

receive an array of navigation nodes objects as parameters.

function renderNavigation(nodes)

{

var i = 0,

len = nodes.length,

node,

html = '',

bc = LSAPI_AFPPlugin_model.getCurrentSelectedPath();

// construct the HTML of the first level (here: rendered as tiles)

while (i < len) {

node = nodes[i++];

var imgNum = 'img' + Math.floor(Math.random()*7) + '.png',

colorNum = 'color' + Math.floor(Math.random()*4);

html += '<a href="'+node.getNodeURI()+'"

node="'+node.getName()+'" showType="'+node.getShowType()+

'" class="tile '+colorNum+'"><span class="icon"><img

src="'+FWK.mimesPath+'/mimes/'+ imgNum +'"></span><span

class="title">'+ node.getTitle()+'</span></a>';

How To... Apply Custom Branding Using the AJAX Framework L-Shape APIs

July 2011 4

}

html += '<div style="clear:both"></div>';

$('#tiles').html(html).sortable({

update: function _onUpdate(event, ui) {

var tabset = LSAPI_tabsetPlugin.getCurrentTabset(),

undockedNodes = [];

// get the names of the tiles in the new order

$('>.tile', '#tiles').each(function _each() {

undockedNodes.push($(this).attr('node'));

});

LSAPI_AFPPlugin_service.setInitialNodes(tabset, [],

undockedNodes, function _callback() {/*no follow-up action

needed*/});

}

}).disableSelection();

}

The actual navigation (clicking on a link) is done by using the following API:

LSAPI.AFPPlugin.service.navigate(node, mode, params, title,

windowAttributes, windowID, workProtect, toHistory, i_postBody);

In most cases the first two or three parameters are sufficient.

In our example, click events on the tiles are registered like follows and trigger navigation after fetching

name and showType (= mode) of the clicked node/link:

function doNavigate(name, mode, params) {

...

// trigger navigation

LSAPI_AFPPlugin_service.navigate(name, mode, params);

}

$('.tile', '#tiles').live('click', function _onClick(e) {

var $this = $(this),

name = $this.attr('node'),

showType = $this.attr('showType');

...

doNavigate(name, showType, "InitialNodesFirstLevel=true");

...

});

To receive notification each time a navigation step is performed and to then update the highlighting of

the navigation step, use the following registration method:

LSAPI.AFPPlugin.controller.registerOnNavigate(onNavigate);

How To... Apply Custom Branding Using the AJAX Framework L-Shape APIs

July 2011 5

The method receives a callback function that is called when navigation is performed. The callback

function receives the current navigation node and launch node as parameters, and in this example, it

updates the tiles and view with the relevant information:

function onNavigate(currentNode, launchedNode) {

var bc = LSAPI_AFPPlugin_model.getCurrentSelectedPath(),

i = 0,

len = bc.length,

bcEntries = [];

// show content frame again

$('#contentAreaFrame').css('visibility', 'visible');

// update DTN

if (len > 0 && bc[0].hasChildren()) {

bc[0].getChildren(renderDTN, {

bc: bc,

lvl: 1,

elid: '#dtn'

});

} else {

$('#dtn').empty();

}

// update breadcrumb

for (i = 0; i < len; i++) {

bcEntries.push({

title: bc[i].getTitle(),

name: bc[i].getName(),

showType: bc[i].getShowType(),

href: bc[i].getNodeURI()

});

}

renderBreadcrumb(bcEntries);

// update history

$('#histback').toggleClass('disabled',

!LSAPI_historyPlugin.isBackwardEnabled());

$('#histfrwd').toggleClass('disabled',

!LSAPI_historyPlugin.isForwardEnabled());

// update favorites

var favId = getFavoriteID(launchedNode);

if (favId) {

$('#favsadd').addClass('set').attr('favId', favId);

} else {

$('#favsadd').removeClass('set');

}

}

How To... Apply Custom Branding Using the AJAX Framework L-Shape APIs

July 2011 6

4.1.2.4 Create the Welcome Message and Log Off Link

To create the welcome message, use the following API:

var user = LSAPI.AFPPlugin.configuration.getUser();

This will return a user object from which it is possible to get the user’s display name:

$('#welcome').text("Welcome: " + user.DisplayName);

To set up the log off link, use the following API method:

LSAPI.getSessionPlugin().logoff();

Here’s how we use it in our example:

$('#logoff').click(function _onclick() {

LSAPI_sessionPlugin.logoff();

});

4.1.2.5 Build the Portal Search

In this example, we decided that upon entering a search term in the portal search input field:

Pressing Enter will search for the entered search term in the default search provider. This is done

by calling the following API:

var defaultProvider = LSAPI_searchProviderPlugin.getDefaultProvider();

LSAPI_searchProviderPlugin.search(term, defaultProvider,

defaultProvider.getSearchTypes()[0], null);

where term is the search term entered in the input field.

Esc closes the suggestions menu.

Typing in either a character or a number displays the suggestions menu with the relevant

suggested items. This is done by calling the following API:

LSAPI_suggestionPlugin.getSuggestions(term, drawQLMenu);

where term is the search term entered in the input field, and drawQLMenu is a callback function

to which the list of suggestion items will be returned.

How To... Apply Custom Branding Using the AJAX Framework L-Shape APIs

July 2011 7

The following code sample demonstrates the above:

// while inside the input field, check key input

$('#quickLaunch').keyup(function _onKeyup(e) {

var keyCode = e.keyCode,

inputElem = e.target;

if (inputElem) {

var term = (inputElem.value || '').replace( /^\s+|\s+$/g, '' );

if (keyCode == 13) {

// Enter

var defaultProvider =

LSAPI_searchProviderPlugin.getDefaultProvider();

if (defaultProvider) {

var returnVal = LSAPI_searchProviderPlugin.search(term,

defaultProvider, defaultProvider.getSearchTypes()[0],

null);

if (returnVal == false) {

alert('The selected search provider is currently

unavailable.');

} else {

clearQLMenu();

$(this).val('');

}

} else {

alert('No search provider is configured.');

}

} else if (term == '' || keyCode == 27) {

// empty input field or escape key

drawQLMenu(null, null, e);

} else if ((keyCode > 48 && keyCode < 90) || (keyCode == 8)) {

// characters or backspace

LSAPI_suggestionPlugin.getSuggestions(term, drawQLMenu);

} else if (keyCode == 40) {

// arrow down to move the focus to the menu list

// set the focus on the menu

$('#ql-menu a:first').focus();

}

}

});

4.1.2.6 Display the User's Tabsets

Tabsets are subsets of entry points defined by the administrator so that portal users only see a given

group of entry points in top-level navigation.

To get the array of currently available tabsets, we use the following API:

var tabsets = LSAPI.getTabsetPlugin().getTabsets();

How To... Apply Custom Branding Using the AJAX Framework L-Shape APIs

July 2011 8

In addition, we need to listen to the tabset switch event, to get notifications when a tabset is switched

and the list of entry points should be updated:

LSAPI.getTabsetPlugin().registerOnTabsetSwitch(onTabsetSwitch);

The onTabsetSwitch is the callback method which will be triggered once a tabset is switched, and

all it does in our example is the following:

function onTabsetSwitch() {

LSAPI_AFPPlugin_model.getNavigationSubTree(null, renderNavigation);

}

When a specific tabset is selected in the menu, we first set it as the current selected tabset:

LSAPI.getTabsetPlugin().setCurrentTabset(id);

In our example, this gives the following results. Before selecting a tabset:

After selecting the "Administration" tabset:

How To... Apply Custom Branding Using the AJAX Framework L-Shape APIs

July 2011 9

4.1.2.7 Display the User's Portal Favorites

To add a navigation node to the portal favorites we use the following API:

LSAPI.getFavoritesPlugin().addFavorite(id, title, updateFavsContent);

where updateFavsContent is a callback method that is triggered when the favorite item is added to

the favorites list. Here’s how we use it in our example:

// set up the "Add to favorites" button

$('#favsadd').click(function _onClick() {

var $this = $(this),

isSet = $this.hasClass('set'),

currentNode = LSAPI_AFPPlugin_model

.getCurrentLaunchNode().originalObject;

$this.toggleClass('set');

if (isSet) {

var favId = $this.attr('favId');

LSAPI_favoritesPlugin.deleteFavorite(favId, updateFavsContent);

$this.removeAttr('favId');

} else {

LSAPI_favoritesPlugin.addFavorite(currentNode.id,

currentNode.title, updateFavsContent);

}

});

In our example, adding a page to favorites at runtime is done using the star icon next to the Favorites

menu. When the star is activated (yellow), it means that this page is already in the list of favorites.

Clicking the star removes the item from the list of favorites (and vice versa for adding a page to the

list):

How To... Apply Custom Branding Using the AJAX Framework L-Shape APIs

July 2011 10

To retrieve the favorites list and display it in a menu, you need to use the following API method:

LSAPI.getFavoritesPlugin().getFavoritesProviders(updateFavProviders);

Where updateFavProviders is a callback function that is called with the current favorite providers

available for the user. In this example, we are only displaying the portal favorites, therefore, to read

those we do the following:

var favoritesProviders = null;

function updateFavProviders(favProviders) {

favoritesProviders = favProviders;

}

// set up the "Favorites" menu trigger

$('#favsmenu').click(function _onClick() {

var favorites = favoritesProviders[0].getFavorites(),

favMenuItems = [];

// loop through favorites and build items for menu

for (var i = 0; i < favorites.length; i++) {

var currFav = favorites[i],

itemUrl = currFav.getURL();

favMenuItems[i] = {

title: currFav.getTitle(),

click: navigateToItem(itemUrl, 0),

href: itemUrl,

css: ''

}

}

var $this = $(this),

offs = $this.offset(),

w = $this.width(),

h = $this.height(),

items = favMenuItems;

// open menu by positioning it below the triggering element and

// passing the menu items to it

$.popupMenu(

'favs-menu',

{left: offs.left + w - 175, top: offs.top + h},

items,

$this

);

});

How To... Apply Custom Branding Using the AJAX Framework L-Shape APIs

July 2011 11

4.1.2.8 Display the Navigation History List

The History API enables you to access and control the navigation history.

In this example, we used the History API to display the last navigation nodes the user visited, and to

navigate back and forward between these entries.

Here is how we retrieve the history list and add the entries to a dropdown menu:

// set up the "History" menu trigger

$('#histmenu').click(function _onClick() {

var histEntries = LSAPI_historyPlugin.getEntries();

if (histEntries) {

var histMenuItems = [];

// loop through history entries and build items for menu

for (var i = 0; i < histEntries.length; i++) {

var currItem = histEntries[i],

itemURL = currItem.getUrl();

histMenuItems[i] = {

title: currItem.title,

click: navigateToItem(itemURL, 0),

href: itemURL,

css: ''

}

}

var $this = $(this),

offs = $this.offset(),

w = $this.width(),

h = $this.height(),

items = histMenuItems;

// open menu by positioning it below the triggering element and

// passing the menu items to it

$.popupMenu(

'hist-menu',

{left: offs.left + w - 175, top: offs.top + h},

items,

$this

);

}

});

And here is how we navigate back and forward between the history entries:

// set up the "Back" button

$('#histback').click(function _onClick () {

if (LSAPI_historyPlugin.isBackwardEnabled()) {

LSAPI_historyPlugin.back(true);

}

});

// set up the "Forward" button

$('#histfrwd').click(function _onClick () {

if (LSAPI_historyPlugin.isForwardEnabled()) {

LSAPI_historyPlugin.forward(true);

}

How To... Apply Custom Branding Using the AJAX Framework L-Shape APIs

July 2011 12

4.2 Steps to Perform in SAP NetWeaver Portal

4.2.1 Create an iView and a Layout ...

1. Log onto the portal

2. Navigate to Content Administration Portal Content Management.

3. Within the Portal Catalog, go to Portal Content.

4. Create a new folder named Ajax Framework from Scratch.

5. Go to Portal Applications com.customer.afp.fromscratch.

6. Copy the two objects (iview and layout) to a folder under Portal Content by repeating the

following steps:

a. Right-click an object in the application's folder and select Copy from the context menu.

b. Right-click you’re the new folder (Ajax Framework from Scratch) and paste the

object by selecting Paste as PCD Object from the context menu.

c. Enter the relevant information.

d. Choose Next and Finish.

How To... Apply Custom Branding Using the AJAX Framework L-Shape APIs

July 2011 13

The iView and the layout are created.

How To... Apply Custom Branding Using the AJAX Framework L-Shape APIs

July 2011 14

4.2.2 Create Your Own Copy of the Ajax Framework Page

1. Navigate to Content Administration Portal Content Management.

2. In the Portal Catalog go to Portal Content Portal Users Standard Portal Users Ajax

Framework Content Ajax Framework Page.

3. Right-click the Ajax Framework Page and select Copy from the context menu.

4. Go to Portal Content and paste the page in the folder that you created in the previous section

(Ajax Framework from Scratch) by right-clicking the folder and selecting Paste from the

context menu.

5. In the Paste wizard that opens choose Create a delta link. Choose Next and then Finish.

6. Right-click the copied page and choose Open Properties in the context menu. Click Modify

Properties and provide a new Name for the framework page.

Open the Page editor.

a. Remove all iViews except AFP Resources.

b. Change the page layout to the layout that you created in step 4.2.1:

i. Choose Add/Remove Layouts.

ii. Remove all layouts from the page.

iii. Move layout from the Available Layouts list to the Selected Layouts list.

How To... Apply Custom Branding Using the AJAX Framework L-Shape APIs

July 2011 15

c. Add the iView you created in step 4.2.1 to the page:

Right-click the iView and choose Add iView to Page Delta link from the context menu.

2. Save your changes and close the page.

4.2.3 Create a Desktop

1. Navigate to System Administration System Configuration Portal Display Desktops &

Display Rules.

2. Locate the folder you created in step 4.2.1 (5) in the Portal Catalog.

3. Right-click the folder and choose: New Portal Desktop.

4. Provide a name for the desktop (for example: Custom Desktop), and click Next.

5. Add your page to the desktop: right-click on the page and choose: Add Framework Page to

Portal Desktop).

How To... Apply Custom Branding Using the AJAX Framework L-Shape APIs

July 2011 16

6. Add a theme to the desktop. You can find themes in the Portal Catalog under Portal Content

themes. In this example, we will add the SAP Chrome theme to the desktop.

7. Click Next and Finish.

How To... Apply Custom Branding Using the AJAX Framework L-Shape APIs

July 2011 17

4.2.4 Create a Display Rule

A portal alias is the part of the URL after the section that specifies the portal J2EE application (irj),

which by default is http://<server>:<port>/irj.

Note

Standard portal aliases are defined in the portal's J2EE deployment descriptor

(web.xml) in com.sap.portal.runtime.dispatcher.ear, which is located under

EP-Basis SCA. If a user specifies an undefined alias, it is ignored.

Important

Changes you make to the web.xml will be overwritten after upgrading your portal to a

new release or support package stack.

1. Locate the com.sap.portal.runtime.dispatcher.war

2. In the .ear file, open the com.sap.portal.runtime.dispatcher.war file then the WEB-

INF file and extract the web.xml file.

3. In the web.xml file of the irj J2EE application, add an initial parameter (<init-param>

element) for the gateway servlet.

4. Set the <param-name> element to the new portal alias.

5. Set the <param-value> element to a string of key-value pairs, separated by commas (,). All

values are either 0 (false) or 1 (true).

The following shows the XML added to create a new alias called "customFrwkPage":

<param-name>portal/customFrwkPage</param-name>

<param-value>

anonymous=0,proxy=0,low_bandwidth=1,include_in_url=1,

include_application _name_in_url=1

</param-value>

</init-param>

6. Save the XML in com.sap.portal.runtime.dispatcher.war.

7. Locate the com.sap.portal.runtime.dispatcher.ear. This file is part of the

com.sap.portal.runtime.dispatcher.sda file located in the EP-Basis SCA.

8. Make a copy of the .ear file.

9. Insert the .war file into com.sap.portal.runtime.dispatcher.ear, overwriting the

existing .war file.

10. Deploy the modified .ear file on the server.

11. Restart the portal.

12. In the portal administration environment, go to System administration System Configuration

Portal Display Desktop & Display Rules.

13. In the Portal Catalog, go to Portal Content Portal Administrators Super Administrators

Master Rule Collection. Right-click the Master Rule Collection and choose Open Rule

Collection.

14. Add an IF expression: URL Alias = portal/customFrwkPage and choose Apply.

15. Select the Then line of the IF expression. In the Portal Catalog, go to the custom desktop that

you created and choose Add Portal Desktop to Expression.

How To... Apply Custom Branding Using the AJAX Framework L-Shape APIs

July 2011 18

16. Save your changes and close the Display Rules editor.

17. Open a Web browser and go to http://<host>:<port>/irj/portal/CustomFrwkPage.

18. Your portal should look like the example below.

How To... Apply Custom Branding Using the AJAX Framework L-Shape APIs

July 2011 19

5. Some Notes about the Provided Sample Code

5.1.1 Enhanced Portal Response

The example’s source code contains a Java library provided by SAP Consulting

(com.sapconsulting.portal.utils.html_api.jar) which provides a way of enhancing the

portal response with HTML output. For example:

Set a <!DOCTYPE> ((X)HTML5, HTML 4.01, XHTML 1.0)

Add specific <meta>, <link> and other tags to the <head> element

Set the <title>

Defer the loading of a <script> by placing it just above the closing </body> tag

In the doContent() method of your component that inherits from AbstractPortalComponent

instantiate the class EnhancedPortalResponse like this:

EnhancedPortalResponse epResponse =

new EnhancedPortalResponse(request, true, true);

Then use the instance to directly manipulate or add certain elements or attributes, for example:

epResponse.setDocTypeToHtml5();

epResponse.setTitle("Ajax Framework from Scratch");

epResponse.removeBodyClass();

Include <meta>, <link>, or <script> tags, or even browser-specific conditional comments in the

<head> section, with the help of the static createXY() methods of the HtmlFactory class:

epResponse.include(

HtmlFactory.createHttpEquivMeta("X-UA-Compatible", "IE=edge"));

epResponse.include(

HtmlFactory.createLink("stylesheet",

mimesPath + "/mimes/fwk.min.css", null, null));

epResponse.include(

HtmlFactory.createLink("shortcut icon",

mimesPath + "/mimes/favicon.ico", "image/x-icon", null));

epResponse.include(

HtmlFactory.createConditionalComment("lt IE 9", false,

HtmlFactory.createScript(mimesPath + "/mimes/html5.js",

null)));

How To... Apply Custom Branding Using the AJAX Framework L-Shape APIs

July 2011 20

You can defer <script>s (and other elements) and place them before the end of the <body>:

epResponse.defer(

HtmlFactory.createInlineScript(

"var FWK={mimesPath:'" + mimesPath + "'}", null));

epResponse.defer(

HtmlFactory.createScript(mimesPath + "/mimes/jquery-1.6.1.min.js",

null));

epResponse.defer(

HtmlFactory.createComment("sven://kannengiesser"));

5.1.2 JavaScript Coding Style

The style in which the provided JavaScript file

(\com.customer.afp.fromscratch\dist\mimes\fwk.js) is written requires some

explanation.

1. There is a self-invoking, anonymous function called _afp() that encapsulates the entire

functionality needed by the custom framework implementation. It takes a number of arguments

(see top of the fwk.js file) that are passed immediately when it invokes itself (see bottom of the

fwk.js file). This serves two purposes:

a. Passing global variables (such as window, document, EPCM) and namespaced objects

(such as LSAPI.AFPPlugin.model) as an argument (thus making them local to the

function) helps JavaScript obfuscators such as YUI Compressor or Google Closure

Compiler, otherwise rather lengthy names.

b. Variables (declared with var inside a function) and arguments (declared in the signature of

the function) in JavaScript are scoped to the enclosing function (also known as “closure”).

This helps to optimize lookups in the scope chain, due to the fact that when a

variable/argument is accessed, the interpreter first looks it up in the inner function, and then

searches for it in the wrapping/upper function(s), until the global scope (the window object)

is reached.

Note that the plug-ins of the LSAPI object are accessed indirectly from within the code of

_afp().For instance:

LSAPI_AFPPlugin_controller.registerOnNavigate(onNavigate);

LSAPI_tabsetPlugin.registerOnTabsetSwitch(onTabsetSwitch);

instead of:

LSAPI.AFPPlugin.controller.registerOnNavigate(onNavigate);

LSAPI.getTabsetPlugin().registerOnTabsetSwitch(onTabsetSwitch);

2. Many, if not all, anonymous functions start with an underscore (to distinguish them from real

functions), for example:

$('#logoff').click(function _onClick() {

...

});).

How To... Apply Custom Branding Using the AJAX Framework L-Shape APIs

July 2011 21

This is helpful in for the following reasons:

a. At design time, when editing the JavaScript code in the NetWeaver Developer Studio, you

can use the Outline and the code folding feature better.

b. At runtime, when debugging the JavaScript code with Firebug or other tools, you have more

fine-grained insight in the call stack.

3. There are also a number of self-invoking, named anonymous functions, such as:

(function _setupLogoffLink() {

...

})();

The main reason for this is to better manage scopes and “blocks of functionality” (= modules).

www.sdn.sap.com/irj/sdn/howtoguides