ESP Applications Tour

This tour provides an overview of creating ESP applications and the ESP MVC Framework.

To create more complex ESP applications than a simple hello-world, we will typically want a bit more structure and content. The ESP MVC framework provides this structure and with sensible defaults, it greatly minimizes your workload.

Essential Tools

So you can work along as the tour progresses, install the following products and tools. ESP applications and this tour make good use of the Pak and Expansive tools from Embedthis.

Before starting, first make sure you have read the Quick Start, and the ESP Tour and that you have ESP, Pak and Expansive installed on your system so you can type along as you go.

Download ESP Download Pak Download Expansive

Creating a New Application

ESP provides skeletons to get you started quickly. These skeletons packages provide the core structure of your application and include pages, templates, stylesheets and scaffolds that are used to generate models, views and controllers as your application grows.

To create a new ESP application, we will use the Pak package manager to install the esp-html-skeleton application skeleton. The esp-html-skeleton is a starter package for ESP HTML MVC applications with server-side views. Other skeletons include the esp-vue-skeleton for ESP VueJS applications with client-side views.

Install the Skeleton

First make a directory named blog and then install the esp-html-skeleton package.

$ mkdir blog
$ cd blog
$ pak init
$ pak install embedthis/esp-html-skeleton
   [Install] exp-js 0.3.2
   [Install] exp-less 0.3.0
   [Install] exp-css 0.3.1
   [Install] exp-esp 0.3.1
   [Install] exp-html 0.2.0
   [Install] exp-canon 0.1.0
   [Install] esp-mvc 5.5.2
   [Install] esp-html-skeleton 5.5.1

This simple command sequence accomplished quite a bit, including:

Render the Skeleton

Next, run the expansive command to render the skeleton web pages.

$ expansive render
      [Info] Using profile: debug
    [Render] css/all.css
    [Render] index.esp
      [Post] esp
       [Run] esp compile dist/index.esp

This will render the web site including:

Access your Application

To access your application enter http://localhost:4000 in your browser. You should see your first application home page.



The ESP web framework follows the convention over configuration philosophy popularized by Ruby on Rails. This means that ESP adopts certain conventions about where files and directories should be placed and about how names are used. If you work with these conventions, then you need to do little or no configuration. Things will just work.

Here are the most important files and directories:

Name Description
esp.json Primary ESP configuration file
pak.json This file specifies the application name, version and dependent packages.
cache Cached compiled pages and controllers.
contents Input content for the Expansive tool to render into dist
contents/index.esp Home page for your application.
dist Distribution directory for browser visible web content including scripts, pages and style-sheets. This is created from contents, layouts, lib and partials.
controllers Application controller code
db Database file and database initialization scripts
layouts Master page layouts used by Expansive
partials Partial pages used by Expansive.
paks Locally installed extension packages


Scaffolding is a quick way to generate pieces of your application. Scaffolds are stub MVC resource managers that provide basic Create-Read-Update-Delete (CRUD) for a resource or group of resources. ESP scaffolds include:

Don't confuse ESP scaffolds with ESP skeletons. Skeletons are installable packages that are ready-made application starters. Scaffolds are generated MVC resource managers.

Once the esp-html-skeleton framework pak is installed, the esp command can generate scaffolds. The command below will create a post scaffold that includes a database post table with a blog post title and post comment body. The title is a string data type and the body is a multi-line text field.

$ esp generate scaffold post title:string body:text
    [Create] Directory: controllers
    [Create] controllers/post.c
    [Create] Directory: contents/post
    [Create] contents/post/list.esp
    [Create] contents/post/edit.esp
    [Create] Directory: migrations
    [Create] migrations/201503311340450_create_scaffold_post.c
   [Compile] migrations/201503311340450_create_scaffold_post.c
   [Migrate] Apply 201503311340450_create_scaffold_post.c
   [Migrate] All migrations applied
  [Generate] Complete
       [Run] expansive render
      [Info] Using profile: debug
    [Render] css/all.css
    [Render] index.esp
    [Render] post/edit.esp
    [Render] post/list.esp
      [Post] esp
       [Run] esp compile dist/index.esp
       [Run] esp compile dist/post/edit.esp
       [Run] esp compile dist/post/list.esp
      [Info] Rendered 4 files to "dist". Elapsed time 0.94 secs.

