Skip to content

Commit

Permalink
Merge branch 'master' into multi
Browse files Browse the repository at this point in the history
Conflicts:
	include/wf.inc
	www/nitrogen.js
  • Loading branch information
rustyio committed Mar 22, 2009
2 parents 9ee67ca + 02ecbc2 commit 09b738a
Show file tree
Hide file tree
Showing 28 changed files with 210 additions and 40 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG
@@ -1,3 +1,11 @@
2009-03-22
- Added alt text support to #image elements by Robert Schonberger.
- Fixed bug, 'nitrogen create (PROJECT)' now does a recursive copy of the Nitrogen support files, by Jay Doane.
- Added radio button support courtesy of Benjamin Nortier and Tom McNulty.

2009-03-16
- Added .app configuration setting to bind Nitrogen to a specific IP address, by Tom McNulty.

2009-03-08
- Added DatePicker element by Torbjorn Tornkvist.
- Upgrade to JQuery 1.3.2 and JQuery UI 1.7.
Expand Down
2 changes: 1 addition & 1 deletion Quickstart/Quickstart.tmproj
Expand Up @@ -176,6 +176,6 @@
</dict>
</dict>
<key>windowFrame</key>
<string>{{206, 0}, {1013, 778}}</string>
<string>{{204, 0}, {1013, 778}}</string>
</dict>
</plist>
1 change: 1 addition & 0 deletions Quickstart/src/samples/web_samples.erl
Expand Up @@ -17,6 +17,7 @@ column1() -> [
#link { text="In-Place Textbox", url="/web/samples/advancedcontrols1" }, #br{},
#link { text="Google Charts", url="/web/samples/advancedcontrols2" }, #br{},
#link { text="Step-by-Step Wizard", url="/web/samples/advancedcontrols3" }, #br{},
#link { text="Radio Buttons", url="/web/samples/radio" }, #br{},
#link { text="Validation", url="/web/samples/validation" }, #br{},

#h3 { text="User Interface" },
Expand Down
39 changes: 39 additions & 0 deletions Quickstart/src/samples/web_samples_radio.erl
@@ -0,0 +1,39 @@
-module (web_samples_radio).
-include ("wf.inc").
-include ("google_chart.inc").
-compile(export_all).

main() -> #template { file="./wwwroot/onecolumn.html", bindings=[
{'Group', learn},
{'Item', samples}
]}.

title() -> "Radio Button Example".
headline() -> "Radio Button Example".
right() -> linecount:render().

body() -> [

#p{},
#label { text="Radio Buttons" },
#radiogroup { id=myRadio, body=[
#radio { id=myRadio1, text="Option 1", value="1", postback={checked, 1}, checked=true }, #p{},
#radio { id=myRadio2, text="Option 2", value="2", postback={checked, 2} }, #p{},
#radio { id=myRadio3, text="Option 3", value="3", postback={checked, 3} }, #p{},
#radio { id=myRadio4, text="Option 4", value="4", postback={checked, 4} }
]},
#p{},
#button { text="Postback", postback=clicked_button }
].

event({checked, Number}) ->
wf:flash(wf:f("You selected radio button ~p.", [Number])),
ok;

event(clicked_button) ->

wf:flash("Radio button " ++ wf:q(myRadio) ++ " is selected."),
wf:flash("Is radio button 1 selected: " ++ wf:q(myRadio1)),
ok;

event(_) -> ok.
9 changes: 9 additions & 0 deletions Quickstart/src/samples/web_samples_simplecontrols.erl
Expand Up @@ -49,6 +49,15 @@ body() -> [
#option { text="Option 3" }
]},

#p{},
#label { text="Radio Buttons" },
#radiogroup { body=[
#radio { id=myRadio1, text="Option 1", value="1", checked=true }, #p{},
#radio { id=myRadio2, text="Option 2", value="2" }, #p{},
#radio { id=myRadio3, text="Option 3", value="3" }, #p{},
#radio { id=myRadio4, text="Option 4", value="4" }
]},

