IBM Books

Net.Data Programming Guide


Anatomy of a Net.Data macro File

In this section, a simple Net.Data macro illustrates the elements of the macro language. This example macro presents a form that prompts for information to pass to a REXX program. The macro passes this information to an external REXX program called OMPSAMP.CMD, which echoes the data entered by the user. The results are then displayed in a second HTML page.

First, look at the entire macro, then each block in detail:

%{ **********************       Define block        ************************%}
%DEFINE {
   page_title="Net.Data macro Template"
%}
 
%{ ********************** Function Definition block ************************%}
%FUNCTION(DTW_REXX) rexx1 (IN input) returns(result)
    { %EXEC{ompsamp.cmd %}
%}
 
%FUNCTION(DTW_REXX) today () RETURNS(result)
  {
      result = date()
%}
 
%{ **********************      HTML Block: Input    ************************%}
%HTML (INPUT) {
<html>
<head>
<title>$(page_title)<title>
</head><body>
<h1>Input Form</h1>
Today is @today()
 
<FORM  METHOD="post" ACTION="output">
Type some data to pass to a REXX program:
<INPUT NAME="input_data" TYPE="text" SIZE="30">
<p>
<INPUT TYPE="submit" VALUE="Enter">
 
<hr>
<p>[<a href="/">Home page]
</body></html>
%}
 
%{ **********************    HTML Block: Output     ************************%}
%HTML (OUTPUT) {
<html>
<head>
<title>$(page_title)</title>
</head><body>
<h1>Output Page</h1>
<p>@rexx1(input_data)
<p><hr>
<p>[<a href="/">Home page</a> |
<a href="input">Previous page</a>]
</body></html>
%}
 

The macro consists of four major blocks: the DEFINE, the FUNCTION, and the two HTML blocks. You can have multiple DEFINE, FUNCTION, and HTML blocks in one Net.Data macro.

The two HTML blocks contain familiar HTML tags, which makes writing Web macros easy. If you are familiar with HTML, building a macro simply involves adding macro statements to be processed dynamically at the server and SQL to send to the database.

Although the macro looks similar to an HTML document, the Web server accesses it through Net.Data as a CGI program or a Web server API. Net.Data requires two parameters: the name of the macro to process, and the HTML block in that macro to display.

When the macro file is invoked, Net.Data processes it from the beginning. The next sections look at what happens as Net.Data processes the file.

Define Block

%{ **********************       Define Block        ************************%}
%DEFINE {
   page_title="Net.Data macro Template"
%}

The first line is a comment. A comment is any text inside %{ and %}. Comments must be outside other macro blocks. The next statement starts a DEFINE block. You can define multiple variables in one define block. In this example, only one variable, page_title, is defined. Once defined, this variable can be referenced anywhere in the macro using the syntax, $(page_title). Using variables makes it easy to make global changes to your macro later. The last line of this block, %}, identifies the end of the DEFINE block.

The next block is the function definition block, but first look at the HTML block called INPUT in the example.

HTML Block

%{ **********************      HTML Block: Input    ************************%}
%HTML (INPUT) {               <--- Identifies the name of this HTML block.
<html>
<head>
<title>$(page_title)</title>  <--- Note the variable substitution.
</head><body>
<h1>Input Form</h1>
Today is @today()             <--- This line contains a call to a function.
 
<FORM METHOD="post" ACTION="output">  <--- When this form is submitted,
                                           the "output" HTML block is called.
Type some data to pass to a REXX program:
<INPUT NAME="input_data"      <--- "input_data" is defined when the form
TYPE="text" SIZE="30">             is submitted and can be referenced elsewhere in
                                   this macro. It is initialized to whatever the
                                   user types into the input field.
<p>
<INPUT TYPE="submit" VALUE="Enter">
 
<hr>
<p>
[
<a href="/">Home page</a>]
 </body><html>
%}                            <--- Closes the HTML block.