This command created:

The command also ran the migration to create the database and table.

Now if you set your browser to the home page, you will now see an empty listing of blog posts.


Create New Posts

The New Post button directs your browser to the /post/ URL. This form is being rendered on the client from the contents/post/edit.esp template. Behind the scenes, the browser asks for the /post/init URL to determine what are the required input fields for a post.


Fill in the input fields and click OK to add the new blog post.


The home page is now updated with the first post. You can click on the post title or body to edit its contents. This will run the same post-edit.html template that was used to create the post.

On the Server

When OK button is clicked to create a post, the browser invokes the /post/ URL with the HTTP POST method to create the blog post. Esp parses this URL and and selects the appropriate request route and handler for the request. It then identifies post as the name of the server-side controller invokes the createPost action routine to service the request. The controller is automatically compiled and loaded if required.

A controller file typically defines many such C functions called actions, that are bound to specific URLs via ESP routes. Actions are defined using the espAction API in the initialization function of the controller.

A minimal post controller file looks like this:

#include "esp.h"
static void createPost() {
    if (saveRec(createRec("post", params()))) {
        feedback("info", "New post Created");
    } else {
        feedback("error", "Cannot Create Post");
ESP_EXPORT int esp_controller_blog_post(EspRoute *eroute)
    espAction(route, "post/create", NULL, createPost);
    return 0;


The job of the action is to respond to the request and generate the response via views for the client. Here is the listPost action in the generated post controller.

static void listPost() {

The listPost action simply renders the post/list.esp view page.

Code Errors

What happens if you make a mistake entering the embedded "C" code in your controller or in an ESP web page. Say you forgot the semicolon in the last example. You will see an error like this in your browser:


If you look at the esp console output, you also see full details about the request that failed.

14:10:20 1-0-1-1 request.error msg='Cannot run command: clang -c -DME_DEBUG -g -Wall -DPIC -fPIC -arch x86_64 -I. -Isrc -I/usr/local/lib/esp/5.4.0/inc controllers/post.c -o cache/controller_c1a25719dee243438859faa7d60c148d.o

controllers/post.c=46:28: error: expected ';' after expression
1 error generated.


Complete validation of all user entered data is essential for a robust and secure application. Some validation may be performed at the client, but full validation must always be fully implemented on the server incase the client or network connection is compromised. ESP provides flexible validation methods to help ensure the data you save at the server is correct.

You can add calls to validate record data before it is saved to the database. To do this, edit the controllers/post.c file and add calls to ediAddValidation.

ESP_EXPORT int esp_controller_post(EspRoute *eroute)
    Edi *edi;
    /* Existing code */
    edi = getDatabase();
    ediAddValidation(edi, "present", "post", "title", 0);
    ediAddValidation(edi, "present", "post", "body", 0);
    ediAddValidation(edi, "unique", "post", "title", 0);
    return 0;

This will cause the database to automatically ensure that the title and body fields are not blank and that the title is unique in the post database table.

If you click OK in the Post edit web page without entering any data you will see the following:


This automatically identified the input fields in error and generated a summary of the errors above the form. Of course, this default error highlighting behavior can be overridden if desired by modifying the application style sheets.

Other validation types include: checkNumber, checkBoolean, checkDate and checkFormat. You can also define new validation types by calling ediDefineValidation.

Hosting in Appweb

If you want to host your application in Appweb, generate the required appweb.conf via:

esp generate appweb

This will generate a stand-alone appweb.conf that includes the required EspApp directive to define your application.

EspApp prefix="/demo" config="/path/to/esp.json

Learn More ...

That concludes the a quick tour through some of the capabilities of the ESP web framework. To learn more, please read:

© Embedthis Software. All rights reserved.