= Getting your feet wet with ErlyWeb =
We´ll start out with a very basic blog application, which will be expanded step by step. At the end of the tutorials section, you will have a working, full blown blog application and should know everything important to roll out your own applications with ErlyWeb.
*Help*
If you face any kind of problems, don´t hesitate to ask for help on the [http://groups.google.com/group/erlyweb mailing list] or join #erlyweb on irc.freenode.net.
Assuming you already have ErlyWeb and Yaws installed, we start off making our first application.
== Creating an application ==
Start Yaws in interactive mode (*yaws -i*) and type in the Yaws shell:
{{{
erlyweb:create_app("blog", "/path/to/your/apps").
}}}
This will create an ErlyWeb directory structure as well as a few files. (Note: this initial procedure will probably be shorter when ErlyWeb matures.) This is what you should see inside your apps directory:
{{{
/apps/blog/
/apps/blog/ebin/
/apps/blog/src/blog_app_controller.erl
/apps/blog/src/components/
/apps/blog/src/components/html_container_controller.erl
/apps/blog/src/components/html_container_view.et
/apps/blog/www/
/apps/blog/www/index.html
/apps/blog/www/style.css
}}}
Edit your yaws.conf file by adding a server configuration with the following docroot, appmod, and opaque directives, then type *yaws:restart()*.
{{{
docroot = /path/to/your/apps/blog/www
appmods = <"/", erlyweb>
<% Description %>
<% Entries %> <%@ entry({Id, Title, Body}) %><% Body %>
}}} === Entry === entry.erl {{{ -module(entry). -export([relations/0]). relations() -> [{many_to_one, [category]}]. }}} entry_controller.erl {{{ -module(entry_controller). -export([index/1, entry/2, detail/2]). index(A) -> Entries = entry:find_with({order_by, [{id, desc}]}), [{ewc, entry, entry, [A, Entry]} || Entry <- Entries]. entry(A, Entry) -> Category = entry:category(Entry), {data, {integer_to_list(entry:id(Entry)), entry:title(Entry), entry:body(Entry), integer_to_list(category:id(Category)), category:title(Category)} }. detail(A, Id) -> Entry = entry:find_id(Id), Category = entry:category(Entry), {data, {entry:title(Entry), entry:body(Entry), integer_to_list(category:id(Category)), category:title(Category)} }. }}} entry_view.et {{{ <%@ index(Entry) %><% Body %>
Category: <% Category_Title %>
<%@ detail({Title, Body, Category_Id, Category_Title}) %><% Body %>
Category: <% Category_Title %>
}}} ErlyWeb treats all Erlang modules whose names don't end with *_controller* or *_view* and whose files exist under *src/components* as models. Coming back to the many-to-one relation we previously talked about, have a look at the models to guess how its done. Controllers are implemented in Erlang source files. Views are typically implemented in ErlTL files, but views can be implemented in plain Erlang as well. The controller file is named *[ComponentName]_controller.erl* and the view file is named *[ComponentName]_view.[Extension]*, where [ComponentName] is the name of the component, and [Extension] is *erl* for Erlang files and *et* for ErlTL files. For more details about this see the api docs for [http://erlyweb.org/doc/overview-summary.html#Components Components], [http://erlyweb.org/doc/overview-summary.html#Models Models], [http://erlyweb.org/doc/overview-summary.html#Controllers Controllers] and [http://erlyweb.org/doc/overview-summary.html#Views Views]. We´ve set up our Models, Controllers and Views, so its time to start the database and compile our app. == Connect to the database and compile your app == Type this commands in the Yaws Shell for (depending on your choice) === Mysql === {{{ erlydb:start(mysql, [{hostname, "localhost"}, {username, "username"}, {password, "password"}, {database, "blog"}]). erlyweb:compile("/path/to/apps/blog", [{erlydb_driver, mysql}]). }}} === PostgreSQL === (Not yet added) === Mnesia === (Not yet added) We are nearly at the end of this tutorial, but there isn´t much to see right now, so let´s add some records. == Creating Records == While still beeing in the Yaws shell, we´ll first add some categories. {{{ Cheer = category:new(<<"Cheer">>, <<"Kermit shouts: Applause, Applause, Applause!">>). category:insert(Cheer). ErlyWeb = category:new(<<"ErlyWeb">>, <<"The Erlang Twist on Web Frameworks">>). category:insert(ErlyWeb). }}} Now we´ll add some entries with relation to a specific category, don´t forget to unbind the previously set variables with {{{f()}}}. {{{ f(). Cheer = category:find({title,'=',<<"Cheer">>}). E1 = entry:new(<<"Welcome to my new blog">>, <<"Hello World, this is my first ErlyWeb powered application. Yippie-ki-yay!">>, [], Cheer). entry:save(E1). ErlyWeb = category:find({title,'=',<<"ErlyWeb">>}). E2 = entry:new(<<"About ErlyWeb">>, <<"ErlyWeb simplifies building database-driven webapps that follow the tried and true MVC pattern using a great language with many outstanding strengths.">>, [], ErlyWeb). entry:save(E2). }}} Let´s check some ways to query the data we just created. == Explore the database api == A simple module:find() returns all records for a module. {{{ category:find(). [{category,false,1,<<"Cheer">>, <<"Kermit shouts: Applause, Applause, Applause!">>}, {category,false,2,<<"ErlyWeb">>, <<"The Erlang Twist on Web Frameworks">>}] entry:find(). [{entry,false,1,<<"Welcome to my new blog">>, <<"Hello World, this is my first ErlyWeb powered application. Yippie-ki-yay!">>, {datetime,{{2008,1,23},{21,43,42}}}, 1}, {entry,false,2,<<"About ErlyWeb">>, <<"ErlyWeb simplifies building database-driven webapps that follow the tried and true MVC p"...>>, {datetime,{{2008,1,23},{21,44,20}}}, 2}] }}} We can also insert a WHERE clause to find specific data as you have just seen while creating records for entries. {{{ category:find({title,'=',<<"Cheer">>}). }}} Using module:find_with() we can define EXTRA expressions such as ordering and limiting records. {{{ category:find_with({order_by, {id, desc}}). category:find_with([{order_by, {id, desc}}, {limit,1}]). }}} With module:find_id() we can lookup a record with the given id value. {{{ C1 = category:find_id(1). }}} You can also query for a records attributes. {{{ category:title(C1). category:description(C1). }}} Or find related records. {{{ category:entries(C1). entry:category(E1). }}} You´ll read more about the database api in full detail later. We´re done with the introduction, congratulations. == Look Ma, no hassle == Finally, you should see this screens pointing your browser to {{{ http://localhost:8000/entry }}} and browsing around. [http://groups.google.com/group/erlyweb/web/blog_first_records.png http://groups.google.com/group/erlyweb/web/blog_first_records_thumb.png] [http://groups.google.com/group/erlyweb/web/blog_first_records_category.png http://groups.google.com/group/erlyweb/web/blog_first_records_category_thumb.png] [http://groups.google.com/group/erlyweb/web/blog_first_records_entry.png http://groups.google.com/group/erlyweb/web/blog_first_records_entry_thumb.png]