// vim: ft=asciidoc : N2O how-to ============ :author: Dave Kuhlman :email: dkuhlman (at) davekuhlman (dot) org :toc: How to install N2O -------------------- Run this: ---------- $ git clone git://github.com/5HT/n2o.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+ Some documentation is here: https://synrc.com/apps/n2o/doc/web/elements.htm 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", app=n2o_sample, bindings=[ {title, title()}, {body, body()}, {info, info()}]}. title() -> [ <<"Information">> ]. body() -> [ #span{body="Name: "}, #textbox{id=username, autofocus=true}, #br{}, #button{ id=userdata, body="Update user data", postback=userdata, source=[username]}, #hr{}, #panel{id=new_content, body=[]}, #hr{} ]. 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+.