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>