#p{},
#label { text="Checkbox" },
#checkbox { text="Checkbox", checked=true },
Expand Down
8 changes: 4 additions & 4 deletions include/wf.inc
Expand Up @@ -31,7 +31,7 @@
-record(listitem, {?ELEMENT_BASE(element_listitem), body=[], text="", html_encode=true}).
-record(br, {?ELEMENT_BASE(element_br) }).
-record(hr, {?ELEMENT_BASE(element_hr) }).
-record(p, {?ELEMENT_BASE(element_p) }).
-record(p, {?ELEMENT_BASE(element_p), body=""}).
-record(label, {?ELEMENT_BASE(element_label), text="", html_encode=true}).
-record(value, {?ELEMENT_BASE(element_value), text="", html_encode=true}).
-record(link, {?ELEMENT_BASE(element_link), text="", body="", html_encode=true, url="javascript:", postback}).
Expand All @@ -43,15 +43,15 @@
-record(hidden, {?ELEMENT_BASE(element_hidden), text="", html_encode=true}).
-record(textarea, {?ELEMENT_BASE(element_textarea), text="", html_encode=true}).
-record(datepicker_textbox, {?ELEMENT_BASE(element_datepicker_textbox), text="", next, html_encode=true, validators=[], options = [{dateFormat, "yy-mm-dd"}] }).


-record(dropdown, {?ELEMENT_BASE(element_dropdown), options=[], html_encode=true, postback, value}).
-record(option, { text="", value="", selected=false }).
-record(checkbox, {?ELEMENT_BASE(element_checkbox), text="", html_encode=true, checked=false, postback}).
-record(radiogroup, {?ELEMENT_BASE(element_radiogroup), body=[]}).
-record(radio, {?ELEMENT_BASE(element_radio), text="", html_encode=true, value, name, checked=false, postback}).
-record(password, {?ELEMENT_BASE(element_password), text="", html_encode=true, next, postback}).
-record(panel, {?ELEMENT_BASE(element_panel), body=""}).
-record(spinner, {?ELEMENT_BASE(element_spinner), image="/nitrogen/spinner.gif"}).
-record(image, {?ELEMENT_BASE(element_image), image=""}).
-record(image, {?ELEMENT_BASE(element_image), image="", alt}).
-record(rounded_panel, {?ELEMENT_BASE(element_rounded_panel), body="", color=gray}).
-record(lightbox, {?ELEMENT_BASE(element_lightbox), body="" }).
-record(table, {?ELEMENT_BASE(element_table), rows}).
Expand Down
2 changes: 1 addition & 1 deletion priv/skel/Makefile
Expand Up @@ -2,4 +2,4 @@ compile:
erl -make

