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>