Previous Contents Index Next |
Sun Java System Application Server Standard and Enterprise Edition 7 2004Q2 Developer's Guide to NSAPI

> ## Chapter 7
> Creating Custom Server-Parsed HTML Tags

> HTML files can contain tags that are executed on the server. For general information about server-parsed HTML tags, see the Sun Java System Application Server Developer’s Guide to Web Applications.

> In Sun Java System Application Server 7, you can define your own server-side tags. For example, you could define the tag HELLO to invoke a function that prints “Hello World!” You could have the following code in your hello.shtml file:

> <html>
> <head>
> <title>shtml custom tag example</title>
> </head>
> <body>
> <!--#HELLO-->
> </body>
> </html>

> When the browser displays this code, each occurrence of the HELLO tag calls the function.

> The steps for defining a customized server-parsed tag are:

> 1. Define the Functions that Implement the Tag.

> You must define the tag execution function. You must also define other functions that are called on tag loading and unloading and on page loading and unloading.

> 1. Write an Initialization Function.

> Write an initialization function that registers the tag using the shtml_add_tag function.

> 1. Load the New Tag into the Server.

> ##

> Define the Functions that Implement the Tag

> Define the functions that implement the tags in C, using NSAPI.

> - Include the header shtml_public.h, which is in the directory install_dir/include/shtml.
> - Link against the shtml shared library. On UNIX platforms, libshtml.so or .sl is in install_dir/lib.

> ShtmlTagExecuteFunc is the actual tag handler. It gets called with the usual NSAPI pblock, Session, and Request variables. In addition, it also gets passed the TagUserData created from the result of executing the tag loading and page loading functions (if defined) for that tag.

> The signature for the tag execution function is:

> typedef int (*ShtmlTagExecuteFunc)(pblock*, Session*, Request*, TagUserData, TagUserData);

> Write the body of the tag execution function to generate the output to replace the tag in the .shtml page. Do this in the usual NSAPI way, using the net_write NSAPI function, which writes a specified number of bytes to a specified socket from a specified buffer.

> For more information about writing NSAPI plug-ins, see Chapter 4, “Creating Custom SAFs.”

> For more information about net_write and other NSAPI functions, see Chapter 6, “NSAPI Function Reference.”

> The tag execution function must return an int that indicates whether the server should proceed to the next instruction in obj.conf or not, which is one of:

> - REQ_PROCEED -- the execution was successful.
> - REQ_NOACTION -- nothing happened.
> - REQ_ABORTED -- an error occurred.
> - REQ_EXIT -- the connection was lost.

> The other functions you must define for your tag are:

> - ShtmlTagInstanceLoad

> This is called when a page containing the tag is parsed. It is not called if the page is retrieved from the browser’s cache. It basically serves as a constructor, the result of which is cached and is passed into ShtmlTagExecuteFunc whenever the execution function is called.

> - ShtmlTagInstanceUnload

> This is basically a destructor for cleaning up whatever was created in the ShtmlTagInstanceLoad function. It gets passed the result that was originally returned from the ShtmlTagInstanceLoad function.

> - ShtmlTagPageLoadFunc

> This is called when a page containing the tag is executed, regardless of whether the page is still in the browser’s cache or not. This provides a way to make information persistent between occurrences of the same tag on the same page.

> - ShtmlTagPageUnLoadFn

> This is called after a page containing the tag has executed. It provides a way to clean up any allocations done in a ShtmlTagPageLoadFunc and hence gets passed the result returned from the ShtmlTagPageLoadFunc.

> The signatures for these functions are:

> #define TagUserData void*
> typedef TagUserData (*ShtmlTagInstanceLoad)(
> const char* tag, pblock*, const char*, size_t);
> typedef void (*ShtmlTagInstanceUnload)(TagUserData);
> typedef int (*ShtmlTagExecuteFunc)(
> pblock*, Session*, Request*, TagUserData, TagUserData);
> typedef TagUserData (*ShtmlTagPageLoadFunc)(
> pblock* pb, Session*, Request*);
> typedef void (*ShtmlTagPageUnLoadFunc)(TagUserData);

