Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
cancel
Showing results for 
Search instead for 
Did you mean: 
former_member193577
Active Contributor


The Portal Runtime has defined some points during the request cycle where you can add your own processing. Those entry points, which are called hooks , are defined by the connection and are run for every request.

In this blog post you can find demo code on how to add any html content to portal responses of all portal iViews. We will use document hooks which are executed before and after construction of HTML document. This enables us to add html to different parts of html page (body,head).

*Important note - Hooks affect every request to the portal, and are designed for special situations. Because hooks can have wide-ranging and dangerous side-effects that could harm performance or entire portal functionality, it is not recommended for wide usage and only for special conditions that suits.

In the sample code we will include a specific css file for each portal response:

1. For this we need first to create an portal project in our NWDS:



Lets call our project CssHook.

2. Next we will create a portal service using the NWDS wizard, by right click on the project, then new-->Potal Application , and selecting Portal service:



We will call our service PortalCssHook, with package myPackage.

After few clicks on Next, you will get portal service interface and java implementation template ready.

 

3.  For turning our service into a real document hook, we need to extend our interface (IPortalCssHook) to inherit the IDocumentHookListener:

 

public interface IPortalCssHook extends IService, IDocumentHookListener







 

4. Now we need to fill in the service Key, so other apps can reach it. this should be the name of ear file created +name of service , so our final Interface IPortalCssHook.java now looks like this:

 

package mypackage;
import com.sapportals.portal.prt.service.IService;
import com.sapportals.portal.prt.service.document.IDocumentHookListener;
public interface IPortalCssHook extends IService, IDocumentHookListener
{
public static final String KEY = "CssHook.PortalCssHook";
}







 

5. Now lets put our css file in the project so the service can reach it.

We will put it under dist/css:





6. Next phase is to override the doDocumentHook methods in our implementation and add in our html to the response:

 

This method calculates the html String to build for return later:


@Override
public String doDocumentHook(int documentPosition, IPortalComponentRequest request) {
IResource myCSS = request.getResource(KEY,IResource.CSS,"css/mCss.css");
String cssURL = myCSS.getResourceInformation().getURL(request);
String cssLink = "<link rel\"stylesheet\" type\"text/css\" href=\"" + cssURL + "\">";
switch (documentPosition){
case IDocumentHookListener.HEAD_SECTION_BEGIN:
return cssLink;
case IDocumentHookListener.HEAD_SECTION_END:
return "<!-- css was included at head begin -->";
default:
return "";
}
}


Explanation:

  • In line 3 and 4 we get our css file , located in our project under  dist/css

  • in line 5 we prepare the html to be embedded later on based on the css resource.

  • lines 8-14 : The html will be inserted on begin of head section, and just a comment on head end.


This method actually writes the string to the html response:

@Override
public void doDocumentHook(int documentPosition, IPortalComponentRequest request, IPortalComponentResponse response) {
response.write(doDocumentHook(documentPosition, request));
}







7. Next phase is to include the hook and register it in the afterinit method of the service:

public void afterInit()
{
IDocumentHookService hookSrvc = (IDocumentHookService)mm_serviceContext.getService( IDocumentHookService.KEY );
hookSrvc.addDocumentHook( this );
}





 

8. Almost last phase, to make sure the hook is unregistered when service goes down, in the destroy method:

public void destroy()
{
// unregister document hooks
IDocumentHookService hookSrvc = (IDocumentHookService)mm_serviceContext.getService( IDocumentHookService.KEY );
hookSrvc.removeDocumentHook( this );
}





 

9. And last, but not least, make the service startup automatically in your portalapp.xml, so when portal starts, or when the service is deployed, it is started right away:

<service name="PortalCssHook">
<service-config>
<property name="className" value="mypackage.PortalCssHook"/>
<property name="startup" value="true"/>
</service-config>





There you go ! your document hook is ready!

After exporting to .ear and deployment in EP, when logging into EP, we can see that for each request, or for each iView (isolated) that runs, our injects html is included in response:



...

....



Enjoy! (just use it wisely, and make sure you understand what you are doing!)

Tal

Related links:

You want to influence the future product roadmap of Enterprise Portal? You plan to implement your portal in the Cloud? Then you should participate in the following survey https://blogs.sap.com/2016/10/11/2016-elections-vote-now/.