clean:
rm -rf ./ebin/*.beam
rm -rf ./ebin/*.beam
2 changes: 1 addition & 1 deletion priv/skel/PROJECT_app.erl
Expand Up @@ -2,7 +2,7 @@
-export ([start/2, stop/1, route/1, request/1]).
-behavior(application).

start(_, _) -> nitrogen:start().
start(_, _) -> nitrogen:start(PROJECT).
stop(_) -> nitrogen:stop().

%% route/1 lets you define new URL routes to your web pages,
Expand Down
40 changes: 40 additions & 0 deletions src/elements/forms/element_radio.erl
@@ -0,0 +1,40 @@
% Nitrogen Web Framework for Erlang
% Copyright (c) 2008-2009 Rusty Klophaus
% See MIT-LICENSE for licensing information.

-module (element_radio).
-include ("wf.inc").
-compile(export_all).

reflect() -> record_info(fields, radio).

render(ControlID, Record) ->
CheckedOrNot = case Record#radio.checked of
true -> checked;
_ -> not_checked
end,

case Record#radio.postback of
undefined -> ok;
Postback -> wf:wire(ControlID, #event { type=change, postback=Postback })
end,

Content = wf:html_encode(Record#radio.text, Record#radio.html_encode),

[
%% Checkbox...
wf_tags:emit_tag(input, [
{id, ControlID},
{name, Record#radio.name},
{value, Record#radio.value},
{type, radio},
{class, [radio, Record#radio.class]},
{style, Record#radio.style},
{CheckedOrNot, true}
]),

%% Label for Radio...
wf_tags:emit_tag(label, Content, [
{for, ControlID}
])
].
27 changes: 27 additions & 0 deletions src/elements/forms/element_radiogroup.erl
@@ -0,0 +1,27 @@
% Nitrogen Web Framework for Erlang
% Copyright (c) 2008-2009 Rusty Klophaus
% See MIT-LICENSE for licensing information.

-module (element_radiogroup).
-include ("wf.inc").
-compile(export_all).

reflect() -> record_info(fields, radiogroup).

render(ControlID, Record) ->
% Set the group to the current ControlID...

F = fun(X) ->
case is_record(X, radio) of
true -> X#radio { name=ControlID };
false -> X
end
end,
Body = [F(X) || X <- Record#radiogroup.body],

% Render the record...
element_panel:render(ControlID, #panel {
class="radiogroup " ++ wf:to_list(Record#radiogroup.class),
style=Record#radiogroup.style,
body=Body
}).
13 changes: 10 additions & 3 deletions src/elements/html/element_image.erl
Expand Up @@ -8,10 +8,17 @@

reflect() -> record_info(fields, image).

render(ControlID, Record) ->
wf_tags:emit_tag(img, [
render(ControlID, Record) ->
Attributes = [
{id, ControlID},
{class, [image, Record#image.class]},
{style, Record#image.style},
{src, Record#image.image}
]).
],

FinalAttributes = case Record#image.alt of
undefined -> Attributes;
ImageAlt -> [{alt, ImageAlt}|Attributes]
end,

wf_tags:emit_tag(img, FinalAttributes).
4 changes: 2 additions & 2 deletions src/elements/html/element_listitem.erl
Expand Up @@ -13,9 +13,9 @@ render(ControlID, Record) ->
wf:html_encode(Record#listitem.text, Record#listitem.html_encode),
wf:render(Record#listitem.body)
],

wf_tags:emit_tag(li, Content, [
{id, ControlID},
{class, [listitem, Record#listitem.class]},
{style, Record#listitem.style}
]).
]).
6 changes: 4 additions & 2 deletions src/elements/html/element_p.erl
Expand Up @@ -9,8 +9,10 @@
reflect() -> record_info(fields, p).

render(ControlID, Record) ->
wf_tags:emit_tag(p, [
Content = wf:render(Record#p.body),
wf_tags:emit_tag(p, Content, [
{id, ControlID},
{class, [p, Record#p.class]},
{style, Record#p.style}
]).
]).

2 changes: 1 addition & 1 deletion src/elements/layout/element_panel.erl
Expand Up @@ -14,4 +14,4 @@ render(ControlID, Record) ->
{id, ControlID},
{class, ["panel", Record#panel.class]},
{style, Record#panel.style}
]).
]).
9 changes: 8 additions & 1 deletion src/lib/wf_tags.erl
Expand Up @@ -20,7 +20,14 @@ emit_tag(TagName, Props) ->
].

%%% Tags with child content %%%


% empty text and body
emit_tag(TagName, [[], []], Props) ->
emit_tag(TagName, Props);

emit_tag(TagName, [], Props) when TagName =/= 'div' ->
emit_tag(TagName, Props);

emit_tag(TagName, Content, Props) ->
STagName = wf:to_list(TagName),
[
Expand Down
22 changes: 21 additions & 1 deletion src/nitrogen.erl
Expand Up @@ -14,6 +14,7 @@
request/1,
get_platform/0,
get_host/0,
get_ip/0,
get_port/0,
get_session_timeout/0,
get_sign_key/0,
Expand Down Expand Up @@ -47,10 +48,16 @@ start_server() ->
inets -> nitrogen_inets_app:start()
end,

Host = case get_ip() of
{0,0,0,0} -> "localhost";
{127,0,0,1} -> "localhost";
{W,X,Y,Z} -> wf:f("~B.~B.~B.~B", [W, X, Y, Z])
end,

io:format("~n~n---~n"),
io:format("Nitrogen is now running on ~s.~n", [get_platform()]),
io:format("Serving files from: ~s.~n", [get_wwwroot()]),
io:format("Open your browser to: http://~s:~p~n", [get_host(),get_port()]),
io:format("Open your browser to: http://~s:~p~n", [Host, get_port()]),
io:format("---~n~n"),

Result.
Expand Down Expand Up @@ -87,6 +94,19 @@ get_host() ->
_ -> "localhost"
end.

get_ip() ->
case get_env(serving_app(), ip) of
{ok, Val} when is_tuple(Val) ->
Val;
{ok, Val} ->
case inet_parse:address(Val) of
{ok, Ip} -> Ip;
_ -> throw("Invalid ip configuration string")
end;
_ ->
{0,0,0,0}
end.

get_port() ->
case get_env(serving_app(), port) of
{ok, Val} -> Val;
Expand Down
2 changes: 1 addition & 1 deletion src/platforms/nitrogen_inets_app.erl
Expand Up @@ -15,7 +15,7 @@ start() ->
{port, nitrogen:get_port()},
{document_root, nitrogen:get_wwwroot()},
{server_root, "."},
{bind_address, any},
{bind_address, nitrogen:get_ip()},
{server_name, nitrogen:get_host()},
{modules, [wf_inets, mod_head, mod_get]},
{mime_types, [{"css", "text/css"}, {"js", "text/javascript"}, {"html", "text/html"}]}
Expand Down
3 changes: 2 additions & 1 deletion src/platforms/nitrogen_mochiweb_app.erl
Expand Up @@ -12,9 +12,10 @@ start() ->
wf:init(),

% Start the Mochiweb server.
Ip = nitrogen:get_ip(),
Port = nitrogen:get_port(),
DocumentRoot = nitrogen:get_wwwroot(),
Options = [{ip, "0.0.0.0"}, {port, Port}],
Options = [{ip, Ip}, {port, Port}],
HooksModule = nitrogen:get_hooks_module(),
case erlang:function_exported(HooksModule, loop, 2) of
true ->
Expand Down
4 changes: 2 additions & 2 deletions src/platforms/nitrogen_yaws_app.erl
Expand Up @@ -19,7 +19,7 @@ start() ->
docroot = nitrogen:get_wwwroot(),
port=nitrogen:get_port(),
appmods = [{"/web", wf_yaws}],
listen = {0, 0, 0, 0}
listen = nitrogen:get_ip()
},
DefaultGC = yaws_config:make_default_gconf(false, Id),
GC = DefaultGC#gconf {
Expand All @@ -44,4 +44,4 @@ stop() ->
exit(Pid, kill),
ok.



11 changes: 8 additions & 3 deletions src/project/nitrogen_project.erl
Expand Up @@ -26,9 +26,14 @@ create_tree(Dir) ->
[ file:make_dir(filename:join(Dir,X)) || X <- Tree].

copy_nitrogen_www(DestDir) ->
SrcDir = src_path("www"),
{ok, FileList} = file:list_dir(SrcDir),
[ nitrogen_file:copy_file(src_path("www/"++X), filename:join(DestDir, X)) || X <- FileList ].
SrcDir = src_path("www") ++ "/",
filelib:fold_files(SrcDir, ".*", true,
fun(SrcFile, _) ->
DestFile = filename:join(DestDir, SrcFile--SrcDir),
filelib:ensure_dir(DestFile),
nitrogen_file:copy_file(SrcFile, DestFile)
end,
[]).

copy_template_files(Name, DestDir) ->
Changes = [{"PROJECT", Name},{"PAGE", "web_index"}],
Expand Down
4 changes: 2 additions & 2 deletions test/src/elements/html/element_label_test.erl
Expand Up @@ -20,8 +20,8 @@ new_label_3() ->
lists:flatten(element_label:render("3",Rec_label)).

basic_test_() ->
[?_assertEqual("<span id='1' class='label'></span>",new_label_1()),
?_assertEqual("<span id='2' class='label t_label'></span>",new_label_2()),
[?_assertEqual("<span id='1' class='label'/>",new_label_1()),
?_assertEqual("<span id='2' class='label t_label'/>",new_label_2()),
?_assertEqual("<span id='3' class='label t_label' style='color: cyan;'>Username:</span>",new_label_3()),
?_assertEqual([module,id,actions,show_if,class,style,text,html_encode],
element_label:reflect())
Expand Down
6 changes: 3 additions & 3 deletions test/src/elements/html/element_link_test.erl
Expand Up @@ -28,9 +28,9 @@ new_link_5() ->
lists:flatten(element_link:render("5",Rec_link)).

basic_test_() ->
[?_assertEqual("<a id='1' href='javascript:' class='link'></a>", new_link_1()),
?_assertEqual("<a id='2' href='javascript:' class='link'></a>", new_link_2()),
?_assertEqual("<a id='3' href='javascript:' class='link'></a>", new_link_3()),
[?_assertEqual("<a id='1' href='javascript:' class='link'/>", new_link_1()),
?_assertEqual("<a id='2' href='javascript:' class='link'/>", new_link_2()),
?_assertEqual("<a id='3' href='javascript:' class='link'/>", new_link_3()),
?_assert(eunit_helper:regexpMatch("<a id='4' href='javascript:' class='link'><img id='.*?' class='image' src='/path/to/image.gif'/></a>",
new_link_4())),
?_assertEqual("<a id='5' href='not_javascript' class='link'>LINK&nbsp;TEXTA LINK BODY</a>", new_link_5()),
Expand Down

0 comments on commit 09b738a

Please sign in to comment.