> Here is the code that implements the HELLO tag:

> /*
> * mytag.c: NSAPI functions to implement #HELLO SSI calls
> *
> *
> */
> #include "nsapi.h"
> #include "shtml/shtml_public.h"
> /* FUNCTION : mytag_con
> *
> * DESCRIPTION: ShtmlTagInstanceLoad function
> */
> #ifdef __cplusplus
> extern "C"
> #endif
> TagUserData
> mytag_con(const char* tag, pblock* pb, const char* c1, size_t t1)
> {
> return NULL;
> }
> /* FUNCTION : mytag_des
> *
> * DESCRIPTION: ShtmlTagInstanceUnload
> */
> #ifdef __cplusplus
> extern "C"
> #endif
> void
> mytag_des(TagUserData v1)
> {
> }
> /* FUNCTION : mytag_load
> *
> * DESCRIPTION: ShtmlTagPageLoadFunc
> */
> #ifdef __cplusplus
> extern "C"
> #endif
> TagUserData
> mytag_load(pblock *pb, Session *sn, Request *rq)
> {
> return NULL;
> }
> /* FUNCTION : mytag_unload
> *
> * DESCRIPTION: ShtmlTagPageUnloadFunc
> */
> #
> #ifdef __cplusplus
> extern "C"
> #endif
> void
> mytag_unload(TagUserData v2)
> {
> }
> /* FUNCTION : mytag
> *
> * DESCRIPTION: ShtmlTagExecuteFunc
> */
> #ifdef __cplusplus
> extern "C"
> #endif
> int
> mytag(pblock* pb, Session* sn, Request* rq, TagUserData t1, TagUserData t2)
> {
> char* buf;
> int length;
> char* client;
> buf = (char *) MALLOC(100*sizeof(char));
> length = util_sprintf(buf, "<h1>Hello World! </h1>", client);
> if (net_write(sn->csd, buf, length) == IO_ERROR)
> {
> FREE(buf);
> return REQ_ABORTED;
> }
> FREE(buf);
> return REQ_PROCEED;
> }
> /* FUNCTION : mytag_init
> *
> * DESCRIPTION: initialization function, calls shtml_add_tag() to
> * load new tag
> */
> #
> #ifdef __cplusplus
> extern "C"
> #endif
> int
> mytag_init(pblock* pb, Session* sn, Request* rq)
> {
> int retVal = 0;
> // NOTE: ALL arguments are required in the shtml_add_tag() function
> retVal = shtml_add_tag("HELLO", mytag_con, mytag_des, mytag, mytag_load, mytag_unload);
> return retVal;
> }
> /* end mytag.c */

> ##

> Write an Initialization Function

> In the initialization function for the shared library that defines the new tag, register the tag using the function shtml_add_tag. The signature is:

> NSAPI_PUBLIC int shtml_add_tag (
> const char* tag,
> ShtmlTagInstanceLoad ctor,
> ShtmlTagInstanceUnload dtor,
> ShtmlTagExecuteFunc execFn,
> ShtmlTagPageLoadFunc pageLoadFn,
> ShtmlTagPageUnLoadFunc pageUnLoadFn);

> Any of these arguments can return NULL except for the tag and execFn.

> ##

> Load the New Tag into the Server

> After creating the shared library that defines the new tag, you load the library into the Sun ONE Application Server in the usual way for NSAPI plug-ins. That is, add the following directives to the configuration file init.conf:

> 1. Add an Init directive whose fn parameter is load-modules and whose shlib parameter is the shared library to load. For example, if you compiled your tag into the shared object install_dir/hello.so, it would be:

> Init funcs="mytag,mytag_init" shlib="install_dir/hello.so" fn="load-modules"

> 2. Add another Init directive whose fn parameter is the initialization function in the shared library that uses shtml_add_tag to register the tag. For example:

> Init fn="mytag_init"

> Previous Contents Index Next

> Copyright 2004 Sun Microsystems, Inc. All rights reserved.