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

Max Bourinov <>
Wed Dec 19 13:07:27 CET 2012


Joe, thank you for great explanation!

Max




On Wed, Dec 19, 2012 at 3:58 PM, Joe Armstrong <> wrote:

> > On Wed, Dec 19, 2012 at 9:12 AM, Barco You <> wrote:
> > Very nice idea.
>
> > But how the browser understand the commands you send from erlang
> process? for
> > 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
> https://github.com/joearms/ezwebframe/blob/master/src/ezwebframe.erl
>
> 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>">>}].
> [{cmd,fill_div},{id,xyz},{txt,<<"<h1>Hello</h1>">>}]
> > list_to_binary(ezwebframe_mochijson2:encode([{struct,Cmd}])).
> <<"[{\"cmd\":\"fill_div\",\"id\":\"xyz\",\"txt\":\"<h1>Hello</h1>\"}]">>
>
> This is a bit unreadable because the quotes are escaped: The JSON term
> without escaping the quotes is:
>
> [{"cmd":"fill_div","id":"xyz","txt":"<h1>Hello</h1>"}]
>
> 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);
>     do_cmds(json);
> }
>
> 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);
>         alert("bad_command:"+o.cmd);
>       };
>    };
> }
>
> 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
> https://github.com/joearms/ezwebframe/blob/master/priv/websock.js)
>
> function fill_div(o){
>     $('#'+o.id).html(o.txt);
> }
>
> 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){
>      document.body.style.backgroundColor=o.color;
>   }
>
>
> and make sure this gets loaded
>
> Cheers
>
> /Joe
>
>
>
>
> 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 <> 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
>>> 
>>> http://erlang.org/mailman/listinfo/erlang-questions
>>>
>>>
>>
>
> _______________________________________________
> erlang-questions mailing list
> 
> http://erlang.org/mailman/listinfo/erlang-questions
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20121219/ddfaeadf/attachment.html>


More information about the erlang-questions mailing list