Erlang Web

Example Code Two - listing the person with a given id, adding a new person



dispatch.conf - dispatcher configuration file that defines regular expressions

{static, "^/index.html$", "index.html"}.
{dynamic, "^/person", {people, list}}.
{static, "^/add_person$", "add_person.html"}.
{dynamic, "^/create_person$", {people, add}}.


index.html - contains a link to the page that lists the person description stored in the database

<a href="/person">List the first person</a>

and to the page where we can add a new person to the database:

<a href="/add_person">Add a person</a>


person.hrl - contains person and person_types records

-record(person, {id, name, sex, age}).

-record(person_types,
	{id = {integer, [{description, "Person ID"},
			{primary_key},
			{min, 1}]},
	name = {string, [{description, "Person name"},
			{min_length, 3},
			{max_length, 20}],
	sex = {bool, [{description, "Is person male?"}]}}).


wtype_person.erl - defines the wtype person using Erlang records

-module(wtype_person).
-import("person.hrl").

-export([get_record_info/1, validate/1]).

get_record_info(person_types) -> #person_types{};
get_record_info(person) -> #person{}.	

validate(From) ->	
	wpart_valid:validate(get_record_info(person),
			get_record_info(person_types),
			From ++ ["person"]).


people.erl - implements controller function. Call to the function will be proceded with calls to the log function and get_arg or validate functions

-module(people.erl).
-export([dataflow/1, error/2]).
-export([log/2, get_arg/2, validate/2]).
-export([list/1, add/1]).

-include("person.hrl").

dataflow(list) -> [log, get_arg];
dataflow(add)  -> [log, validate].

error(_, {cannot_write_to_log, _LogName, _Fun} = Reason) ->
	error_logger:error_msg("~p module, error: ~p~n", [?MODULE, Reason]),
	{redirect, "/index.html"};
error(add, not_valid) ->
	Err = wpart:fget("__error"),
	Msg = "ERROR: Incomplete input or wrong type in form! Reason: " ++ Err,
	wpart:fset("error_message", Msg),
	{template, "error_add.html"}.

log(Fun, _) ->
	case my_logger:log("people.log", {?MODULE, Fun}) of
		true -> {ok, []};
		false -> {error, {cannot_write_to_log, "people.log", Fun}}
	end.

get_arg(list, _) ->
	case catch list_to_integer( wpart:fget("get", "id") of
		P when is_integer(P) -> {ok, [P]};
		_ -> {ok, [1]}
	end.

validate(add, _) ->
	validate_tool:validate_cu(?MODULE, add).

list(Id) ->
	[Person] = mnesia:dirty_read(person, Id),
	wpart:fset("person:name", Person#person.name),
	wpart:fset("person:sex", Person#person.sex),
	wpart:fset("person:age", Person#person.age),
	
	Prev = if
		Id > 1 ->
			"<a href="?id=\"" ++ integer_to_list(Id-1) ++ "\">Prev</a> | ";
		true ->
			"Prev | "
	end,
	Next = "<a href="?id=\"" ++ integer_to_list(Id+1) ++ "\">Next</a>",

	wpart:fset("person:next", Next),
	wpart:fset("person:prev", Prev),
	
	{template, "person.html"}.

add(Person) ->
	mnesia:dirty_write(Person),
	{redirect, "/person?id=" ++ integer_to_list(Person#person.id)}.


person.html - renders a person

<html>
  <head>
    <title>Erlang Web Example Page</title> 
  </head>
  <body> 
    <center>
     	Person (id = <wpart:lookup key="person:id"/>) details:
	  Name: <wpart:lookup key="person:name" /><br/>
	  Age: <wpart:lookup key="person:age" format="age"/><br/>
	  Sex: <wpart:lookup key="person:sex" format="sex"/><br/>

	<wpart:lookup key="person:prev"/><wpart:lookup key="person:next"/>
    </center>
  </body>
</html>


add_person.html - generates form used to create a new person

<html>
  <head>
    <title>Erlang Web Example Page</title> 
  </head>
  <body> 
    <center>
     	<wpart:form type="person" action="/create_person"/>
    </center>
  </body>
</html>


error_add.html - displays error

<html>
  <head>
    <title>Erlang Web Example Page</title> 
  </head>
  <body> 
    <center>
     	<wpart:lookup key="error_message"/>
    </center>
  </body>
</html>


install.erl - initialises mnesia database and puts sample data into it

-module(install).
-export([install/0]).
-import("person.hrl").

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"}),



erlang