How to install Nitrogen

UPDATE : this is slightly obsolete post now.
See part 2 which explains how to setup Nitrogen with Cowboy

Nitrogen is one of the web frameworks available for people who like to program in Erlang. There are few other alternatives, and here you can find some useful features comparison.

In short, Nitrogen allows you to create dynamic websites with Erlang backends. It supports Ajax, Comet, etc. It gives your building block in the form of the elements – some of which are simple html forms but others are wrappers around JQuery UI controls. You can extend Nitrogen by building your own custom elements and binding javascript actions to them. Anyway, I think it is pretty cool and though Nitrogen doesn’t completely shield you from using javascript, you can get pretty far by quickly cooking up initial Web GUI with existing elements and then extend whatever you need by your own custom elements. At this stage you will probably need to dig deeper into javascript and JQuery. In the next posts I will give detailed examples of how to build custom controls because this is how you get most value from using Nitrogen.

Assuming that you are convinced now and did your own research and decided to give Nitrogen a try, I will give few steps that might help you to get started.

I like to use Nitrogen as a dependency library which could be pulled from github wherever I need to build my project. This is a bit different from the standard installation which requires you to load Nitrogen from one of the pre-built binaries and add your project into “Sites” directory.
I also prefer to use Webmachine as http requests routing mechanism.

Hopefully you already have rebar installed, if not please clone from rebar git repo and build it.

Now, when you have rebar installed, let’s start:

1. Create an empty folder for your project:

$ mkdir nitrogen_proj;cd nitrogen_proj

2. Create a template for your application:

$ rebar create-app appid=nitrogen_proj

this will create 3 files in your project’s src dir:

Screen Shot 2012-12-29 at 18.46.19

3. Create Makefile in the root of your project and add the following commands:

all: get-deps compile

get-deps:
	rebar get-deps

