How to install N2O

Run this:

$ git clone git://

How to serve an N2O application

Go to the application directory inside the n2o directory and run mad. For example:

$ cd n20/samples
$ ./mad deps compile plan repl

If the dependencies have already been downloaded and compiled, then just do:

$ ./mad repl

How to do logging and debugging

We need to turn on logging by calling:

log_modules() -> [module1, module2].

Then use any of the following logging functions defined in n2o/src/wf.erl:

  • wf:info/2, wf:info/3

  • wf:warning/2, wf:warning/3

  • wf:error/2, wf:error/3

For example:

wf:info(?MODULE, "Some message and argument: ~p~n", [Arg1]),

How to modify an existing page

There are several pieces that may need modification, depending …

  • If the contents to be modified are in the HTML template, then modify the relevant template file in n2o/my_app/apps/my_app1/priv/templates.

  • If the contents to be modified are being inserted into the page by the page handler using N2O/Nitrogen DSL elements. Often there will be a function named body that is called to generate the content. In order to determine which is the relevant module to be modified, look in n2o/my_app/apps/my_app1/src/routes.erl.

How to create a new page

Follow this steps:

  1. Add a routing specification to routes.erl, likely in the function route/1. For example, you might add a clause something like this:

    route(<<"my_page">>) -> my_page;
  2. Add a template to n2o/my_app/apps/my_app1/priv/templates. The template is standard HTML code. It may also contain targets to be filled in with content from the handler module. For example, a target might look like this {{ body }}.

  3. Add a module to n2o/my_app/apps/my_app1/src/. The name should match the target in the clause you added to routes.erl. See other modules in the src/ directory for hints and tips and clues.

  4. In your new module, make the following changes:

    • Change the module name in the module(xxx) macro.

    • Change the reference to the template (HTML) file.

    • Create functions that return chunks of content using the N2O content API/records.

How to define elements using Erlang

Take a look at the Erlang modules in the sample app. They are here: n2o/samples/apps/n2o_sample/src

The code that implements the element records is here: n2o/src/nitrogen/elements

And the record definitions themselves are here: n2o/include/wf.hrl

How to update a page on an event

This section explains how push data into a page on an event, for example a button click in the page.

  1. Add a button to the page. Also add an element to serve as the target for the new or updated content. For example:

    main() -> #dtl{file = "info",
                   bindings=[ {title, title()}, {body, body()}, {info, info()}]}.
    title() -> [ <<"Information">> ].
    body() ->
            #span{body="Name: "},
            #textbox{id=username, autofocus=true},
                body="Update user data",
            #panel{id=new_content, body=[]},
    info() ->
        [ #p{body="more content"} ].
  2. Add an event handler. The event you catch must match the event that is sent, in this case by the button:

    event(userdata) ->
        Username = wf:q(username),
        wf:info(?MODULE, "event(userdata) called.  username: ~p~n",[Username]);
    event(_) ->
        wf:info(?MODULE, "unknown event called~n", []).
  3. Modify your event handler so that it pushes data back to an element in the Web page. Note that we update the new_content element that is defined above:

    event(userdata) ->
        Username = wf:q(username),
        wf:info(?MODULE, "event(userdata) called.  username: ~p~n",[Username]),
        wf:update(new_content, #panel{id=new_content, body=[
            #p{body=["The User name: ", Username]}]});
    event(_) ->
        wf:info(?MODULE, "unknown event called~n", []).

How to create a new application

Copy an existing one. Follow these steps:

  1. Do a deep copy of the n2o/samples directory. For example:

    $ cd n2o
    $ cp -r samples my_app
  2. Modify n2o/my_app/apps/src/routes. Change clauses in route/1, in particular.

  3. Create a module for each new route that you added to routes.erl. You might consider copying an existing module under my_app/apps/src. And, after you’ve done this several times, you are likely to create your own skeleton that you can copy and modify.

  4. In some cases you will also want to create a new template in my_app/apps/priv/templates.