This block contains the HTML for a simple form with one input field. The entire block is surrounded by the HTML block identifier, %HTML (INPUT) { ... %}. INPUT identifies the name of this block. You can give it any name. The HTML <title> tag contains an example of macro substitution. The contents of the variable page_title are substituted into the title of the form.

This block also has an example of a function call. The expression @today() is a call to the function today. This function is defined in the FUNCTION block that is described later. The result of the today function, the current date, is inserted into the HTML text in the same location that the @today() expression is located.

The ACTION parameter of the FORM statement is an example of navigation between HTML blocks or between macros. Referencing the name of another block in an ACTION parameter accesses that block when the form is submitted. Any input data from an HTML form is passed to the block as implicit variables. This is true of the single input field defined on this form. When the form is submitted, data typed into this field is passed to the HTML output block in the variable input_data.

You can access HTML blocks in other macro files with a relative reference if the macro files are on the same Web server. For example, ACTION="../othermacro.mac/main" accesses the HTML block called main in the macro file othermacro.mac. Again, any data typed into the form is passed to this macro in the variable input_data.

When you invoke Net.Data, you pass the variable as part of the URL. For example:

<a href="/cgi-bin/db2www/othermacro.mac/main?input_data=value">Next macro</a>

There is no need to deal with environment variables to receive input data, as one does with most CGI programs. Net.Data handles them for you. You only need to reference the variable names.

The next HTML block in the example is the OUTPUT block.

%{ **********************    HTML Block: Output     ************************%}
%HTML (OUTPUT) {
<html>
<head>
<title>$(page_title)</title>  <--- More substitution.
</head><body>
<h1>Output Page</h1>
<p>@rexx1(input_data)  <--- This line contains a call to function rexx1
                            passing the argument "input_data".
<p>
<hr>
<p>
[
<a href="/">Home page</a> |
<a href="input">Previous page</a>]
%}

Like the INPUT block, this block is standard HTML with macro statements to substitute variables and a function call. Again the page_title variable is substituted into the title statement. And, as before, this block contains a function call. In this case, it calls the function rexx1 and passes to it the contents of the variable input_data which it received from the INPUT form. You can pass any number of variables to and from a function. The function definition determines the number of variables passed and their type.

For more details on functions, see "Function Definition Block".

Function Definition Block

%{ ********************** Function Definition Block ************************%}
%FUNCTION(DTW_REXX) rexx1 (IN input) returns(result) { <-- This function accepts
                                                       one parameter and returns a
                                                       result which is substituted
                                                       for the associated function
                                                       call
     %EXEC{ompsamp.cmd %}  <-- The function executes an external REXX program
                               called "ompsamp.cmd"
%}
 
%FUNCTION(DTW_REXX) today () RETURNS(result) {
      result = date()  <-- The single source statement for this function is 
                           contained inline.
%}

This function definition block contains two function declarations. The first, rexx1, is a REXX function declaration that, in turn, executes an external REXX program called ompsamp.cmd. One input variable, input, is accepted by this function and automatically passed to the external REXX command. The REXX command also returns one variable called result. The contents of the result variable in the REXX command replaces the invoking @rexx1() function call contained in the OUTPUT block. The variables input and result are directly accessible by the REXX program, as shown in the source for ompsamp.cmd:

/* REXX */
result = 'The REXX program received "'input'" from the macro.'

The code in this function echoes the data that passed to it. You can format the resulting text any way you want by enclosing the requesting @rexx1() function call in normal HTML style tags (like <b> or <em>). Rather than using the result variable, the REXX program could have written HTML tags to standard output using REXX SAY statements.

The second function declaration, today, also refers to a REXX program. However, the entire REXX program (one whole line) in this case is contained in the function declaration itself. An external program is not needed. Inline programs are allowed for both REXX and PERL functions because they are interpreted languages that can be parsed and executed dynamically. Inline programs have the advantage of simplicity by not requiring a separate program file to manage. The first REXX function could also just as well have been handled inline.


[ Top of Page | Previous Page | Next Page | Table of Contents | Index ]