summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--ChangeLog12
-rw-r--r--src/mod_offline.erl2
-rw-r--r--src/mod_offline_odbc.erl2
-rw-r--r--src/mod_roster.erl4
-rw-r--r--src/mod_roster_odbc.erl4
-rw-r--r--src/mod_shared_roster.erl35
-rw-r--r--src/web/ejabberd_web_admin.erl168
-rw-r--r--src/web/ejabberd_web_admin.hrl10
8 files changed, 142 insertions, 95 deletions
diff --git a/ChangeLog b/ChangeLog
index 6270afdc..aaae2717 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,16 @@
2009-01-12 Badlop <badlop@process-one.net>
+ * src/web/ejabberd_web_admin.erl: Use textareas for large input
+ like ejabberd module options and listening port options. Show
+ result of POST more clearly. Ensure access rules are shown with
+ some minimum separation. Improve menu headers. (EJAB-562)
+ * src/web/ejabberd_web_admin.hrl: Likewise
+ * src/mod_offline.erl: Likewise
+ * src/mod_offline_odbc.erl: Likewise
+ * src/mod_roster.erl: Likewise
+ * src/mod_roster_odbc.erl: Likewise
+ * src/mod_shared_roster.erl: Likewise
+
* src/ejabberd_listener.erl: New way to configure IP address and
IP version of listener. Support for definition of IP address in
string format, and implicit definition of IP
@@ -13,6 +24,7 @@
* src/mod_proxy65/mod_proxy65_stream.erl: Likewise
* src/mod_proxy65/mod_proxy65_service.erl: Likewise
* src/web/ejabberd_web_admin.erl: Likewise
+
* doc/guide.tex: Document the new way to configure IP address and
IP version of listener, undocument options ip and inet6
* doc/guide.html: Likewise
diff --git a/src/mod_offline.erl b/src/mod_offline.erl
index b2e2b5db..0607ddb8 100644
--- a/src/mod_offline.erl
+++ b/src/mod_offline.erl
@@ -500,7 +500,7 @@ user_queue(User, Server, Query, Lang) ->
[?XC("h1", io_lib:format(?T("~s's Offline Messages Queue"),
[us_to_list(US)]))] ++
case Res of
- ok -> [?CT("Submitted"), ?P];
+ ok -> [?XREST("Submitted")];
nothing -> []
end ++
[?XAE("form", [{"action", ""}, {"method", "post"}],
diff --git a/src/mod_offline_odbc.erl b/src/mod_offline_odbc.erl
index b3f1ec10..e70cfbe6 100644
--- a/src/mod_offline_odbc.erl
+++ b/src/mod_offline_odbc.erl
@@ -358,7 +358,7 @@ user_queue(User, Server, Query, Lang) ->
[?XC("h1", io_lib:format(?T("~s's Offline Messages Queue"),
[us_to_list(US)]))] ++
case Res of
- ok -> [?CT("Submitted"), ?P];
+ ok -> [?XREST("Submitted")];
nothing -> []
end ++
[?XAE("form", [{"action", ""}, {"method", "post"}],
diff --git a/src/mod_roster.erl b/src/mod_roster.erl
index c52ff57f..a1639c55 100644
--- a/src/mod_roster.erl
+++ b/src/mod_roster.erl
@@ -844,8 +844,8 @@ user_roster(User, Server, Query, Lang) ->
end,
[?XC("h1", ?T("Roster of ") ++ us_to_list(US))] ++
case Res of
- ok -> [?CT("Submitted"), ?P];
- error -> [?CT("Bad format"), ?P];
+ ok -> [?XREST("Submitted")];
+ error -> [?XREST("Bad format")];
nothing -> []
end ++
[?XAE("form", [{"action", ""}, {"method", "post"}],
diff --git a/src/mod_roster_odbc.erl b/src/mod_roster_odbc.erl
index 1678e525..ee4e326a 100644
--- a/src/mod_roster_odbc.erl
+++ b/src/mod_roster_odbc.erl
@@ -944,8 +944,8 @@ user_roster(User, Server, Query, Lang) ->
end,
[?XC("h1", ?T("Roster of ") ++ us_to_list(US))] ++
case Res of
- ok -> [?CT("Submitted"), ?P];
- error -> [?CT("Bad format"), ?P];
+ ok -> [?XREST("Submitted")];
+ error -> [?XREST("Bad format")];
nothing -> []
end ++
[?XAE("form", [{"action", ""}, {"method", "post"}],
diff --git a/src/mod_shared_roster.erl b/src/mod_shared_roster.erl
index 01bd1662..1a15119b 100644
--- a/src/mod_shared_roster.erl
+++ b/src/mod_shared_roster.erl
@@ -725,8 +725,8 @@ list_shared_roster_groups(Host, Query, Lang) ->
)]),
?H1GL(?T("Shared Roster Groups"), "modsharedroster", "mod_shared_roster") ++
case Res of
- ok -> [?CT("Submitted"), ?P];
- error -> [?CT("Bad format"), ?P];
+ ok -> [?XREST("Submitted")];
+ error -> [?XREST("Bad format")];
nothing -> []
end ++
[?XAE("form", [{"action", ""}, {"method", "post"}],
@@ -789,8 +789,9 @@ shared_roster_group(Host, Group, Query, Lang) ->
[]
end ++ [[us_to_list(Member), $\n] || Member <- Members],
FDisplayedGroups = [[DG, $\n] || DG <- DisplayedGroups],
+ DescNL = length(element(2, regexp:split(Description, "\n"))),
FGroup =
- ?XAE("table", [],
+ ?XAE("table", [{"class", "withtextareas"}],
[?XE("tbody",
[?XE("tr",
[?XCT("td", "Name:"),
@@ -799,34 +800,34 @@ shared_roster_group(Host, Group, Query, Lang) ->
),
?XE("tr",
[?XCT("td", "Description:"),
- ?XE("td", [?XAC("textarea", [{"name", "description"},
- {"rows", "3"},
- {"cols", "20"}],
- Description)])
+ ?XE("td", [
+ ?TEXTAREA("description", integer_to_list(lists:max([3, DescNL])), "20", Description)
+ ]
+ )
]
),
?XE("tr",
[?XCT("td", "Members:"),
- ?XE("td", [?XAC("textarea", [{"name", "members"},
- {"rows", "3"},
- {"cols", "20"}],
- FMembers)])
+ ?XE("td", [
+ ?TEXTAREA("members", integer_to_list(lists:max([3, length(FMembers)])), "20", FMembers)
+ ]
+ )
]
),
?XE("tr",
[?XCT("td", "Displayed Groups:"),
- ?XE("td", [?XAC("textarea", [{"name", "dispgroups"},
- {"rows", "3"},
- {"cols", "20"}],
- FDisplayedGroups)])
+ ?XE("td", [
+ ?TEXTAREA("dispgroups", integer_to_list(lists:max([3, length(FDisplayedGroups)])), "20", FDisplayedGroups)
+ ]
+ )
]
)]
)]),
?H1GL(?T("Shared Roster Groups"), "modsharedroster", "mod_shared_roster") ++
[?XC("h2", ?T("Group ") ++ Group)] ++
case Res of
- ok -> [?CT("Submitted"), ?P];
- error -> [?CT("Bad format"), ?P];
+ ok -> [?XREST("Submitted")];
+ error -> [?XREST("Bad format")];
nothing -> []
end ++
[?XAE("form", [{"action", ""}, {"method", "post"}],
diff --git a/src/web/ejabberd_web_admin.erl b/src/web/ejabberd_web_admin.erl
index cf3150b9..ea1a936e 100644
--- a/src/web/ejabberd_web_admin.erl
+++ b/src/web/ejabberd_web_admin.erl
@@ -157,7 +157,7 @@ make_xhtml(Els, Host, Node, Lang) ->
[?XAE("div",
[{"id", "header"}],
[?XE("h1",
- [?ACT("/admin/", "Administration")]
+ [?ACT("/admin/", "ejabberd Web Admin")]
)]),
?XAE("div",
[{"id", "navigation"}],
@@ -312,6 +312,7 @@ ul li #navhead a, ul li #navheadsub a, ul li #navheadsubsub a {
text-align: center;
border-top: 2px solid #d47911;
border-bottom: 1px solid #d47911;
+ background: #FED6A6;
}
#navheadsub, #navitemsub {
@@ -367,10 +368,6 @@ textarea {
border: 1px solid #d6760e;
color: #723202;
background-color: #fff2e8;
- vertical-align: middle;
- margin-top: 7px;
- margin-bottom: 5px;
- padding: 0.1em;
}
select {
@@ -538,6 +535,19 @@ div.guidelink {
padding-right: 1em;
}
+table.withtextareas>tbody>tr>td {
+ vertical-align: top;
+}
+
+p.result {
+ border: 1px;
+ border-style: dashed;
+ border-color: #FE8A02;
+ padding: 1em;
+ margin-right: 1em;
+ background: #FFE3C9;
+}
+
*.alignright {
font-size: 10pt;
}
@@ -633,6 +643,7 @@ process_admin(Host,
#request{path = ["acls-raw"],
q = Query,
lang = Lang}) ->
+
Res = case lists:keysearch("acls", 1, Query) of
{value, {_, String}} ->
case erl_scan:string(String) of
@@ -654,22 +665,17 @@ process_admin(Host,
_ ->
nothing
end,
- ACLs = lists:flatten(
- io_lib:format(
- "~p.", [lists:keysort(
- 2, ets:select(acl, [{{acl, {'$1', Host}, '$2'},
- [], [{{acl, '$1', '$2'}}]}]))])),
+ ACLs = lists:keysort(2, ets:select(acl, [{{acl, {'$1', Host}, '$2'},
+ [], [{{acl, '$1', '$2'}}]}])),
+ {NumLines, ACLsP} = term_to_paragraph(ACLs, 80),
make_xhtml(?H1GL(?T("Access Control Lists"), "ACLDefinition", "ACL Definition") ++
case Res of
- ok -> [?CT("Submitted"), ?P];
- error -> [?CT("Bad format"), ?P];
+ ok -> [?XREST("Submitted")];
+ error -> [?XREST("Bad format")];
nothing -> []
end ++
[?XAE("form", [{"action", ""}, {"method", "post"}],
- [?XAC("textarea", [{"name", "acls"},
- {"rows", "16"},
- {"cols", "80"}],
- ACLs),
+ [?TEXTAREA("acls", integer_to_list(lists:max([16, NumLines])), "80", ACLsP++"."),
?BR,
?INPUTT("submit", "submit", "Submit")
])
@@ -704,8 +710,8 @@ process_admin(Host,
[], [{{acl, '$1', '$2'}}]}])),
make_xhtml(?H1GL(?T("Access Control Lists"), "ACLDefinition", "ACL Definition") ++
case Res of
- ok -> [?CT("Submitted"), ?P];
- error -> [?CT("Bad format"), ?P];
+ ok -> [?XREST("Submitted")];
+ error -> [?XREST("Bad format")];
nothing -> []
end ++
[?XE("p", [?ACT("../acls-raw/", "Raw")])] ++
@@ -764,23 +770,19 @@ process_admin(Host,
nothing
end,
Access =
- lists:flatten(
- io_lib:format(
- "~p.", [ets:select(config,
+ ets:select(config,
[{{config, {access, '$1', Host}, '$2'},
[],
- [{{access, '$1', '$2'}}]}])])),
+ [{{access, '$1', '$2'}}]}]),
+ {NumLines, AccessP} = term_to_paragraph(Access, 80),
make_xhtml(?H1GL(?T("Access Rules"), "AccessRights", "Access Rights") ++
case Res of
- ok -> [?CT("Submitted"), ?P];
- error -> [?CT("Bad format"), ?P];
+ ok -> [?XREST("Submitted")];
+ error -> [?XREST("Bad format")];
nothing -> []
end ++
[?XAE("form", [{"action", ""}, {"method", "post"}],
- [?XAC("textarea", [{"name", "access"},
- {"rows", "16"},
- {"cols", "80"}],
- Access),
+ [?TEXTAREA("access", integer_to_list(lists:max([16, NumLines])), "80", AccessP++"."),
?BR,
?INPUTT("submit", "submit", "Submit")
])
@@ -810,8 +812,8 @@ process_admin(Host,
[{{access, '$1', '$2'}}]}]),
make_xhtml(?H1GL(?T("Access Rules"), "AccessRights", "Access Rights") ++
case Res of
- ok -> [?CT("Submitted"), ?P];
- error -> [?CT("Bad format"), ?P];
+ ok -> [?XREST("Submitted")];
+ error -> [?XREST("Bad format")];
nothing -> []
end ++
[?XE("p", [?ACT("../access-raw/", "Raw")])] ++
@@ -850,8 +852,8 @@ process_admin(Host,
make_xhtml([?XC("h1",
io_lib:format(?T("~s access rule configuration"), [SName]))] ++
case Res of
- ok -> [?CT("Submitted"), ?P];
- error -> [?CT("Bad format"), ?P];
+ ok -> [?XREST("Submitted")];
+ error -> [?XREST("Bad format")];
nothing -> []
end ++
[?XAE("form", [{"action", ""}, {"method", "post"}],
@@ -1054,12 +1056,20 @@ acl_spec_select(ID, Opt) ->
node_regexp, user_glob, server_glob, node_glob, all, raw]))]).
+%% @spec (T::any()) -> StringLine::string()
term_to_string(T) ->
StringParagraph = lists:flatten(io_lib:format("~1000000p", [T])),
%% Remove from the string all the carriage returns characters
{ok, StringLine, _} = regexp:gsub(StringParagraph, "\\n ", ""),
StringLine.
+%% @spec (T::any()) -> {NumLines::integer(), Paragraph::string()}
+term_to_paragraph(T, Cols) ->
+ Paragraph = erl_prettypr:format(erl_syntax:abstract(T), [{paper, Cols}]),
+ {ok, FieldList} = regexp:split(Paragraph, "\n"),
+ NumLines = length(FieldList),
+ {NumLines, Paragraph}.
+
term_to_id(T) ->
jlib:encode_base64(binary_to_list(term_to_binary(T))).
@@ -1227,7 +1237,7 @@ access_rule_to_xhtml(Rules) ->
fun({Access, ACL} = _Rule) ->
SAccess = element_to_list(Access),
SACL = atom_to_list(ACL),
- SAccess ++ "\t" ++ SACL ++ "\n"
+ SAccess ++ "\s\t" ++ SACL ++ "\n"
end, Rules),
?XAC("textarea", [{"name", "rules"},
{"rows", "16"},
@@ -1304,8 +1314,8 @@ list_users(Host, Query, Lang, URLFunc) ->
end, lists:seq(1, N, M))
end,
case Res of
- ok -> [?CT("Submitted"), ?P];
- error -> [?CT("Bad format"), ?P];
+ ok -> [?XREST("Submitted")];
+ error -> [?XREST("Bad format")];
nothing -> []
end ++
[?XAE("form", [{"action", ""}, {"method", "post"}],
@@ -1500,8 +1510,8 @@ user_info(User, Server, Query, Lang) ->
[User, Server, Lang]),
[?XC("h1", ?T("User ") ++ us_to_list(US))] ++
case Res of
- ok -> [?CT("Submitted"), ?P];
- error -> [?CT("Bad format"), ?P];
+ ok -> [?XREST("Submitted")];
+ error -> [?XREST("Bad format")];
nothing -> []
end ++
[?XAE("form", [{"action", ""}, {"method", "post"}],
@@ -1668,8 +1678,8 @@ get_node(global, Node, [], Query, Lang) ->
MenuItems2 = make_menu_items(global, Node, Base, Lang),
[?XC("h1", ?T("Node ") ++ atom_to_list(Node))] ++
case Res of
- ok -> [?CT("Submitted"), ?P];
- error -> [?CT("Bad format"), ?P];
+ ok -> [?XREST("Submitted")];
+ error -> [?XREST("Bad format")];
nothing -> []
end ++
[?XE("ul",
@@ -1698,7 +1708,10 @@ get_node(global, Node, ["db"], Query, Lang) ->
{badrpc, _Reason} ->
[?XCT("h1", "RPC Call Error")];
Tables ->
- node_db_parse_query(Node, Tables, Query),
+ ResS = case node_db_parse_query(Node, Tables, Query) of
+ nothing -> [];
+ ok -> [?XREST("Submitted")]
+ end,
STables = lists:sort(Tables),
Rows = lists:map(
fun(Table) ->
@@ -1735,7 +1748,7 @@ get_node(global, Node, ["db"], Query, Lang) ->
])
end, STables),
[?XC("h1", ?T("Database Tables at ") ++ atom_to_list(Node))] ++
- [?CT("Submitted"), ?P] ++
+ ResS ++
[?XAE("form", [{"action", ""}, {"method", "post"}],
[?XAE("table", [],
[?XE("thead",
@@ -1757,9 +1770,14 @@ get_node(global, Node, ["db"], Query, Lang) ->
end;
get_node(global, Node, ["backup"], Query, Lang) ->
- _Res = node_backup_parse_query(Node, Query),
- [?XC("h1", ?T("Backup of ") ++ atom_to_list(Node)),
- ?XCT("p", "Remark that these options will only backup the builtin Mnesia database. If you are using the ODBC module, you also need to backup your SQL database separately."),
+ ResS = case node_backup_parse_query(Node, Query) of
+ nothing -> [];
+ ok -> [?XREST("Submitted")];
+ {error, Error} -> [?XRES(?T("Error") ++": " ++ io_lib:format("~p", [Error]))]
+ end,
+ [?XC("h1", ?T("Backup of ") ++ atom_to_list(Node))] ++
+ ResS ++
+ [?XCT("p", "Remark that these options will only backup the builtin Mnesia database. If you are using the ODBC module, you also need to backup your SQL database separately."),
?XAE("form", [{"action", ""}, {"method", "post"}],
[?XAE("table", [],
[?XE("tbody",
@@ -1822,9 +1840,9 @@ get_node(global, Node, ["ports"], Query, Lang) ->
H1String = ?T("Listened Ports at ") ++ atom_to_list(Node),
?H1GL(H1String, "listened", "Listening Ports") ++
case Res of
- ok -> [?CT("Submitted"), ?P];
- error -> [?CT("Bad format"), ?P];
- {error, ReasonT} -> [?CT("Problem: "), ?C(ReasonT), ?P];
+ ok -> [?XREST("Submitted")];
+ error -> [?XREST("Bad format")];
+ {error, ReasonT} -> [?XRES(?T("Error") ++ ": " ++ ReasonT)];
nothing -> []
end ++
[?XAE("form", [{"action", ""}, {"method", "post"}],
@@ -1847,8 +1865,8 @@ get_node(Host, Node, ["modules"], Query, Lang) when is_list(Host) ->
H1String = ?T("Modules at ") ++ atom_to_list(Node),
?H1GL(H1String, "modoverview", "Modules Overview") ++
case Res of
- ok -> [?CT("Submitted"), ?P];
- error -> [?CT("Bad format"), ?P];
+ ok -> [?XREST("Submitted")];
+ error -> [?XREST("Bad format")];
nothing -> []
end ++
[?XAE("form", [{"action", ""}, {"method", "post"}],
@@ -1916,17 +1934,19 @@ get_node(global, Node, ["update"], Query, Lang) ->
FmtLowLevelScript = ?XC("pre", io_lib:format("~p", [LowLevelScript])),
[?XC("h1", ?T("Update ") ++ atom_to_list(Node))] ++
case Res of
- ok -> [?CT("Submitted"), ?P];
- error -> [?CT("Bad format"), ?P];
+ ok -> [?XREST("Submitted")];
+ error -> [?XREST("Bad format")];
nothing -> []
end ++
[?XAE("form", [{"action", ""}, {"method", "post"}],
- [?INPUTT("submit", "update", "Update"),
+ [
?XCT("h2", "Update plan"),
- ?XCT("h3", "Updated modules"), Mods,
+ ?XCT("h3", "Modified modules"), Mods,
?XCT("h3", "Update script"), FmtScript,
?XCT("h3", "Low level update script"), FmtLowLevelScript,
- ?XCT("h3", "Script check"), ?C(atom_to_list(Check))])
+ ?XCT("h3", "Script check"), ?XC("pre", atom_to_list(Check)),
+ ?INPUTT("submit", "update", "Update")
+ ])
];
get_node(Host, Node, NPath, Query, Lang) ->
@@ -1981,6 +2001,8 @@ db_storage_select(ID, Opt, Lang) ->
{disc_only_copies, "Disc only copy"},
{unknown, "Remote copy"}])).
+node_db_parse_query(_Node, _Tables, [{nokey,[]}]) ->
+ nothing;
node_db_parse_query(Node, Tables, Query) ->
lists:foreach(
fun(Table) ->
@@ -2014,6 +2036,8 @@ node_db_parse_query(Node, Tables, Query) ->
end, Tables),
ok.
+node_backup_parse_query(_Node, [{nokey,[]}]) ->
+ nothing;
node_backup_parse_query(Node, Query) ->
lists:foldl(
fun(Action, nothing) ->
@@ -2040,15 +2064,15 @@ node_backup_parse_query(Node, Query) ->
load_textfile, [Path])
end,
case Res of
- {error, _Reason} ->
- error;
- {badrpc, _Reason} ->
- error;
+ {error, Reason} ->
+ {error, Reason};
+ {badrpc, Reason} ->
+ {badrpc, Reason};
_ ->
ok
end;
- _ ->
- error
+ OtherError ->
+ {error, OtherError}
end;
_ ->
nothing
@@ -2059,7 +2083,7 @@ node_backup_parse_query(Node, Query) ->
node_ports_to_xhtml(Ports, Lang) ->
- ?XAE("table", [],
+ ?XAE("table", [{"class", "withtextareas"}],
[?XE("thead",
[?XE("tr",
[?XCT("td", "Port"),
@@ -2073,14 +2097,14 @@ node_ports_to_xhtml(Ports, Lang) ->
{_Port, SPort, _TIP, SIP, SSPort, OptsClean} =
get_port_data(PortIP, Opts),
SModule = atom_to_list(Module),
+ {NumLines, SOptsClean} = term_to_paragraph(OptsClean, 40),
%%ID = term_to_id(E),
?XE("tr",
[?XAE("td", [{"size", "6"}], [?C(SPort)]),
?XAE("td", [{"size", "15"}], [?C(SIP)]),
?XE("td", [?INPUTS("text", "module" ++ SSPort,
SModule, "15")]),
- ?XE("td", [?INPUTS("text", "opts" ++ SSPort,
- term_to_string(OptsClean), "40")]),
+ ?XE("td", [?TEXTAREA("opts" ++ SSPort, integer_to_list(NumLines), "35", SOptsClean)]),
?XE("td", [?INPUTT("submit", "add" ++ SSPort,
"Update")]),
?XE("td", [?INPUTT("submit", "delete" ++ SSPort,
@@ -2091,8 +2115,8 @@ node_ports_to_xhtml(Ports, Lang) ->
[?XE("tr",
[?XE("td", [?INPUTS("text", "portnew", "", "6")]),
?XE("td", [?INPUTS("text", "ipnew", "0.0.0.0", "15")]),
- ?XE("td", [?INPUTS("text", "modulenew", "", "17")]),
- ?XE("td", [?INPUTS("text", "optsnew", "[]", "40")]),
+ ?XE("td", [?INPUTS("text", "modulenew", "", "15")]),
+ ?XE("td", [?TEXTAREA("optsnew", "2", "35", "[]")]),
?XAE("td", [{"colspan", "2"}],
[?INPUTT("submit", "addnew", "Add New")])
]
@@ -2170,7 +2194,7 @@ node_ports_parse_query(Node, Ports, Query) ->
end.
node_modules_to_xhtml(Modules, Lang) ->
- ?XAE("table", [],
+ ?XAE("table", [{"class", "withtextareas"}],
[?XE("thead",
[?XE("tr",
[?XCT("td", "Module"),
@@ -2180,11 +2204,11 @@ node_modules_to_xhtml(Modules, Lang) ->
lists:map(
fun({Module, Opts} = _E) ->
SModule = atom_to_list(Module),
+ {NumLines, SOpts} = term_to_paragraph(Opts, 40),
%%ID = term_to_id(E),
?XE("tr",
[?XC("td", SModule),
- ?XE("td", [?INPUTS("text", "opts" ++ SModule,
- term_to_string(Opts), "40")]),
+ ?XE("td", [?TEXTAREA("opts" ++ SModule, integer_to_list(NumLines), "40", SOpts)]),
?XE("td", [?INPUTT("submit", "restart" ++ SModule,
"Restart")]),
?XE("td", [?INPUTT("submit", "stop" ++ SModule,
@@ -2194,7 +2218,7 @@ node_modules_to_xhtml(Modules, Lang) ->
end, Modules) ++
[?XE("tr",
[?XE("td", [?INPUT("text", "modulenew", "")]),
- ?XE("td", [?INPUTS("text", "optsnew", "", "40")]),
+ ?XE("td", [?TEXTAREA("optsnew", "2", "40", "[]")]),
?XAE("td", [{"colspan", "2"}],
[?INPUTT("submit", "start", "Start")])
]
@@ -2437,11 +2461,11 @@ make_menu_items2(Lang, Deep, {MURI, MName, [Item | Items]}, Res) ->
make_menu_items2(Lang, Deep, {MURI, MName, Items}, Res2).
make_menu_item(header, 1, URI, Name, _Lang) ->
- ?LI([?XAE("div", [{"id", "navhead"}], [?AC(URI, "~ "++Name++" ~")] )]);
+ ?LI([?XAE("div", [{"id", "navhead"}], [?AC(URI, Name)] )]);
make_menu_item(header, 2, URI, Name, _Lang) ->
- ?LI([?XAE("div", [{"id", "navheadsub"}], [?AC(URI, "~ "++Name++" ~")] )]);
+ ?LI([?XAE("div", [{"id", "navheadsub"}], [?AC(URI, Name)] )]);
make_menu_item(header, 3, URI, Name, _Lang) ->
- ?LI([?XAE("div", [{"id", "navheadsubsub"}], [?AC(URI, "~ "++Name++" ~")] )]);
+ ?LI([?XAE("div", [{"id", "navheadsubsub"}], [?AC(URI, Name)] )]);
make_menu_item(item, 1, URI, Name, Lang) ->
?LI([?XAE("div", [{"id", "navitem"}], [?ACT(URI, Name)] )]);
make_menu_item(item, 2, URI, Name, Lang) ->
diff --git a/src/web/ejabberd_web_admin.hrl b/src/web/ejabberd_web_admin.hrl
index d197e3ab..2bf164e0 100644
--- a/src/web/ejabberd_web_admin.hrl
+++ b/src/web/ejabberd_web_admin.hrl
@@ -51,6 +51,16 @@
-define(INPUTST(Type, Name, Value, Size), ?INPUT(Type, Name, ?T(Value), Size)).
-define(ACLINPUT(Text), ?XE("td", [?INPUT("text", "value" ++ ID, Text)])).
+-define(TEXTAREA(Name, Rows, Cols, Value),
+ ?XAC("textarea", [{"name", Name},
+ {"rows", Rows},
+ {"cols", Cols}],
+ Value)).
+
+%% Build an xmlelement for result
+-define(XRES(Text), ?XAC("p", [{"class", "result"}], Text)).
+-define(XREST(Text), ?XRES(?T(Text))).
+
%% Guide Link
-define(GL(Ref, Title),
?XAE("div",