faq | docs | tutorials | guide | reference | contact | home  

TUTORIAL - ACTIVE PAGES Previous | Next | Tutorial Home

The FGL environment uses the concept of Active Pages to create dynamically generated web content. An Active Page is an ordinary HTML-based web page with optional embedded FGL (and other language) instructions. You use Active Pages to create web-based programs that can be as simple or complex as you want (they can also be used to create standalone desktop-based applications – more on that in the desktop-application tutorial).

To begin, create a standard web page in your favorite editor (or you can use the highly recommended TextPad with FGL syntax highlighting) – only save it with the .AP extension instead of .HTM or .HTML. Save it in a directory that is accessible through a web server. If you are using the FifthGen server the default directory is c:\fgl\server\home or below. For example:

Default HTML page, saved as c:\fgl\server\home\sample1.ap:
<html>
<head>
 <title>Sample Active Page</title>
</head>
<body text=black bgcolor=white>
This is my first FGL Active Page.
</body>
</html>

FGL instruction can be added to an Active Page using the HTML “<script language=FGL>” tag, or through the more efficient and flexible “<[” tag. In either case, FGL instructions are surrounded by beginning and ending tags. For example:

Active Page with embedded FGL tags:
<html>
<head>
 <title>Sample Active Page</title>
</head>
<body text=black bgcolor=white>
This is my first FGL Active Page.<br><br>

<script language=FGL>
! "The date today is " + date( )
</script><br><br>

And the current time is <[ ! time( ) ]>

</body>
</html>

With the FifthGen server, you can access .AP pages by using standard .HTM and .HTML names, such as http://localhost/sample1.htm. In this case, the FifthGen server will first look to see if it can find the actual “sample1.htm” page, then check for .AP page if not found. This allows Active Pages to be referenced as regular HTML pages, thereby providing added page visibility to search engines (the actual page-name resolution methodology and its optimizations are a bit more involved than this, but that is for a later discussion). Non-FifthGen servers access Active Pages using the actual .AP name, as in http://localhost/sample1.ap.

When a user requests an Active Page through the browser, the server will recognize the page by its .AP extension and look for embedded FGL instructions. If it finds any, it will execute the commands on the server and return the resultant page to the user as if it were a pure HTML file.

By default, FGL instructions do not alter or insert anything in an Active Page. The INSERTION OPERATOR ( “!” ) is used to tell the server to take the results of the execution of FGL instructions and insert them into the Active Page. For example:

Active Page demonstrating the FGL INSERTION OPERATOR:
<html>
<head>
 <title>Sample Active Page</title>
</head>
<body text=black bgcolor=white>

<script language=FGL>
    
    d = date( )                        // this does not insert anything
    t = time( )                        // neither does this
    
    ! "Today is " + d + " at " + t     // this uses the insertion operator
                                       // to insert the results in the page
</script>

</body>
</html>

[Note that the insertion operator uses the same character reference as the NOT operator. The engine tells the difference based on the structure of the character’s use. Command lines that begin with the “!” character are treated as insertion operators, while elsewhere it is treated as the NOT operator]

FGL instructions can be added to Active Pages in either INLINE or BLOCK mode. With the inline mode, FGL instructions are added individually in the exact location desired within the page. Inline instructions are almost always used in conjunction with the insertion operator. Block mode defines an area within the Active Page containing a sequence of FGL commands. For example:

Active Page with INLINE vs. BLOCK mode FGL:
<[ session = new( "session" ) ]>
<html>
<head>
 <title>Sample Active Page</title>
</head>
<body text=black bgcolor=white>

<p>This is an example of the FGL INLINE mode: presented on
this <[ ! date( "DDD day of MMMM, YYYY") ]> at <[ ! timetostr( time( ), 0 ) ]>m. 
The host name is <[ ! session.host ]> and HTTP version is <[ ! session.HTTPversion ]>.

<p>This is an example of the FGL BLOCK mode:
<[
    dte = date( "DDD day of MMMM, YYYY")
    tme = timetostr( time( ), 0 ) + "m"
    host = session.host
    version = session.HTTPversion
    
    ! "presented on the " + dte + " at " + tme + ". "
    ! "The host name is " + host + " and HTTP version is " + version
]>
</body>
</html>

The above example introduces a new concept: objects. The session object is used to get information about the server host and HTTP version. The first line of the Active Page creates an instance of the “session” object and stores it to a variable also named (coincidentally) session. Its contents can then be accessed throughout the rest of the page (more on objects in a subsequent discussion).

When using FGL BLOCK mode, you can “toggle” in and out of HTML and FGL mode at will with the FGL INLINE HTML tag, <% (opening) and %> (closing). This makes it easy to wrap complex HTML code in FGL instructions. For example:

Accessing HTML mode within an FGL block:
<[
    session = new( "session" ) 
    
    fname = "Steve"
    lname = "Repetti"
]>
<html>
<head>
 <title>Sample Active Page</title>
</head>
<body text=black bgcolor=white>

<[
    if ( session.IsMicrosoft( ) )
        <%
            This browser is "Microsoft" compatible and the date is <[ ! date ( ) ]>
            and my name is <[ ! fname ]> <[ ! lname ]>.
        %>
    else
        <%
            This browser is not "Microsoft" compatible and the date is <[ ! date ( ) ]>,
            the time is <[ ! time( ) ]>, and my name is <[ ! fname + " " + lname ]>.
        %>
    end
]>

</body>
</html>

Once a variable or class has been defined it is available throughout the rest of the Active Page. In this regard, you must define a variable or class in an Active Page before you use it.

Active Pages make it easy to create complex dynamically generated content for the web. You can include inline and block FGL instructions, library references, as well as local procedures, functions, and class definitions within an Active Page. The overall syntax for using Active Pages is:

Active Page Syntax:
<[
    // LIBRARY references
    
    // local CLASS definitions
    // local FUNCTION definitions
    
    // Initialization FGL instructions
]>
<html>
<head>
 <title>Sample Active Page</title>
</head>
<body text=black bgcolor=white>

<[ ! "Embedded INLINE FGL instructions. " ]>

<[
	! "Embedded "
	! "FGL BLOCK instructions. "
    <%
        Switching into FGL mode within an FGL BLOCK
    %>
]>

</body>
</html>

Active Pages can easily interact with the server environment through the use of the internal FGL "session" object. For example:

Active Page server interaction:
<[
    session = new( "session" )
]>
<html>
<head>
 <title>Active Page demonstrating server interaction</title>
</head>
<body text=black bgcolor=white>

<[
    a = { "ALL_HTTP", "ALL_RAW", "APPL_MD_PATH", "APPL_PHYSICAL_PATH", 
          "AUTH_PASSWORD", "AUTH_TYPE", "AUTH_USER", "CERT_COOKIE", 
          "CERT_FLAGS", "CERT_ISSUER", "CERT_KEYSIZE", "CERT_SECRETKEYSIZE",
          "CERT_SERIALNUMBER", "CERT_SERVER_ISSUER", "CERT_SERVER_SUBJECT", 
          "CERT_SUBJECT", "CONTENT_LENGTH", "CONTENT_TYPE", "HTTP_ACCEPT", 
          "HTTPS", "HTTPS_KEYSIZE", "HTTPS_SECRETKEYSIZE", "HTTPS_SERVER_ISSUER",
          "HTTPS_SERVER_SUBJECT", "INSTANCE_ID", "INSTANCE_META_PATH", 
          "PATH_INFO", "PATH_TRANSLATED", "QUERY_STRING", "REMOTE_ADDR", 
          "REMOTE_HOST", "REMOTE_USER", "REQUEST_METHOD", "SCRIPT_NAME",
          "SERVER_NAME", "SERVER_PORT", "SERVER_PORT_SECURE", "SERVER_PROTOCOL", 
          "SERVER_SOFTWARE", "URL"," HTTP_COOKIE", "LOGON_USER", "REQUEST_URI", 
          "HTTP_AUTHORIZATION"
    }
    
    ! "<p>Session DATA elements</p>"
    ! "<table border=1 width=100% cellspacing=0 cellpadding=2 class=smtxt>"
    
    cnt = len( a )
    for ( i=1; i<=cnt; i++ )
        ! "<tr><td>" + a[i] + ":</td><td>" + session.data(a[i]) + "&nbsp;</td></tr>\r\n"
    end
    
    ! "</table>"
]>
          
<p>Session Object access variables</p>
<table border=1 width=100% cellspacing=0 cellpadding=2 class=smtxt>
 <tr><td>Total Bytes Sent:</td><td><[ ! session.TotalBytesSent ]></td></tr>
 <tr><td>Total Bytes Received:</td><td><[ ! session.TotalBytesRcvd ]></td></tr>
 <tr><td>AP BytesSent:</td><td><[ ! session.APBytesSent ]></td></tr>
 <tr><td>Authentication Failures:</td><td><[ ! session.AuthenticateFailures ]></td></tr>
 <tr>
  <td>Authentication Challenges:</td>
  <td><[ ! session.AuthenticateChallenges ]></td>
 </tr>
 <tr><td>Total Conections:</td><td><[ ! session.TotalConnections ]></td></tr>
 <tr><td>Total Requests:</td><td><[ ! session.TotalRequests ]></td></tr>
 <tr><td>Total Responses:</td><td><[ ! session.TotalResponses ]></td></tr>
 <tr><td>URL:</td><td><[ ! session.url ]></td></tr>
 <tr><td>Request Method:</td><td><[ ! session.method ]></td></tr>
 <tr><td>Server Root:</td><td><[ ! session.ServerRoot ]></td></tr>
 <tr><td>Server Config file:</td><td><[ ! session.ServerConfigFile ]></td></tr>
 <tr><td>Engine Config File:</td><td><[ ! session.EngineConfigFile ]></td></tr>
 <tr><td>Transaction Log File:</td><td><[ ! session.TransactionLogFile ]></td></tr>
 <tr><td>System Log File:</td><td><[ ! session.systemLogFile ]></td></tr>
</table>

</body>
</html>

DEVNOTE: This Active Page uses FGL and arrays to automatically determine the PREVIOUS and NEXT options for the turorial selections. Click here to view the source code (search for the "TutorialLinks" method in the "pagelib" class).

#####