Skip to Content

Displaying Long Text Messages in Business Server Pages II

‘ in rv_content_html with space. replace ‘—-‘ in rv_content_html with space. replace ‘` lv_build iv_titel lv_build `‘ IN rv_content_html WITH space. REPLACE ‘—-‘ IN rv_content_html WITH space. REPLACE ‘In the first part of this log(Displaying Long Text Messages in Business Server Pages I) we examined how you obtain the long text for a T100 message from the database. In this, second part we are going to show you how to render a long text message in order that it can be displayed with a similar look and feel as the underlying application.


As mentioned in the first part of this log, a long text message is delivered in SAPscript format, in this case, using the method read_log( ) from the application class cl_applog. To render and subsequently display the message with the same look and feel as the underlying application, the text formatted in SAPscript needs to be converted to HTML. You can do this easily with the function module convert_ift_to_html. This function module converts the long text message that is formatted in SAPscript to HTML, though here we are mainly interested in the message content.

Figure 1: long text message

Once we have converted the long text to HTML, the message content is extracted, the HTML tags that are not needed are deleted, and the message content is then inserted into a dynamically-generated HTMLB textview element. After the page has been rendered, its content is to be saved to the WebAS cache as a URL, which will be available for display from the browser until the cache time expires.


It is good programming practice to separate all message handling operations from rendering and conversion operations. Therefore, our first step is to create a new class for rendering, caching, and converting the message text to HTML. The new class, CL_RENDER_PAGE, consists of nine methods, six of which are private and three of which are public.

Figure 2: class diagrams of the message classes

The main method in the class is the method cl_render_page->render( ). As explained before, it is easy to execute the whole process of converting the long text message to HTML by calling the member method to_HTMLB(). The function module CONVERT_ITF_TO_HTML is executed and returns the long text message as HTML. What we actually need is the content of the message, so we continue by deleting from the message content all the HTML tags that we do not need.

Method Render()

As you can see in Figure 1, we intended to display the long text message inside a textview element and this textview inside of a tray element. If we cannot use HTMLB extension tags inside a class, we are still able to reuse part of its HTMLB rendering to get a similar look and feel as the underlying application. Therefore, the next step is to dynamically create the layout and all the elements it contains, using member method cl_render_page->create_layout(). You can dynamically create a grid layout by using the static method in factory class clur_d2_factory=>gridlayout(). However the factory class allows you to create other elements as rows, cells, textviews, and trays. Once we have the instances of the grid layout, the tray, and the textview, we continue by adding the message content to the textview and the textview to the tray context. A new layout row and a cell are then created and added to the grid layout.

Method Create_layout:

Method to_HTML( ):
‘ in rv_content_html with space. replace ” in rv_content_html with space. replace ” in rv_content_html with space. replace ” in rv_content_html with space. replace ” in rv_content_html with space. replace ” in rv_content_html with space. replace ” in rv_content_html with space. 

The next step is executed by member method cl_render_page->build_path(), which initializes some parameters and creates two main objects: system and render. These objects contain some parameters, such as minepath, stylepath, spacegifpath, and browser ID, which are needed to build the path to load javascript and mine types (see method cl_render_page->build_page() ). The object system invokes its method cl_render_page->render( ) to render the grid layout to HTML, in which the message content has been embedded.

Method build_path( ):

The said method, cl_render_page->build_page(), needs some parameters as the theme_root, browser_version and agent_type are normally embedded in the HTTP request and at this point are not available in our current context. These parameters can be obtained from the objects request and runtime via the BSP application’s event_handler and the static method cl_render_page=> ser_ext_Param(), which initialize the static attributes user_agent_type, user_agent_version and theme_root of the class.

The following coding must be added to the event handler in our BSP application: Event handler OnInputProcessing:

Once we’ve completed the content layout,method cl_render_page=>render( ) executes method renderer->render( )inininof the object render, which renders the grid layout to HTML.

