WebDSL is a domain-specific language for building web applications. WebDSL avoids the boilerplate that is common in other web technologies by providing tuned domain-specific notations for the concerns of web development. Furthermore, the consistency of these concerns is verified at compile-time. WebDSL is available from webdsl.org. There you can also find instructions for installing the compiler and the other components that you need to run WebDSL applications. In this series of screencasts I will illustrate the use of WebDSL, by building a web application from scratch. The application we are going to build is called ‘The Big Scheme of Things’, a to-do list application. In this first episode I keep it really simple and create a single page app that allows us to add and remove tasks. First I show how to get an even simpler “Hello web!” app running.
(This is as much an experiment in screencasting, as it is a WebDSL tutorial. Feedback is welcome.)
We start with creating the main module of our application with a placeholder definition of the application’s root page:
application bigscheme define page root() { "Hello web!" }
Then we can try to build the application with the webdsl command
$ webdsl build
The WebDSL compiler needs a few build and deployment parameters to compile an application. The first time you try to compile an application it asks for the values for these parameters. The values are stored in the application.ini configuration file, where you can change them later on.
A WebDSL application is built and deployed using the commands
$ webdsl build $ webdsl deploy
or combined as a single command
$ webdsl build deploy
The application should now be visible http://localhost:8080/bigscheme/
At the heart of a to-do application, we have Task objects that need to be stored between user sessions. In WebDSL, persistent objects are described by a data model consisting of entity declarations. An entity declaration consists of the name of the entity (the type), and the properties of objects. For now our Tasks contain a single property, name of type String.
entity Task { name :: String }
We’ll refine and enrich this entity in future episodes.
Next we want to present the list of Tasks in the database. We replace the body of the root() page definition with a Tasks section with a list of all tasks:
section{ header{"Tasks"} list{ for(t : Task) { listitem{ output(t.name) } } } }
Since our database is empty this is not very useful yet. We need to be able to add tasks as well.
var task := Task{} form{ input(task.name) action("+", action{ task.save(); }) }
When Tasks are completed we can delete them. In the future we will probably want to refine that to mark tasks as completed. But for now we’ll just delete. We add to the tasks in the list a delete action
listitem{ output(t.name) form{ action("-",action{t.delete();}) } }
That completes the first episode of this screencast series. We have written a small app for creating, reading, and deleting Tasks. We’ll have to consider updating tasks in a future episode. This example has taken us through all the steps needed to get a WebDSL application up and running. In future episodes we’ll refine and extend this to-do list application and encounter many more features of WebDSL.
// file: bigscheme.app application bigscheme entity Task { name :: String } define page root() { section{ header{"Tasks"} list{ for(t : Task) { listitem{ output(t.name) " " form{ action("-", action{ t.delete(); })} } } } } var task := Task{} form{ input(task.name) " " action("+", action{ task.save(); }) } }