Extending Embedded Server Pages™

Embedded Server Pages provides a strong library of standard functions and data variables. However, ESP is excels when it is extended via custom JavaScript functions to allow dynamic data and commands to be simply called from within ESP pages. ESP Applications normally create functions for data display, input validation and command execution. Selecting the right set of JavaScript functions (controls) to create is secret to creating powerful and elegant ESP applications.

Embedded Server Pages (ESP) has been designed to be easily extended via the creation of new JavaScript functions that are bound to equivalent C functions. When the JavaScript function is called, the matching C function is invoked. The C and JavaScript functions are bound together by calling an ESP API that defines the functions in the ESP variable space and specifies the required calling convention.

How to Create ESP Procedures

You can easily create Embedded Server Page procedures in both C and C++ languages. However, the C API is simpler and is recommended over the C++ API. The C++ API is officially deprecated.

Creating ESP Functions in C

To create an ESP function in C, you create a function to execute when the ESP JavaScript function is invoked. This function is passed the ESP request handle and the actual arguments passed to the JavaScript function at run-time.

You can create two kinds of ESP C functions. The simplest, shown below, automatically converts all arguments to strings before calling the C function. These are called String ESP Functions and are created via the espDefineStringCFunction API call. This method of function definition is ideal when the arguments and function result will always be strings.

The other kind of function definition does not convert the arguments to strings. Arguments are passed in an array of MprVar variables. These variables may be strings, boolean, integer, floating point or object variables. This style of function definition is best when any type of argument may be passed into the function.

For example, the following code fragment creates a String ESP function that will be invoked when an ESP page specifies <% myEsp(); %>.

#include "esp.h"

static int myEspProc(EspRequest *ep, int argc, char **argv)
{
maWriteStr("Hello World");
}

// Somewhere in the main program

espDefineStringCFunction(0, "myEsp", myEspProc, 0);

NOTE: the ESP C function is essentially stateless. It is passed the ESP request handle from which per-request data may be accessed.

Creating ESP Functions in JavaScript

You can create ESP functions directly in your ESP page. The following code creates a global JavaScript function:

function myProc(name, address)
{
// Do anything you like with the data here
}

You can also create JavaScript functions from within C / C++ code by calling the espDefineFunction API and passing to it a string containing the function body and a string containing the arguments.

Creating ESP Procedures in C++

In AppWeb, you can also create an ESP functions if you subclass the MaEspProc class and override the run method. The run method is called whenever the procedure is run by the ESP handler. For example, the following code fragment creates an ESP procedure that will be invoked when an ESP page specifies <% myEsp(); %>.

#include "appWeb/appWeb.h"

class MyEsp : public MaEspProc {
public:
MyEsp() : MaEspProc("myEsp") {};
~MyEsp() {};
int run(MaRequest *rq, int argc, char **argv);
};

int MyEsp::run(MaRequest *rq, int argc, char **argv)
{
rq->write("Hello World");
return 0;
}

// Somewhere in the main program
new MyEsp();

You can also provide constructors and destructors for your class if you have persistent data structures that you need create.

Tips for Effective ESP Web Pages

Returning a Result

ESP Procedures may return a result that can then be assigned to JavaScript variables within the ESP page. To return a result, use the espSetReturn and espSetReturnString calls. See the simpleEsp sample for details. For example, the ESP page fragment uses the result of a database read call and tests the returned value before conditionally displaying a message.

<% 
temperature = dbRead("myDb", "system", "temperature");

if (temperature > 100) {
write("Wow it is hot");
}
%>

Don't use Write Too Much JavaScript

Embedded JavaScript is meant to be used as glue between your application and the web page. You must be careful not to write too much JavaScript in a single page. While AppWeb will certainly run the script, it can be hard to debug and verify the correctness of large JavaScript programs.

JavaScript is not a scalable language like C/C++ and large JavaScript programs can be difficult to debug. In large programs, the key strength of JavaScript, namely its easy typeless expressions, and dynamic typing can obscure subtle bugs that only surface at run-time. Furthermore, EJS does not have the development support tools and debuggers that C/C++ have. So keep your scripts small and push complex logic into EJS functions written in C/C++.

Use Inline Variable Access

You can use write within an ESP script. However it is often more conventient to invert the script. For example:

<% 
temperature = dbRead("myDb", "system", "temperature");
write("Today's temperature is ", temperature, " degrees);
%>

is better written as:

<% temperature = dbRead("myDb", "system", "temperature"); %>
Today's temperature is @@temperature



© Mbedthis Software LLC, 2003-2204. All rights reserved. Mbedthis is a trademark of Mbedthis Software LLC.