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 <b>", temperature, "</b> degrees);
%>
is better written as:
<% temperature = dbRead("myDb", "system", "temperature"); %>
Today's temperature is <b>@@temperature</b>