Having already rendered the layout to HTML, the page can be built using method cl_render_page->build_page( ), which concatenates the page content and adds javascript, stylesheet, and HTML tags to the page. We have now seen that the HTML page containing the long text has been fully generated. However, we need to create a URL for this page. We can do this with the member method create_url(), which invokes the static interface method cl_bsp_runtime=>construct_bsp_url( ) and returns the required URL as a string. The URL consists of tree parts: host, port, application path, a guid path obtained from the method cl_applog=>create_url( ), the client number, and the end, the extension “.htm”. The client number should be added to the URL to avoid login problems in a non-default client.

URL example: )

Method Create_URL:

Once we have reached this point, we only need to save the rendered page to the Web As cache. First, when our generated page (long text message) is requested, the Web As sends it in response to the client. Next, an instance of the interface if_http_responce is created and the page content is added by its interface method, if_http_response->set_cdata( ). The HTTP response code is then set to 200 (OK) and the expiration time for the cache content is set by default to 180 seconds. Finally, the added content is saved as a URL in the ICM cache. As mentioned in the first part of this log series, this topic (ICM Cache) has already been covered in another web log. The content of the saved page is displayed in the ICM cache monitor. Now our message is ready to be called and displayed.

Figure 3: ICM cache monitor

Method cache_page( ):

Closing words

The idea behind this log was more to show you how to display a long text in a separate window with same look and feel as the application. It was not intended to provide a “cut and paste” solution. The challenge here was to create a simple way of enhancing message handling to support the display of T100 message long texts. However, the implementation is rather complex. A better approach – and the next step we must undertake – will be to port this to a BSP extension.

` lv_build “ lv_build “ lv_build “ lv_build “ lv_build “ INTO lv_header_html. CONCATENATE lv_build “ lv_build `

