⬆️ ⬇️

Erlang web

Erlang Web is an open source platform for HTTP-based applications. Currently, INETS and Yaws web servers are supported. Erlang Web was developed by Erlang Training & Consulting Ltd. over the past three years and has been used in many commercial and open source projects.



Application



Projects using Erlang Web:





Key features



Erlang Web introduces a different approach to generating dynamic pages. It allows you to combine XHTML code with a special XML tag called wpart. Using the concept of wparts, you can implement portions of the functionality that can be reused in different pages, providing a basis for developing dynamic web services. A number of frequently used templates have been implemented as a standard wparts library. For example, wparts include:



In addition, the wtypes mechanism allows you to format the date, time and numbers, as well as data validation. Formatting and validation can also be implemented for custom composite types. Such composite types can consist of standard or other composite types and can be defined using Erlang records. This is convenient when data is stored in the Mnesia database, however data can be stored in other databases like MySQL or PostgreSQL.



To make the URL easy to remember, the Erlang network provides a dispatching mechanism based on regular expressions that maps the URL to controller calls. Each controller call can be made by calling the so-called dataflow functions. With template inheritance and multilingual site support, Erlang Web is a complete tool for creating web applications.

')

Wparts



Implementing wparts as XML allows Erlang Web to parse the pages with an XML parser to ensure that valid XHTML is sent to the client. The processed file is converted to an Erlang binary file and is cached on disk or stored in memory.



Wtypes



The Wtype module is responsible for validating and formatting data. Erlang Web provides more than 10 simple types like dates, integers, strings, etc. and provides the ability to easily add new ones. A developer can create his own composite types on top of them. Data validation and form generation can be easily automated.



Code examples



The diagram below shows an example of wpart people , which is used to add dynamic content to a page.



mboga.org



When the URL "/app/mod/func/people.html" is called, the mod: func () controller function is called. The function reads data from the model and prepares it for wpart people . During page rendering, the wpart tag is replaced with dynamic data.



<!-- people.html - renders data from the model --> <html> <head> <title>Erlang Web Sample Page 4</title> </head> <body> <center> <wpart:people rows="2" key="list"> <tr> <td><wpart:lookup key="item:person" /></td> <td><wpart:lookup key="item:age" format="age"/></td> <td><wpart:lookup key="item:sex" format="sex"/></td> </tr> </wpart:people> <img src="/images/powered.gif" /> </center> </body> </html> 




 % install.erl - initialises mnesia database and puts sample data into it -module(install). -export([install/0]). install() -> mnesia:create_schema([node()]), application:start(mnesia), mnesia:create_table(person, [{disc_copies, [node()]}, {attributes, record_info(fields,person)}]), mnesia:dirty_write(#person{name = "Lucy", age = "20", sex="female"}), mnesia:dirty_write(#person{name = "John", age = "22", sex="male"}), mnesia:dirty_write(#person{name = "Anna", age = "22", sex="female"}). 




 % mod.erl - controller function writes data into the request dictionary -module(mod). -export([validate/1,func/0,]). -export([install/0]). -record(person, {name, age, sex}). validate(func) -> {ok, []}; func() -> Keys = mnesia:dirty_all_keys(person), Records = [mnesia:dirty_read(person, Key) || Key <- Keys], Persons = lists:map(fun([#person{name=Name, age=Age, sex=Sex}]) -> [{"person",Name}, {"age",Age}, {"sex",Sex}] end, Records), eptic:fset("list", Persons), template. 




 % wpart_people.erl - wpart module handles formatting and retrieves data from the request dictionary -module(wpart_people). -export([handle_call/1]). -include_lib("xmerl/include/xmerl.hrl"). handle_call(E) -> Start = case catch list_to_integer(eptic:fget("get", "start")) of S when is_integer(S) -> S; _ -> 1 end, Rows = case catch list_to_integer(wpart:has_attribute("attribute::rows", E)) of R when is_integer(R) -> R; _ -> 10 end, Key = wpart:has_attribute("attribute::key", E), List = eptic:fget(Key), Prev = if Start-Rows > 0 -> link_prev(Start-Rows); Start == 1 -> "Prev | "; true -> link_prev(1) end, Next = if Start+Rows > length(List) -> "Next"; true -> link_next(Start + Rows) end, F = fun(Item, {N,Start,End,Acc}) when N>=Start, N<End -> eptic:fset("item", Item), {N+1,Start,End,[wpart:eval(E#xmlElement.content)|Acc]}; (_, {N,Start,End,Acc}) -> {N+1,Start,End,Acc} end, {_,_,_,TableRows} = lists:foldl(F, {1,Start,Start+Rows,[]}, List), [#xmlText{value = "<table>", type=cdata}, lists:reverse(TableRows), #xmlText{value = "</table>", type=cdata}, #xmlText{value = Prev, type=cdata}, #xmlText{value = Next, type=cdata}]. link_prev(Start) -> ["<a href=\"?start=",integer_to_list(Start),"\">Prev</a> | "]. link_next(Start) -> ["<a href=\"?start=",integer_to_list(Start),"\">Next</a>"]. 




The second example illustrates the dispatching of a request, the logging of a request by a dataflow function, validation, automatic creation of forms and error handling.

Source: https://habr.com/ru/post/116240/



All Articles