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.
- Pak manager to install and manage extension packages.
- Expansive site manager for layout pages and web site tooling.
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:
- Create a core structure with directories for various parts of the application. Initially, some of these directories are empty, but they will be used as your application grows.
-
Installed the esp-html-skeleton, esp-mvc, exp-js, exp-less, exp-css, and exp-esp packages. You can see these via the pak list command.
- Created esp.json and pak.json files that configures and control how your application will run.
- Generated
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:
- Create the style sheets from the Less contents/css/*.less sheets
- Create the home page: index.esp from the master layouts/default.html.exp and the reusable partial pages under the "partials" directory.
- Compile the ESP pages into loadable libraries under the "cache" directory.
Access your Application
To access your application enter http://localhost:4000 in your browser. You should see your first application home page.
Conventions
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 |
Scaffolds
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:
- Database table schema
- Database migration to create the table
- Controller logic to create and mange table records
- Views to display table and record data
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:
- A server-side post Controller controllers/post.c
- Server-side HTML views for listing posts contents/post/list.esp and editing posts contents/post/edit.esp.
- A database migration to create the post database table.
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"); renderView("post/list"); } else { feedback("error", "Cannot Create Post"); renderView("post/edit"); } } ESP_EXPORT int esp_controller_blog_post(EspRoute *eroute) { espAction(route, "post/create", NULL, createPost); return 0; }
Actions
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() { renderView("post/list"); }
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 renderView("post/list") ^ ; 1 error generated.
Validations
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: