503 lines
30 KiB
HTML
503 lines
30 KiB
HTML
<!-- BeginDsi "dsi/head.html" -->
|
|
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<title>Embedthis Appweb 4.3.4 Documentation</title>
|
|
<meta name="keywords" content="embedded web server, web server software, embedded HTTP, application web server,
|
|
embedded server, small web server, HTTP server, library web server, library HTTP, HTTP library" />
|
|
<meta name="description" content="Embedthis Sofware provides commercial and open source embedded web servers for
|
|
devices and applications." />
|
|
<meta name="robots" content="index,follow" />
|
|
<link href="../../../doc.css" rel="stylesheet" type="text/css" />
|
|
<link href="../../../print.css" rel="stylesheet" type="text/css" media="print"/>
|
|
<!--[if IE]>
|
|
<link href="../../../iehacks.css" rel="stylesheet" type="text/css" />
|
|
<![endif]-->
|
|
<link href="http://www.google.com/cse/style/look/default.css" type="text/css" rel="stylesheet" />
|
|
</head>
|
|
|
|
<body>
|
|
<div class="top">
|
|
<a class="logo" href="http://appwebserver.org/"> </a>
|
|
<div class="topRight">
|
|
<div class="search">
|
|
<div id="cse-search-form"></div>
|
|
<div class="version">Embedthis Appweb 4.3.4</div>
|
|
</div>
|
|
</div>
|
|
<div class="crumbs">
|
|
<a href="../../../index.html">Home</a>
|
|
<!-- EndDsi -->
|
|
><a href="index.html">ESP Guide</a>> <b>Controllers and Actions</b>
|
|
</div>
|
|
</div>
|
|
<div class="content">
|
|
<div class="contentRight">
|
|
<h1>Quick Nav</h1>
|
|
<ul class="nav">
|
|
<li><a href="#example">Controller Example</a></li>
|
|
<li><a href="#routing">Routing Requests</a></li>
|
|
<li><a href="#config">Configuring a Controller</a></li>
|
|
<li><a href="#actions">Actions</a></li>
|
|
<li><a href="#context">Controller Context</a></li>
|
|
<li><a href="#parameters">Request Parameters</a></li>
|
|
<li><a href="#generating">Generating Controllers</a></li>
|
|
</ul>
|
|
<!-- BeginDsi "dsi/espSeeAlso.html" -->
|
|
<h1>See Also</h1>
|
|
<ul class="nav">
|
|
<li><a href="../../../guide/esp/users/using.html">ESP Overview</a></li>
|
|
<li><a href="../../../guide/esp/users/tour.html">ESP Tour</a></li>
|
|
<li><a href="../../../guide/esp/users/template.html">Templates and Layouts</a></li>
|
|
<li><a href="../../../guide/esp/users/controls.html">HTML Controls</a></li>
|
|
<li><a href="../../../guide/esp/users/config.html">ESP Configuration Directives</a></li>
|
|
<li><a href="../../../guide/esp/users/mvc.html">Model-View-Controller</a></li>
|
|
<li><a href="../../../guide/esp/users/generator.html">Application Generator</a></li>
|
|
<li><a href="../../../guide/esp/users/controllers.html">Controllers and Actions</a></li>
|
|
<li><a href="../../../guide/esp/users/database.html">Database Interface</a></li>
|
|
<li><a href="../../../guide/appweb/users/caching.html">Caching Responses</a></li>
|
|
</ul>
|
|
<!-- EndDsi -->
|
|
|
|
<ul>
|
|
<li><a href="../../../api/esp.html">ESP Library</a></li>
|
|
</ul>
|
|
</div>
|
|
<div class="contentLeft">
|
|
<h1>Controllers and Actions</h1>
|
|
<p>The ESP Model-view-controller (MVC) architecture is a pattern for designing well-structured applications and
|
|
MVC applications have proven to be an effective organization for web applications. A key reason is that MVC apps
|
|
separate the logic (<em>controller</em>), from the presentation (<em>view</em>) and the application's
|
|
data (<em>model</em>). This clear partition of responsibilities, scales well and helps to create maintainable
|
|
applications.</p>
|
|
<p>MVC <em>controllers</em> are the conductors of the application and they orchestrate the application's
|
|
activities. Via <em>action</em> functions, they receive client requests and generate appropriate responses,
|
|
mutating the applications data model in the process.</p>
|
|
<a id="example"></a>
|
|
<h2 class="section">Example of a Controller</h2>
|
|
<p>So what does a controller look like? Here is a partial example that has four actions:</p>
|
|
<pre class="light">
|
|
#include "esp.h"
|
|
static void create() {
|
|
/* Create post here */
|
|
redirect("list")
|
|
}
|
|
static void list() { }
|
|
}
|
|
static void edit() {
|
|
/* Create post here */
|
|
}
|
|
static void update() {
|
|
/* Update post here */
|
|
renderView("post-edit");
|
|
}
|
|
ESP_EXPORT int esp_controller_post(HttpRoute *route, MprModule *module)
|
|
{
|
|
Edi *edi;
|
|
espDefineAction(route, "post-create", create);
|
|
espDefineAction(route, "post-edit", edit);
|
|
espDefineAction(route, "post-list", list);
|
|
espDefineAction(route, "post-update", update);
|
|
return 0;
|
|
}
|
|
</pre>
|
|
<p>Say the client issues a request for:</p>
|
|
<pre>
|
|
http://embedthis.com/app/post/create
|
|
</pre>
|
|
<p>assuming a correctly configured request route, the <em>create</em> action, in the <em>post</em>
|
|
controller will be run. This will create a new blog post and then render the <em>post-list.esp</em>
|
|
view of posts back to the client.</p>
|
|
<a id="routing"></a>
|
|
<h2 class="section">Routing Requests</h2>
|
|
<p>At the heart of understanding how controllers are loaded and actions are run, is understanding Appweb
|
|
routing. When Appweb receives a client request, it examines each of the request routes configured in the
|
|
<em>appweb.conf</em> configuration file, until it finds a matching route for the request URI. The selected
|
|
route will then break the URI into tokens and save the token values as request parameters.</p>
|
|
<p>For example: consider the URI format:</p>
|
|
<pre>
|
|
http://embedthis.com/APP/CONTROLLER/ACTION/ID
|
|
</pre>
|
|
<p>In this example, <em>APP</em> is the (optional) name of the application, <em>CONTROLLER</em> is the controller
|
|
name, <em>ACTION</em> is the name of the action method to run and <em>ID</em> is a selector for an element
|
|
in the Model. When the request URI is tokenized, the Appweb router will extract the controller name and then
|
|
use this name to load the appropriate controller to service the request.</p>
|
|
<h3>RESTful Routes</h3>
|
|
<p>A RESTful approach to designing URI routes is also often used where different controller
|
|
actions are linked to specific routes. The benefit being being simple, readable, RESTful URIs.</p>
|
|
<table title="routes">
|
|
<thead>
|
|
<tr><th>Name</th><th>Method</th><th>Pattern</th><th>Action</th></tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr><td>init</td><td>GET</td><td>/CONTROLLER/init$</td><td>init</td></tr>
|
|
<tr><td>create</td><td>POST</td><td>/CONTROLLER(/)*$</td><td>create</td></tr>
|
|
<tr><td>edit</td><td>GET</td><td>/CONTROLLER/edit$</td><td>edit</td></tr>
|
|
<tr><td>show</td><td>GET</td><td>/CONTROLLER$</td><td>show</td></tr>
|
|
<tr><td>update</td><td>PUT</td><td>/CONTROLLER$</td><td>update</td></tr>
|
|
<tr><td>destroy</td><td>DELETE</td><td>/CONTROLLER$</td><td>destroy</td></tr>
|
|
<tr><td>default</td><td>*</td><td>/CONTROLLER/{action}$</td><td>cmd-${action}</td></tr>
|
|
</tbody>
|
|
</table>
|
|
<p>In either case, RESTFul or not, the request URI is broken into tokens that specify the controller and
|
|
action to invoke to service the request. When a request is received, ESP will create an instance of the
|
|
controller and invoke the requested action method.</p>
|
|
<a id="flow"></a>
|
|
<h3>Processing Flow</h3>
|
|
<p>Appweb processes requests in stages:</p>
|
|
<ol>
|
|
<li>Decode the URI and web request</li>
|
|
<li>Route an incoming request to the request handler (ESP)</li>
|
|
<li>If the request is for a web page, run that and render a response</li>
|
|
<li>Otherwise if the request is routed to a controller, load the controller</li>
|
|
<li>Run the specified controller action determined by the request route pattern</li>
|
|
<li>Optionally render a response view to the client</li>
|
|
</ol>
|
|
<a id="config"></a>
|
|
<h2 class="section">Configuring Controllers</h2>
|
|
<p>Controllers may be configured two ways:</p>
|
|
<ul>
|
|
<li>As part of an MVC application</li>
|
|
<li>As a stand-alone controller function.</li>
|
|
</ul>
|
|
<h3>MVC Configuration</h3>
|
|
<p>MVC applications are typically created via the <a href="generator.html">esp</a> generator command.
|
|
The <em>esp</em> command is used to create a bare MVC application with a directory for controllers,
|
|
views and databases. It is also used generate an <em>appweb.conf</em> configuration file to use when
|
|
you run Appweb to host your application. By default, this configuration file will have an
|
|
<em>EspApp</em> directive configured for your application. This directive creates a top level route for the
|
|
MVC application and then a set of routes for each of the RESTful verbs: create, destroy, edit, list, show
|
|
and update.</p>
|
|
<pre>EspApp Prefix Dir RouteSet Database</pre>
|
|
<p>The
|
|
<a href="../../appweb/users/dir/esp.html#espApp">EspApp</a> directive creates routes that intercept request URIs that begin with the given prefix
|
|
and directs them toward the MVC application in the specified Directory. The RouteSet is typically
|
|
"<em>restful</em>". Lastly, an optional database may be pre-opened for the MVC application. For example:</p>
|
|
<pre>EspApp /store ./applications/store restful mdb://app/db/store.mdb</pre>
|
|
<h3>Stand-Alone Controllers</h3>
|
|
<p>Sometimes, you may wish to have a controller without a full MVC application. You can do this by using a
|
|
set of Appweb directives.</p>
|
|
<pre>
|
|
<Route ^/app/{controller}(/)*$ >
|
|
Name /app/*/list
|
|
AddHandler espHandler
|
|
EspDir controllers ./controllers
|
|
Source test.c
|
|
Target run $1-list
|
|
</Route>
|
|
</pre>
|
|
<p>This set of directives will create a route that will invoke the controller <em>controllers/test.c</em>.
|
|
If the <em>/app/test/</em> URI is invoked, the <em>list</em> action function will be invoked.
|
|
The EspDir directive nominates the directory to contain the controllers. By default this is configured to be
|
|
{Documents}/controllers. The Target directive defines how the action function name to invoke.
|
|
Note: This usage is less typical than using the MVC pattern.</p>
|
|
<a id="actions"></a>
|
|
<h2 class="section">Actions</h2>
|
|
<p>Actions are where the controller does its work. In ESP, actions are simple "C" functions and thus
|
|
they need to be registered before use. This is done in the controller initialization function.
|
|
The initialization function should be named: "<em>esp_controller_NAME</em>", where NAME is the unique
|
|
name of the controller. The first time the controller is invoked, the controller
|
|
library will be loaded and the initialization function will be run. Typically, the initialization function
|
|
will then call
|
|
<a href="../../../api/esp.html#group___esp_route_1ga321abe89cc91246b2a44f40493988670">espDefineAction</a>
|
|
to bind action functions to route actions.</p>
|
|
<h3>Missing Actions</h3>
|
|
<p>When responding to a request, if the required action is not found, ESP will look for an action called
|
|
"<em>CONTROLLER-missing</em>". If that is not defined in the controller, it will look for a global
|
|
"missing" function. Otherwise it will respond with a HTTP 404 error indicating that the required
|
|
action could not be found.</p>
|
|
|
|
<a id="processing"></a>
|
|
<h3>Processing the Request</h3>
|
|
<p>The controller action can perform any processing it desires. There are no real restrictions except you don't
|
|
want to block for too long without giving the client some feedback. Because Appweb is multithreaded, you can
|
|
block. In that case, the server will continue to run and serve other requests. However, note that threads
|
|
are a limited resource. It may be better to use non-blocking techniques such as async processing.</p>
|
|
<h3>Async Processing</h3>
|
|
<p>An action may service a long-running request without blocking, by responding in pieces.
|
|
An action function may return without completing the request. Normally, ESP will automatically finalize
|
|
the request when the action returns. To prevent this, call
|
|
<a href="../../../api/esp.html#group___esp_abbrev_1ga9db9b8b7e2c750f6f942da0478866de2">
|
|
dontAutoFinalize</a> to tell ESP not to finalize the request and to keep the connection and
|
|
response open. At anytime and from any other code, you may then call
|
|
<a href="../../../api/esp.html#group___esp_abbrev_1ga32d626626eee0bc4ade146973f6abb1c">finalize</a>
|
|
to complete the request. To force output to the client, without finalizing, use
|
|
<a href="../../../api/esp.html#group___esp_abbrev_1ga32d626626eee0bc4ade146973f6abb1c">flush</a>.</p>
|
|
<p>For example:</p>
|
|
<pre>
|
|
static void second(HttpConn *conn) {
|
|
setConn(conn);
|
|
render("World\n");
|
|
finalize();
|
|
}
|
|
static void first() {
|
|
dontAutoFinalize();
|
|
render("Hello ");
|
|
flush();
|
|
<b>setTimeout(second, 5000, getConn());</b>
|
|
}
|
|
</pre>
|
|
<p>This example will print "Hello ", then wait five seconds and then print "World". Note that the request
|
|
is held open, but Appweb is not blocked in any thread. The call to <em>setTimeout</em> will arrange to have
|
|
the Appweb event loop invoke <em>second</em> after five seconds have elapsed. This pattern is a
|
|
highly efficient in its use of system resources and scales very well.</p>
|
|
<h2>Loading and Caching Controllers</h2>
|
|
<p>Before a controller can run, it must first be compiled and linked into a loadable library.
|
|
On Windows, this will be a DLL, on Unix, it will be a shared library with a ".so" extension. On VxWorks it
|
|
will be a loadable task module.</p>
|
|
<p>The compilation of controllers into libraries happens automatically if a compiler is installed on the
|
|
system and if the <em>EspUpdate</em> directive is enabled. If so, when a request is received, ESP will
|
|
compile and link the controller in to a library and save the result into the ESP <em>cache</em> directory
|
|
for future use. After servicing the first request for the controller, the controller code is retained in
|
|
memory and the controller will not be reloaded unless the source code is modified. If Appweb is rebooted,
|
|
the cached library will be reloaded without recompiling. This provides two levels of caching: in-memory and
|
|
on-disk as a shared library.</p>
|
|
<h3>Development and Production Modes</h3>
|
|
<p>When a request for a controller is received, ESP will test if the source code has been updated to
|
|
determine if the controller must be recompiled. If the source has been changed, Appweb will wait for all
|
|
requests that are using the already loaded controller, to gracefully complete. When no requests are using
|
|
the old controller version, Appweb will unload the controller, and ESP will recompile the updated controller
|
|
source and create a new shared library that will then be loaded and the request servicing resumed.</p>
|
|
<p>If Appweb was configured and built in debug mode, the default value for <em>EspUpdate</em> will be
|
|
<em>on</em>. If Appweb was built in release mode, the default value is <em>off</em>. In release mode is it
|
|
common practice to lock down the compiled controllers and not auto-recompile once deployed.</p>
|
|
<a id="context"></a>
|
|
<h2 class="section">Controller Context</h2>
|
|
<p>ESP establishes a request context for the controller before invoking the controller action. The top level
|
|
of the context is represented by the <a href="../../../api/http.html#group___http_conn">HttpConn</a>
|
|
connection object. From this, all other request information can be reached, including the:</p>
|
|
<ul>
|
|
<li>receive object — describes the client HTTP request.</li>
|
|
<li>transmit object — describes the client HTTP response.</li>
|
|
<li>host object — describes the web server hosting the application.</li>
|
|
<li>params — request query, form, and routing parameters.</li>
|
|
<li>session state object — session state information.</li>
|
|
<li>flash messages — informational messages to pass to the next action (and view).</li>
|
|
</ul>
|
|
<h3>ESP Short-Form API</h3>
|
|
<p>When ESP invokes a controller action or a ESP web page, ESP defines the current HttpConn connection
|
|
object in Thread-Local storage. ESP also defines a terse, short-form,
|
|
<a href="../../../api/esp.html#group___esp_abbrev">API</a> that uses the current connection object to
|
|
provide context for the API. When using this API, explicit access to the connection object should not
|
|
typically be required. The ESP short-form API should cover 95% of requirements for action processing.</p>
|
|
<h3>Explicit Connection Access</h3>
|
|
<p>If explicit access to the connection object is required, action functions may
|
|
define a connection argument as
|
|
which is passed into all actions.</p>
|
|
<pre>static void ACTION(HttpConn *conn) {
|
|
/* Use the conn reference here */
|
|
}</pre>
|
|
<p>Alternatively, the connection object can can be retrieved using the <a
|
|
href="../../../api/esp.html#group___esp_abbrev_1gabe448b3542b4d1391e80e74192a09cb3">
|
|
getConn</a> API.</p>
|
|
<h3>Navigating the Connection Object</h3>
|
|
<p>The <a href="../../../api/http.html#group___http_conn">HttpConn</a> object represents the current
|
|
TCP/IP connection. By using HTTP KeepAlive, the connection may be utilized for multiple requests. The fields
|
|
of the HttpConn object are public and can be accessed and
|
|
navigated.</p>
|
|
<table title="properties">
|
|
<thead>
|
|
<tr><th>HttpConn Property</th><th>Purpose</th></tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr><td>rx</td><td>Reference to the HttpRx receive object</td></tr>
|
|
<tr><td>tx</td><td>Reference to the HttpTx transmit object</td></tr>
|
|
<tr><td>host</td><td>Reference to the HttpHost object</td></tr>
|
|
<tr><td>http</td><td>Reference to the Http object</td></tr>
|
|
<tr><td>endpoint</td><td>Reference to the HttpEndpoint transmit object</td></tr>
|
|
<tr><td>limits</td><td>Reference to the HttpLimits object</td></tr>
|
|
<tr><td>ip</td><td>Remote client IP address</td></tr>
|
|
<tr><td>port</td><td>Remote client port</td></tr>
|
|
</tbody>
|
|
</table>
|
|
<h3>Navigating the Receive Object</h3>
|
|
<p>The <a href="../../../api/http.html#group___http_rx">HttpRx</a> object represents the receive side of the
|
|
HTTP protocol. On the server, it holds state regarding the client HTTP request. The fields of the HttpRx
|
|
object are public and can be accessed and navigated.</p>
|
|
<table title="fields">
|
|
<thead>
|
|
<tr><th>HttpRx Property</th><th>Purpose</th></tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr><td>method</td><td>HTTP request method</td></tr>
|
|
<tr><td>uri</td><td>Current URI (may be rewritten)</td></tr>
|
|
<tr><td>pathInfo</td><td>Path portion of the URI after the scriptName</td></tr>
|
|
<tr><td>scriptName</td><td>ScriptName portion of the URI</td></tr>
|
|
<tr><td>length</td><td>Content length</td></tr>
|
|
<tr><td>route</td><td>Reference to current HttpRoute object</td></tr>
|
|
<tr><td>params</td><td>Request params (query, form and route parameters)</td></tr>
|
|
<tr><td>files</td><td>Uploaded files</td></tr>
|
|
</tbody>
|
|
</table>
|
|
<h3>Navigating the Tx Object</h3>
|
|
<p>The <a href="../../../api/http.html#group___http_tx">HttpTx</a> object represents the transmit side of the
|
|
HTTP protocol. On the server, it holds state regarding the response to the client. The fields of the HttpTx
|
|
object are public and can be accessed and navigated.</p>
|
|
<table title="state">
|
|
<thead>
|
|
<tr><th>HttpTx Property</th><th>Purpose</th></tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr><td>filename</td><td>Name of the real file being served</td></tr>
|
|
<tr><td>ext</td><td>Filename extension</td></tr>
|
|
<tr><td>handler</td><td>Request handler object</td></tr>
|
|
<tr><td>length</td><td>Response content length</td></tr>
|
|
<tr><td>status</td><td>Response HTTP status</td></tr>
|
|
<tr><td>headers</td><td>Response HTTP headers</td></tr>
|
|
</tbody>
|
|
</table>
|
|
|
|
<a id="models"></a>
|
|
<h3>Sample of ESP API</h3>
|
|
<p>Here are a few of the ESP APIs that may be used inside controller actions:</p>
|
|
<table title="viewClass">
|
|
<thead>
|
|
<tr>
|
|
<th class="nowrap">Method / Property</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td><a href="../../../api/esp.html#group___esp_abbrev_1gadba1deb080e78b4517119a0294489b44">
|
|
addHeader</a></td> <td>Add a response HTTP header.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><a href="../../../api/esp.html#group___esp_abbrev_1gab7b4049b554576b57f8cc49efc9e3a95">
|
|
createSession</a>
|
|
</td>
|
|
<td>Enable session control.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><a href="../../../api/esp.html#group___esp_abbrev_1ga35677b9aa8d61543db5ea80377e823a6">
|
|
destroySession</a>
|
|
</td>
|
|
<td>Destroy a session.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><a href="../../../api/esp.html#group___esp_abbrev_1ga9db9b8b7e2c750f6f942da0478866de2">
|
|
dontAutoFinalize</a>
|
|
</td>
|
|
<td>Don't automatically finalize output when the action returns. Useful for async actions.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><a href="../../../api/esp.html#group___esp_abbrev_1ga03544bf56dde3a257391d07e1d6f6a3a">
|
|
error</a>
|
|
</td>
|
|
<td>Send an error flash message to the next web page.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><a href="../../../api/esp.html#group___esp_abbrev_1ga8e8c0dccb4ded8a2fecec11d389cf8c8">
|
|
inform</a>
|
|
</td>
|
|
<td>Send an informational flash message to the next web page.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><a href="../../../api/esp.html#group___esp_abbrev_1gad638c34898123293ebc120c1f9396a9c">
|
|
param</a>
|
|
</td>
|
|
<td>Get a request parameter value.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><a href="../../../api/esp.html#group___esp_abbrev_1ga79cf206805a9595395af14e7c35f289d">
|
|
redirect</a></td>
|
|
<td>Redirect the client to a new URI.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><a href="../../../api/esp.html#group___esp_abbrev_1gaf89154adc3cbf6d6a6a32c6b4457c593">
|
|
render</a></td>
|
|
<td>Render the text data back to the client.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><a href="../../../api/esp.html#group___esp_abbrev_1gaa1e37f244a0e0796df494dfb756472a8">
|
|
renderFile</a></td>
|
|
<td>Render a file's contents back to the client.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><a href="../../../api/esp.html#group___esp_abbrev_1gafe8d897ff436eabc6fc275f76222a5c3">
|
|
setContentType</a></td>
|
|
<td>Set the response content type.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><a href="../../../api/esp.html#esp_8h_1a85b884db9ea1993efaa01dbe686f601c">
|
|
setCookie</a></td>
|
|
<td>Define a cookie to include in the response.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><a href="../../../api/esp.html#group___esp_abbrev_1gadb4f7bc3020ab9c481f1ebcaf1ed3f2a">
|
|
setSessionVar</a></td>
|
|
<td>Set a variable in session state storage.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><a href="../../../api/esp.html#group___esp_abbrev_1ga56d17d8860dc351f63feaa55891cdf21">
|
|
uri</a></td>
|
|
<td>Make a URI from parameters.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<a id="parameters"></a>
|
|
<h2 class="section">Request Parameters</h2>
|
|
<p>ESP will collect request query, form data and route parameters into one
|
|
<em>params</em> object which is accessible to actions via the
|
|
<a href="../../../api/esp.html#group___esp_abbrev_1gad638c34898123293ebc120c1f9396a9c">param</a> API. Each query key/value pair and all
|
|
request form elements posted by the client will become a properties of the <em>params</em> object.
|
|
When routing the request, Appweb will tokenize the URI and create parameters for each positional token in
|
|
the URI. The Controller name and Action are defined as the parameters: <em>controller</em> and
|
|
<em>token</em>.</p>
|
|
<a id="views"></a>
|
|
<h3>Rendering Views</h3>
|
|
<p>After processing the request, the controller is responsible for rendering a response back to the client.
|
|
The controller can choose how to respond. It may explicitly create the response body by calling
|
|
<a href="../../../api/esp.html#group___esp_abbrev_1gaf89154adc3cbf6d6a6a32c6b4457c593">render</a> to generate HTML.
|
|
Alternatively, the action may call
|
|
<a href="../../../api/esp.html#group___esp_abbrev_1gaf0db430f850378bd83c514a0dda77fb9">renderView</a> to
|
|
response with a view web page.
|
|
|
|
If the action method does not explicitly generate any response, ESP will invoke a view with the same name as
|
|
the action method.</p>
|
|
<a id="generating"></a>
|
|
<h2 class="section">Generating Controllers and Actions</h2>
|
|
<p>If you are creating an MVC application, you may use the ESP application generator, called <em>esp</em> to
|
|
make it quick and easy to create controllers, actions and controller scaffolds. To generate a new
|
|
controller, run:</p>
|
|
<pre>
|
|
esp generate CONTROLLER ACTIONS...
|
|
</pre>
|
|
<p><em>CONTROLLER</em> is the controller name. <em>ACTIONS...</em> are the names of the actions you want to
|
|
generate. This command will create the controller source file under the <em>controllers</em> directory. The
|
|
controller source will contain empty functions for each of the requested actions.
|
|
You can edit the controller source to meet your needs.</p>
|
|
</div>
|
|
</div>
|
|
<!-- BeginDsi "dsi/bottom.html" -->
|
|
<div class="bottom">
|
|
<p class="footnote">
|
|
<a href="../../../product/copyright.html" >© Embedthis Software LLC, 2003-2013.
|
|
All rights reserved. Embedthis, Appweb, ESP, Ejscript and Embedthis GoAhead are trademarks of Embedthis Software LLC.</a>
|
|
</p>
|
|
</div>
|
|
<script src="http://www.google.com/jsapi" type="text/javascript"></script>
|
|
<script type="text/javascript">
|
|
google.load('search', '1', {language : 'en'});
|
|
google.setOnLoadCallback(function() {
|
|
var customSearchControl = new google.search.CustomSearchControl(
|
|
'000262706376373952077:1hs0lhenihk');
|
|
customSearchControl.setResultSetSize(google.search.Search.FILTERED_CSE_RESULTSET);
|
|
var options = new google.search.DrawOptions();
|
|
options.enableSearchboxOnly("http://appwebserver.org/search.html");
|
|
customSearchControl.draw('cse-search-form', options);
|
|
}, true);
|
|
</script>
|
|
<script type="text/javascript">
|
|
var _gaq = _gaq || [];
|
|
_gaq.push(['_setAccount', 'UA-179169-2']);
|
|
_gaq.push(['_trackPageview']);
|
|
(function() {
|
|
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
|
|
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
|
|
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
|
|
})();
|
|
</script>
|
|
</body>
|
|
</html>
|