[erlang-questions] ANN: ezwebframe - an easy web framework

Joe Armstrong erlang@REDACTED
Wed Dec 19 12:58:10 CET 2012

> On Wed, Dec 19, 2012 at 9:12 AM, Barco You <barcojie@REDACTED> wrote:
> Very nice idea.

> But how the browser understand the commands you send from erlang process?
> example here: {cmd, fill_div}

This is easy, here's an overview:

- Convert the Erlang command to JSON
- send the JSON on the websocket uing Erlang
- receive the JSON in Javascript
- parse the JSON
- build a Javascript command
- execute the Javascript command

Here are the details

0) assume there is a div xyz on the HTML page

   <div id="xyz"> ...</div>

1) We send a message to the browser:

Browser ! [{cmd,'fill_div'},{div,xyz},{txt,<<"<h1>Hello</h1>">>}]

This will fill the div with some HTML

2) The message [cmd,'fill_div'} ,,...] is converted to JSON
   and sent to the websocket:

This is done in lines 227-229 of

websocket_info([{cmd,_}|_]=L, Req, Pid) ->
    B = list_to_binary(encode([{struct,L}])),
    {reply, {text, B}, Req, Pid, hibernate};

Here's an example of encode in the Erlang shell:

> Cmd = [{cmd,fill_div},{id,xzy},{txt,<<"<h1>Hello</h1>">>}].
> list_to_binary(ezwebframe_mochijson2:encode([{struct,Cmd}])).

This is a bit unreadable because the quotes are escaped: The JSON term
without escaping the quotes is:


3) The client code has an event handler that is triggered when the
websocket receives data:

Line 37 of websock.js is

 websocket.onmessage = onMessage;

4) onMessage is defined like this:

function onMessage(evt) {
    var json = JSON.parse(evt.data);

function do_cmds(objs){
    // console.log('do_cmds', objs);
    for(var i = 0; i < objs.length; i++){
      var o = objs[i];
      // as a safety measure we only evaluate js that is loaded
      if(eval("typeof("+o.cmd+")") == "function"){
      eval(o.cmd + "(o)");
      } else {
        // console.log('bad_cmd', o);

The JSON command on the websocket is of the form

 [{cmd:Cmd, ...}]

After parsing with JSON.parse(evt.data) I can iterate over the commands
which are stored in an array objs[...]

The command I just send becomes the Javascript object

o = {cmd:fill_div, id:'xyz', txt:'<h1>Hello</h1>'}

I check that there really is a function called fill_div

with this

 if(eval("typeof("+o.cmd+")") == "function"){

and if there is I do this:

      eval(o.cmd + "(o)");

now o.cmd = 'fill_div' so this is equivalent to eval('fill_div(o)')

and so

fill_div(o) is called where

   o = {cmd:fill_div, id:'xyz', txt:'<h1>Hello</h1>'}

5) Finally fill_div is defined like this

(line 110 of

function fill_div(o){

This method is easily extended.

Suppose Erlang sends a new command called color_page to change the
background color of the page

  Browser ! [{cmd,color_page},{color,<<"green">>}]

All you have to do is supply a javascript function called color_page:

  function color_page(o){

and make sure this gets loaded



Thants to say, you have to define all the commands and relevant parsing
> fucntions in a Javascript library?
> Thanks,
> Barco
> On Thu, Dec 13, 2012 at 6:17 PM, Joe Armstrong <erlang@REDACTED> wrote:
>> ezwebframe
>> ==========
>> https://github.com/joearms/ezwebframe
>> Pronounced "Easy web frame."
>> About
>> =====
>> Ezwebframe attempts to make web programming just a little bit easier.
>> From Erlang point of view the browser *is* an Erlang process.
>> Assume we have a web page populated with divs. For example:
>>     <div id="a">
>>       ...
>>     </div>
>>     <div id="b">
>>       ...
>>     </div>
>> Erlang thinks the browser is a process. To fill div a with HTML an
>> Erlang process evaluates the command:
>>      Browser ! [{cmd, fill_div}, {id, a}, {txt, B}]
>> Where B is a binary containing HTML.
>> In the browser controls can be programmed to send messages to Erlang,
>> for example, when we click on a button in the browser the Erlang
>> process controlling the window will be sent a message which can be
>> received with the statement:
>>     receive
>>        {Browser, {struct, [{clicked, ButtonName}]}} ->
>>            ...
>>     end
>> All this is achieved using a thin JSON layer over websockets and
>> with cowboy managing the websockets.
>> Cheers
>> /Joe
>> _______________________________________________
>> erlang-questions mailing list
>> erlang-questions@REDACTED
>> http://erlang.org/mailman/listinfo/erlang-questions
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20121219/f2e528ba/attachment.htm>

More information about the erlang-questions mailing list