compile:
	rebar compile
	(rm -rf priv/static/nitrogen; mkdir -p priv/static/nitrogen; \
	cp -r deps/nitrogen_core/www/* priv/static/nitrogen/;)

clean:
	rebar clean

and make it executable:

$ chmod u+x Makefile

4. Create rebar.config in the root of the project and add the following:

{lib_dirs,["deps"]}.
{src_dirs, ["src"]}.
{erl_opts, [debug_info, fail_on_warning]}.

{deps, [
    {mochiweb, ".*", {git, "git://github.com/mochi/mochiweb.git", {tag, "1.5.1"}}},
    {nitrogen_core, ".*", {git, "git://github.com/nitrogen/nitrogen_core", "HEAD"}},
    {nprocreg,      ".*", {git, "git://github.com/nitrogen/nprocreg", "HEAD"}},
    {simple_bridge, ".*", {git, "git://github.com/nitrogen/simple_bridge", "HEAD"}},
    {sync,          ".*", {git, "git://github.com/rustyio/sync", "HEAD"}},
    {webmachine, ".*", {git, "git://github.com/basho/webmachine", "HEAD"}}
]}.

5. run make.

If everything is good (you have make installed at your systems and everything else is up to date and not broken), you should see rebar pulling a bunch of repos from github and adding them into src/deps and then compiling *.erl’s into *.beam’s.

My project dir looks like this now:
Screen Shot 2012-12-29 at 19.22.02

Also notice that make copied deps/nitrogen_core/www/* -> priv/static/nitrogen.

At this point we are *almost* done with getting all the dependencies but we are still missing three critical files (nitrogen_webmachine.erl, static_resource.erl and static_route_handler.erl) which are not part of nitrogen_core repo, but instead live in nitrogen. Unfortunately we can’t add https://github.com/nitrogen/nitrogen.git as a dependency to our project because it is not OTP application but OPT release, so rebar would fail while validating it. So, it is probably easier to manually clone Nitrogen release repo and copy these three files into our src folder.

6. clone Nitrogen repo and copy files from Nitrogen to nitrogen_proj/src:

$ cd ..
$ git clone https://github.com/nitrogen/nitrogen.git
$ cp nitrogen/rel/overlay/webmachine/site/src/nitrogen_webmachine.erl nitrogen/rel/overlay/webmachine/site/src/static_resource.erl nitrogen/rel/overlay/webmachine/site/src/static_route_handler.erl ./nitrogen_proj/src/

You only need to do this step once, after you get the files into src, add them into the git repo along with other source files. After that you can delete and reload other dependencies just by running make.

and finally lets copy templates:

$ cp -r nitrogen/rel/overlay/common/site/templates ./nitrogen_proj/priv

Ok, now we have all the project dependencies ready and we can create a first page.

7. create file index.erl in nitrogen_proj/src and add the following contents:

-module (index).
-include_lib ("nitrogen_core/include/wf.hrl").
-compile(export_all).
main() -> #template { file="./priv/templates/bare.html" }.
title() -> "Nitrogen Web Framework for Erlang".
body() -> "Hello World!".

8. add nitrogen_proj.config into src with the following contents:

[
 {nitrogen_proj, [
		  {bind_address,"0.0.0.0"},
		  {port,8000}
		 ]},

 {sync, [{sync_mode, nitrogen}]}
].

9. add the following line at the end of your rebar.config:

{post_hooks, [{compile, "cp ./src/nitrogen_proj.config ./ebin/nitrogen_proj.config"}]}.

this will make sure that config file for our application will be copied into ebin every time you make a change to it.

10. Open nitrogen_proj_sup.erl and add the following:

-module(nitrogen_proj_sup).
-behaviour(supervisor).
-export([
	 start_link/0,
	 init/1
	]).

-include_lib("webmachine/include/webmachine.hrl").
-include_lib ("nitrogen_core/include/wf.hrl").

%% ===================================================================
%% API functions
%% ===================================================================

start_link() ->
    supervisor:start_link({local, ?MODULE}, ?MODULE, []).

%% ===================================================================
%% Supervisor callbacks
%% ===================================================================

init([]) ->
    {ok, BindAddress} = application:get_env(bind_address),
    {ok, Port} = application:get_env(port),

    Options = [
        {ip, BindAddress},
        {port, Port},
        {dispatch, dispatch()}
    ],
    webmachine_mochiweb:start(Options),
    {ok, { {one_for_one, 5, 10}, []} }.

dispatch() ->
    [
     %% Static content handlers...
     {["css", '*'], static_resource, [{root, "./priv/static/css"}]},
     {["images", '*'], static_resource, [{root, "./priv/static/images"}]},
     {["nitrogen", '*'], static_resource, [{root, "./priv/static/nitrogen"}]},
     {["/"], nitrogen_webmachine, index},
     {['*'], nitrogen_webmachine, dynamic_route_handler}
    ].

this is probably the most important part as the code above defines the routing rules and specifies how your requests are processed by Webmachine. First three rules in dispatch() function are dealt with by static_resource.erl module and used to load static contents, css, images, etc. The last two lines specify rules for dynamic contents which are processed by nitrogen_webmachine.erl module which will route the requests to the Nitrogen to render. In our case we want our default page “/” to be routed to index.erl module.

11. open nitrogen_proj_app.erl and add the following:

-module(nitrogen_proj_app).
-behaviour(application).
-export([
	 start/0,
	 start/2,
	 stop/1
	]).

-define(APPS, [nprocreg, sync, nitrogen_proj]).

%% ===================================================================
%% Application callbacks
%% ===================================================================

%% to start manually from console with start.sh
start() ->
    [begin application:start(A), io:format("~p~n", [A]) end || A <- ?APPS].

start(_StartType, _StartArgs) ->
    nitrogen_proj_sup:start_link().

stop(_State) ->
    ok.

this code is called from start.sh script and starts the applications which we want to be running in our erlang node.

12. create start.sh in the root of your project and add the following:

#!/bin/sh
cd `dirname $0`
exec erl -pa $PWD/ebin -pa $PWD/deps/*/ebin -name web"@"$HOSTNAME \
-s nitrogen_proj_app start -config ebin/nitrogen_proj

make start.sh executable:

$ chmod u+x start.sh

13. and now run make last time and check that your project compiles without errors.

14. start your app:

$ ./start.sh

15. point the browser to http://localhost:8000

hopefully you will see something like this:

Screen Shot 2012-12-29 at 23.51.20

Admittedly, the steps above are not as simple as I expected but maybe this will be helpful for someone who needs to add Nitrogen as dependency to the project.

You can find all the code for this example here

About these ads
This entry was posted in Erlang, Nitrogen. Bookmark the permalink.

5 Responses to How to install Nitrogen

  1. Pingback: How to create custom Nitrogen elements using Tabs control as example. | R.Shestakov

  2. that’s huge config for simple project :)

    git clone https://github.com/nitrogen/nitrogen
    cd nitrogen
    make rel_yaws

    easier for beginners :))

    but this will create site. So what to do to change that to the name of your project ? would be helpfull.

    • Hi, the idea is to use nitrogen as dependency lib instead of adding your app logic into Nitrogen site. I want to be able to add my project dependencies into rebar.config including Nitrogen bits. This is currently not easily allowable by Nitrogen setup. Your example would force me to add my code into Nitrogen site instead of other way around

    • I somehow managed to remove your last comment, didn’t mean to, sorry

  3. Yes, true :-), I like Cowboy more now. Will add some updates for Cowboy config. Thanks for noticing

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s