` INTO lv_body_start_html. *—–Add Tags

lv_body_end_html = ”. CONCATENATE lv_header_html lv_body_start_html iv_content_html lv_body_end_html “ INTO rv_html. ENDMETHOD. METHOD create_layout . *——————————————————————– * Create grid layout *——————————————————————– *—–Declarations DATA: lr_gridlayoutcell TYPE REF TO ifur_d2_gridlayoutcell, lr_gridlayoutrow TYPE REF TO ifur_d2_gridlayoutrow, lr_gridlayout TYPE REF TO ifur_d2_gridlayout, lr_tray TYPE REF TO ifur_d2_tray, lr_tabstrip TYPE REF TO ifur_d2_tabstrip, lr_tabstripitem TYPE REF TO ifur_d2_tabstripitem, lr_caption TYPE REF TO ifur_d2_caption, lr_textview TYPE REF TO ifur_d2_textview. *—–Create Gridlayout lr_grid_outer = clur_d2_factory=>gridlayout( width = ‘100%’ height = ‘100%’ margintop = ‘0’ marginbottom = ‘0’ marginleft = ‘0’ marginright = ‘0’ ). *—–Create Row lr_gridlayoutrow = clur_d2_factory=>gridlayoutrow( ). *—–Add this row to layout lr_grid_outer->rows_add( lr_gridlayoutrow ). *—–Create Cell lr_gridlayoutcell = clur_d2_factory=>gridlayoutcell( width = ‘100%’ halign = ifur_d2=>cellhalign_forcedleft valign = ifur_d2=>cellvalign_top ). *—–Create Textview with the html context of the long text lr_textview = clur_d2_factory=>textview( text = iv_content_html design = ifur_d2=>textviewdesign_standard ). *—– Embbed Content in Tray lr_tray = clur_d2_factory=>tray( id = ‘tray01’ title = ‘Details’ design = ifur_d2=>traydesign_plain ). *—–Add Tray to Grid lr_tray->content = lr_textview. lr_gridlayoutcell->content = lr_tray. lr_gridlayoutrow->cells_add( lr_gridlayoutcell ). ENDMETHOD. “create_layout METHOD to_htmlb . *———————————————————————* * Render to HTMLB *———————————————————————* *—–Declarations DATA: lt_html TYPE html_t, lv_help TYPE string. *—– Convert SAPscript-Text to HTML CALL FUNCTION ‘CONVERT_ITF_TO_HTML’ EXPORTING i_header = is_head i_title = ‘—-‘ TABLES t_itf_text = it_docu_lines t_html_text = lt_html. *—–Convert table to line LOOP AT lt_html INTO lv_help. CONCATENATE rv_content_html lv_help INTO rv_content_html. ENDLOOP. *—–Delete not needed HTML Tags REPLACE ” IN rv_content_html WITH space. REPLACE ” IN rv_content_html WITH space. REPLACE ” IN rv_content_html WITH space. REPLACE ” IN rv_content_html WITH space. REPLACE ” IN rv_content_html WITH space. REPLACE ” IN rv_content_html WITH space. REPLACE ” IN rv_content_html WITH space. ENDMETHOD. METHOD BUILD_PATH . *———————————————————————* * Construct Paths *———————————————————————* *—-Declarations DATA: lv_browser_id TYPE string, lv_ur_jsbase TYPE string, lv_basepath TYPE string VALUE ‘/sap/public/bc/ur/Design2002/themes/sap_tradeshow’, lv_hostname TYPE string, lv_port TYPE string. *—–Build path TRANSLATE iv_theme_root TO LOWER CASE. CASE iv_theme_root. WHEN ‘sap_chrome’. lv_basepath = `/sap/public/bc/ur/Design2002/themes/sap_chrome`. WHEN ‘sap_hcb’. lv_basepath = `/sap/public/bc/ur/Design2002/themes/sap_hcb`. WHEN ‘sap_highcont’. lv_basepath = `/sap/public/bc/ur/Design2002/themes/sap_highcont`. WHEN ‘sap_standard’. lv_basepath = `/sap/public/bc/ur/Design2002/themes/sap_standard`. WHEN ‘sap_tradeshow’. lv_basepath = `/sap/public/bc/ur/Design2002/themes/sap_tradeshow`. WHEN OTHERS. lv_basepath = `/sap/public/bc/ur/Design2002/themes/sap_standard`. ENDCASE. CASE iv_user_agent_type. *—–I Explorer WHEN ihttp_user_agent_ie. IF iv_user_agent_version <= 500. *—-IE5 lv_browser_id = ‘ie5’. ELSE. *—–IE6 lv_browser_id = ‘ie6’. ENDIF. *—–Netscape WHEN ihttp_user_agent_nn. IF iv_user_agent_version < 700. *—— lv_browser_id = `nn6`. ELSE. *—— lv_browser_id = `nn7`. ENDIF. *—–Default Internet Explorer 5 WHEN OTHERS. lv_browser_id = `ie5`. ENDCASE. *—–Create system intance er_system = clur_d2_factory=>system( ). *—-Build minepath, sytlepath and giftpath to load them from the browser CONCATENATE lv_basepath ‘/common/’ INTO er_system->mimepath. CONCATENATE lv_basepath ‘/ur/’ INTO er_system->stylepath. CONCATENATE lv_basepath ‘/common/1×1.gif’ INTO er_system->spacegif. er_renderer = clur_d2=>create( device = lv_browser_id standardevents = abap_true ). er_renderer->set_system( er_system ). ENDMETHOD. METHOD set_ext_param . *———————————————* * Set Agent type und version *———————————————* iv_user_agent_version = iv_version. iv_user_agent_type = iv_type. iv_theme_root = iv_theme. ENDMETHOD. endclass. “CL_RENDER_PAGE implementation

You must be Logged on to comment or reply to a post.
  • Nestor, good work. Last year when the book “Advanced BSP Programming” was preannounced I was very pleased that some of the missing functionality in the BSP programming model was to be solved, like F4 help and popups etc. I bought the book and implemented the transports given in a R/3 4.7 SP55 system with very good result. I have the same feeling here – having error messages taken care of by a BSP extension really makes good sense. So, hopefully you can find the time wrapping the described functionality as a BSP extension for all the rest of us here on SDN! Thanks a lot, Johan
    • Hi Johan,
      Thank for your comment. Yes as you’ve already said, the next step will be to wrapp this contruction as BSP extension. I hope to do this as soon as posible.

      Have fun!