]> granicus.if.org Git - ejabberd/commitdiff
Improve extraction of translated strings
authorEvgeny Khramtsov <ekhramtsov@process-one.net>
Sat, 22 Jun 2019 14:08:45 +0000 (17:08 +0300)
committerEvgeny Khramtsov <ekhramtsov@process-one.net>
Sat, 22 Jun 2019 14:08:45 +0000 (17:08 +0300)
Now every such string MUST be encapsulated into ?T() macro.
The macro itself is defined in include/translate.hrl.
Example:

-module(foo).
-export([bar/1]).
-include("translate.hrl").

bar(Lang) ->
    translate:translate(Lang, ?T("baz")).

56 files changed:
include/ejabberd_web_admin.hrl
src/ejabberd_c2s.erl
src/ejabberd_captcha.erl
src/ejabberd_local.erl
src/ejabberd_oauth.erl
src/ejabberd_s2s.erl
src/ejabberd_s2s_out.erl
src/ejabberd_service.erl
src/ejabberd_sm.erl
src/ejabberd_web_admin.erl
src/gen_iq_handler.erl
src/mod_adhoc.erl
src/mod_announce.erl
src/mod_block_strangers.erl
src/mod_blocking.erl
src/mod_carboncopy.erl
src/mod_configure.erl
src/mod_delegation.erl
src/mod_disco.erl
src/mod_fail2ban.erl
src/mod_http_upload.erl
src/mod_last.erl
src/mod_legacy_auth.erl
src/mod_mam.erl
src/mod_mix.erl
src/mod_mix_pam.erl
src/mod_muc.erl
src/mod_muc_admin.erl
src/mod_muc_log.erl
src/mod_muc_room.erl
src/mod_multicast.erl
src/mod_offline.erl
src/mod_ping.erl
src/mod_privacy.erl
src/mod_private.erl
src/mod_privilege.erl
src/mod_proxy65_service.erl
src/mod_pubsub.erl
src/mod_push.erl
src/mod_register.erl
src/mod_register_web.erl
src/mod_roster.erl
src/mod_s2s_dialback.erl
src/mod_shared_roster.erl
src/mod_sic.erl
src/mod_stats.erl
src/mod_stream_mgmt.erl
src/mod_time.erl
src/mod_vcard.erl
src/mod_version.erl
src/node_flat_sql.erl
src/nodetree_tree.erl
src/nodetree_tree_sql.erl
src/pubsub_subscription.erl
src/pubsub_subscription_sql.erl
tools/extract-tr.sh

index 477ee97a22c2d9828e9ca397199477f7107e0fd0..9700ab0b349707309f6dee270ea9fda25fcc5102 100644 (file)
 -define(XAC(Name, Attrs, Text),
        ?XAE(Name, Attrs, [?C(Text)])).
 
--define(T(Text), translate:translate(Lang, Text)).
+-define(CT(Text), ?C((translate:translate(Lang, Text)))).
 
--define(CT(Text), ?C((?T(Text)))).
-
--define(XCT(Name, Text), ?XC(Name, (?T(Text)))).
+-define(XCT(Name, Text), ?XC(Name, (translate:translate(Lang, Text)))).
 
 -define(XACT(Name, Attrs, Text),
-       ?XAC(Name, Attrs, (?T(Text)))).
+       ?XAC(Name, Attrs, (translate:translate(Lang, Text)))).
 
 -define(LI(Els), ?XE(<<"li">>, Els)).
 
@@ -53,7 +51,7 @@
 
 -define(AC(URL, Text), ?A(URL, [?C(Text)])).
 
--define(ACT(URL, Text), ?AC(URL, (?T(Text)))).
+-define(ACT(URL, Text), ?AC(URL, (translate:translate(Lang, Text)))).
 
 -define(P, ?X(<<"p">>)).
 
@@ -65,7 +63,7 @@
             {<<"value">>, Value}])).
 
 -define(INPUTT(Type, Name, Value),
-       ?INPUT(Type, Name, (?T(Value)))).
+       ?INPUT(Type, Name, (translate:translate(Lang, Value)))).
 
 -define(INPUTS(Type, Name, Value, Size),
        ?XA(<<"input">>,
@@ -73,7 +71,7 @@
             {<<"value">>, Value}, {<<"size">>, Size}])).
 
 -define(INPUTST(Type, Name, Value, Size),
-       ?INPUT(Type, Name, (?T(Value)), Size)).
+       ?INPUT(Type, Name, (translate:translate(Lang, Value)), Size)).
 
 -define(ACLINPUT(Text),
        ?XE(<<"td">>,
@@ -90,7 +88,7 @@
        ?XAC(<<"p">>, [{<<"class">>, <<"result">>}], Text)).
 
 %% Guide Link
--define(XREST(Text), ?XRES((?T(Text)))).
+-define(XREST(Text), ?XRES((translate:translate(Lang, Text)))).
 
 -define(GL(Ref, Title),
        ?XAE(<<"div">>, [{<<"class">>, <<"guidelink">>}],
index 820e9bbf72dcac509faa29878268f73a62e77aa3..63c36263f5553859ac4e2a169673dedccdc42c9b 100644 (file)
@@ -52,6 +52,7 @@
 -include("xmpp.hrl").
 -include("logger.hrl").
 -include("mod_roster.hrl").
+-include("translate.hrl").
 
 -define(SETS, gb_sets).
 
@@ -431,7 +432,7 @@ bind(R, #{user := U, server := S, access := Access, lang := Lang,
                    ejabberd_hooks:run(forbidden_session_hook, LServer, [JID]),
                    ?WARNING_MSG("(~s) Forbidden c2s session for ~s",
                                 [xmpp_socket:pp(Socket), jid:encode(JID)]),
-                   Txt = <<"Access denied by service policy">>,
+                   Txt = ?T("Access denied by service policy"),
                    {error, xmpp:err_not_allowed(Txt, Lang), State}
            end
     end.
@@ -670,7 +671,7 @@ process_presence_out(#{lserver := LServer, jid := JID,
                MyBareJID = jid:remove_resource(JID),
                case acl:match_rule(LServer, Access, MyBareJID) of
                    deny ->
-                       AccessErrTxt = <<"Access denied by service policy">>,
+                       AccessErrTxt = ?T("Access denied by service policy"),
                        AccessErr = xmpp:err_forbidden(AccessErrTxt, Lang),
                        send_error(State0, Pres, AccessErr);
                    allow ->
@@ -682,8 +683,8 @@ process_presence_out(#{lserver := LServer, jid := JID,
        end,
     case privacy_check_packet(State1, Pres, out) of
        deny ->
-           PrivErrTxt = <<"Your active privacy list has denied "
-                          "the routing of this stanza.">>,
+           PrivErrTxt = ?T("Your active privacy list has denied "
+                           "the routing of this stanza."),
            PrivErr = xmpp:err_not_acceptable(PrivErrTxt, Lang),
            send_error(State1, Pres, PrivErr);
        allow when Type == subscribe; Type == subscribed;
@@ -827,8 +828,8 @@ broadcast_presence_available(#{jid := JID} = State,
 check_privacy_then_route(#{lang := Lang} = State, Pkt) ->
     case privacy_check_packet(State, Pkt, out) of
         deny ->
-            ErrText = <<"Your active privacy list has denied "
-                       "the routing of this stanza.">>,
+            ErrText = ?T("Your active privacy list has denied "
+                        "the routing of this stanza."),
            Err = xmpp:err_not_acceptable(ErrText, Lang),
            send_error(State, Pkt, Err);
         allow ->
index e121163858a41d58259fbb014db3e275579630fb..2271a3bf9ff8e62a49ce5321b768a114d03def3f 100644 (file)
@@ -45,6 +45,7 @@
 -include("xmpp.hrl").
 -include("logger.hrl").
 -include("ejabberd_http.hrl").
+-include("translate.hrl").
 
 -define(CAPTCHA_LIFETIME, 120000).
 -define(LIMIT_PERIOD, 60*1000*1000).
@@ -67,7 +68,7 @@ start_link() ->
 
 -spec captcha_text(binary()) -> binary().
 captcha_text(Lang) ->
-    translate:translate(Lang, <<"Enter the text you see">>).
+    translate:translate(Lang, ?T("Enter the text you see")).
 
 -spec mk_ocr_field(binary(), binary(), binary()) -> xdata_field().
 mk_ocr_field(Lang, CID, Type) ->
@@ -100,8 +101,8 @@ create_captcha(SID, From, To, Lang, Limiter, Args) ->
                mk_ocr_field(Lang, CID, Type)],
          X = #xdata{type = form, fields = Fs},
          Captcha = #xcaptcha{xdata = X},
-          BodyString = {<<"Your subscription request and/or messages to ~s have been blocked. "
-                         "To unblock your subscription request, visit ~s">>, [JID, get_url(Id)]},
+          BodyString = {?T("Your subscription request and/or messages to ~s have been blocked. "
+                          "To unblock your subscription request, visit ~s"), [JID, get_url(Id)]},
          Body = xmpp:mk_text(BodyString, Lang),
          OOB = #oob_x{url = get_url(Id)},
          Hint = #hint{type = 'no-store'},
@@ -123,8 +124,8 @@ create_captcha_x(SID, To, Lang, Limiter, #xdata{fields = Fs} = X) ->
          CID = <<"sha1+", (str:sha(Image))/binary, "@bob.xmpp.org">>,
          Data = #bob_data{cid = CID, 'max-age' = 0, type = Type, data = Image},
          HelpTxt = translate:translate(Lang,
-                                       <<"If you don't see the CAPTCHA image here, "
-                                         "visit the web page.">>),
+                                       ?T("If you don't see the CAPTCHA image here, "
+                                          "visit the web page.")),
          Imageurl = get_url(<<Id/binary, "/image">>),
          NewFs = [mk_field(hidden, <<"FORM_TYPE">>, ?NS_CAPTCHA)|Fs] ++
                [#xdata_field{type = fixed, var = <<"captcha-fallback-text">>, values = [HelpTxt]},
@@ -132,7 +133,7 @@ create_captcha_x(SID, To, Lang, Limiter, #xdata{fields = Fs} = X) ->
                              values = [<<"workaround-for-psi">>]},
                 #xdata_field{type = 'text-single', var = <<"captcha-fallback-url">>,
                              label = translate:translate(
-                                       Lang, <<"CAPTCHA web page">>),
+                                       Lang, ?T("CAPTCHA web page")),
                              values = [Imageurl]},
                 mk_field(hidden, <<"from">>, jid:encode(To)),
                 mk_field(hidden, <<"challenge">>, Id),
@@ -189,7 +190,7 @@ build_captcha_html(Id, Lang) ->
                                      attrs =
                                          [{<<"type">>, <<"submit">>},
                                           {<<"name">>, <<"enter">>},
-                                          {<<"value">>, <<"OK">>}],
+                                          {<<"value">>, ?T("OK")}],
                                      children = []}]},
          {FormEl, {ImgEl, Text, IdEl, KeyEl}};
       _ -> captcha_not_found
@@ -220,17 +221,17 @@ process_iq(#iq{type = set, lang = Lang, sub_els = [#xcaptcha{} = El]} = IQ) ->
        ok ->
            xmpp:make_iq_result(IQ);
        {error, malformed} ->
-           Txt = <<"Incorrect CAPTCHA submit">>,
+           Txt = ?T("Incorrect CAPTCHA submit"),
            xmpp:make_error(IQ, xmpp:err_bad_request(Txt, Lang));
        {error, _} ->
-           Txt = <<"The CAPTCHA verification has failed">>,
+           Txt = ?T("The CAPTCHA verification has failed"),
            xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang))
     end;
 process_iq(#iq{type = get, lang = Lang} = IQ) ->
-    Txt = <<"Value 'get' of 'type' attribute is not allowed">>,
+    Txt = ?T("Value 'get' of 'type' attribute is not allowed"),
     xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang));
 process_iq(#iq{lang = Lang} = IQ) ->
-    Txt = <<"No module is handling this query">>,
+    Txt = ?T("No module is handling this query"),
     xmpp:make_error(IQ, xmpp:err_service_unavailable(Txt, Lang)).
 
 process(_Handlers,
@@ -272,7 +273,7 @@ process(_Handlers,
                        children =
                            [{xmlcdata,
                              translate:translate(Lang,
-                                                 <<"The CAPTCHA is valid.">>)}]},
+                                                 ?T("The CAPTCHA is valid."))}]},
          ejabberd_web:make_xhtml([Form]);
       captcha_non_valid -> ejabberd_web:error(not_allowed);
       captcha_not_found -> ejabberd_web:error(not_found)
index 3b7c0f4f27b8be97a16d124dbaef6507d8249f3d..6b530ec1bb6d9f325c7e8f6866487c9a269b7305 100644 (file)
@@ -49,6 +49,7 @@
 -include_lib("stdlib/include/ms_transform.hrl").
 -include("xmpp.hrl").
 -include("ejabberd_stacktrace.hrl").
+-include("translate.hrl").
 
 -record(state, {}).
 
@@ -91,7 +92,7 @@ bounce_resource_packet(#message{to = #jid{lresource = <<"">>}, type = headline})
     ok;
 bounce_resource_packet(Packet) ->
     Lang = xmpp:get_lang(Packet),
-    Txt = <<"No available resource found">>,
+    Txt = ?T("No available resource found"),
     Err = xmpp:err_item_not_found(Txt, Lang),
     ejabberd_router:route_error(Packet, Err),
     stop.
index 1d03626e7d67dc5eb0d14b6656133c6056fb9179..55a414f15057e7aca863af8e9e2787a79b54c30c 100644 (file)
         oauth_issue_token/3, oauth_list_tokens/0, oauth_revoke_token/1]).
 
 -include("xmpp.hrl").
-
 -include("logger.hrl").
-
 -include("ejabberd_http.hrl").
 -include("ejabberd_web_admin.hrl").
 -include("ejabberd_oauth.hrl").
-
 -include("ejabberd_commands.hrl").
+-include("translate.hrl").
 
 -callback init() -> any().
 -callback store(#oauth_token{}) -> ok | {error, any()}.
@@ -393,10 +391,10 @@ process(_Handlers,
         ?XAE(<<"form">>,
              [{<<"action">>, <<"authorization_token">>},
               {<<"method">>, <<"post">>}],
-             [?LABEL(<<"username">>, [?CT(<<"User (jid)">>), ?C(<<": ">>)]),
+             [?LABEL(<<"username">>, [?CT(?T("User (jid)")), ?C(<<": ">>)]),
               ?INPUTID(<<"text">>, <<"username">>, <<"">>),
               ?BR,
-              ?LABEL(<<"password">>, [?CT(<<"Password">>), ?C(<<": ">>)]),
+              ?LABEL(<<"password">>, [?CT(?T("Password")), ?C(<<": ">>)]),
               ?INPUTID(<<"password">>, <<"password">>, <<"">>),
               ?INPUT(<<"hidden">>, <<"response_type">>, ResponseType),
               ?INPUT(<<"hidden">>, <<"client_id">>, ClientId),
@@ -404,7 +402,7 @@ process(_Handlers,
               ?INPUT(<<"hidden">>, <<"scope">>, Scope),
               ?INPUT(<<"hidden">>, <<"state">>, State),
               ?BR,
-              ?LABEL(<<"ttl">>, [?CT(<<"Token TTL">>), ?C(<<": ">>)]),
+              ?LABEL(<<"ttl">>, [?CT(?T("Token TTL")), ?C(<<": ">>)]),
               ?XAE(<<"select">>, [{<<"name">>, <<"ttl">>}],
                    [
                    ?XAC(<<"option">>, [{<<"value">>, <<"3600">>}],<<"1 Hour">>),
@@ -413,7 +411,7 @@ process(_Handlers,
                    ?XAC(<<"option">>, [{<<"selected">>, <<"selected">>},{<<"value">>, <<"31536000">>}],<<"1 Year">>),
                    ?XAC(<<"option">>, [{<<"value">>, <<"315360000">>}],<<"10 Years">>)]),
               ?BR,
-              ?INPUTT(<<"submit">>, <<"">>, <<"Accept">>)
+              ?INPUTT(<<"submit">>, <<"">>, ?T("Accept"))
              ]),
     Top =
         ?DIV(<<"section">>,
index 4a56191ffbfe626789674b1ef76a7ba888b1ca84..f499e82c252c535a737709eaffd77133dfe0f71a 100644 (file)
@@ -56,6 +56,7 @@
 -include("ejabberd_commands.hrl").
 -include_lib("public_key/include/public_key.hrl").
 -include("ejabberd_stacktrace.hrl").
+-include("translate.hrl").
 
 -define(PKIXEXPLICIT, 'OTP-PUB-KEY').
 
@@ -361,10 +362,10 @@ do_route(Packet) ->
            Err = case Reason of
                      policy_violation ->
                          xmpp:err_policy_violation(
-                           <<"Server connections to local "
-                             "subdomains are forbidden">>, Lang);
+                           ?T("Server connections to local "
+                              "subdomains are forbidden"), Lang);
                      forbidden ->
-                         xmpp:err_forbidden(<<"Access denied by service policy">>, Lang);
+                         xmpp:err_forbidden(?T("Access denied by service policy"), Lang);
                      internal_server_error ->
                          xmpp:err_internal_server_error()
                  end,
index 818d16a5f50a991f17b915c88fc1bf6be30ca34b..7d71cb38bc7edc508cd338550a96bf5d33e6359c 100644 (file)
@@ -43,6 +43,7 @@
 
 -include("xmpp.hrl").
 -include("logger.hrl").
+-include("translate.hrl").
 
 -type state() :: xmpp_stream_out:state().
 -export_type([state/0]).
@@ -251,7 +252,7 @@ handle_timeout(#{on_route := Action, lang := Lang} = State) ->
     case Action of
        bounce -> stop(State);
        _ ->
-           Txt = <<"Idle connection">>,
+           Txt = ?T("Idle connection"),
            send(State, xmpp:serr_connection_timeout(Txt, Lang))
     end.
 
index 2710422a5d9d1fb70725b35803e3eb502f3b5bc2..8e29577c89c141b506eac7d492f630e851102f21 100644 (file)
@@ -37,6 +37,7 @@
 
 -include("xmpp.hrl").
 -include("logger.hrl").
+-include("translate.hrl").
 
 -type state() :: xmpp_stream_in:state().
 -export_type([state/0]).
@@ -119,7 +120,7 @@ handle_stream_start(_StreamStart,
                      host_opts := HostOpts} = State) ->
     case ejabberd_router:is_my_host(RemoteServer) of
        true ->
-           Txt = <<"Unable to register route on existing local domain">>,
+           Txt = ?T("Unable to register route on existing local domain"),
            xmpp_stream_in:send(State, xmpp:serr_conflict(Txt, Lang));
        false ->
            NewHostOpts = case dict:is_key(RemoteServer, HostOpts) of
@@ -198,7 +199,7 @@ handle_authenticated_packet(Pkt0, #{ip := {IP, _}, lang := Lang} = State)
                end,
         State2;
        false ->
-           Txt = <<"Improper domain part of 'from' attribute">>,
+           Txt = ?T("Improper domain part of 'from' attribute"),
            Err = xmpp:serr_invalid_from(Txt, Lang),
            xmpp_stream_in:send(State, Err)
     end;
@@ -211,7 +212,7 @@ handle_info({route, Packet}, #{access := Access} = State) ->
            xmpp_stream_in:send(State, Packet);
        deny ->
            Lang = xmpp:get_lang(Packet),
-           Err = xmpp:err_not_allowed(<<"Access denied by service policy">>, Lang),
+           Err = xmpp:err_not_allowed(?T("Access denied by service policy"), Lang),
            ejabberd_router:route_error(Packet, Err),
            State
     end;
index f0a10e5fad7ac7d7478f8c6bd169c94927bb4988..69e8fcba2e860b6b248fddf6153938a4ec5833a8 100644 (file)
         handle_info/2, terminate/2, code_change/3]).
 
 -include("logger.hrl").
-
 -include("xmpp.hrl").
-
 -include("ejabberd_commands.hrl").
 -include("ejabberd_sm.hrl").
 -include("ejabberd_stacktrace.hrl").
+-include("translate.hrl").
 
 -callback init() -> ok | {error, any()}.
 -callback set_session(#session{}) -> ok | {error, any()}.
@@ -200,7 +199,7 @@ bounce_offline_message(Acc) ->
 -spec bounce_sm_packet({bounce | term(), stanza()}) -> any().
 bounce_sm_packet({bounce, Packet} = Acc) ->
     Lang = xmpp:get_lang(Packet),
-    Txt = <<"User session not found">>,
+    Txt = ?T("User session not found"),
     Err = xmpp:err_service_unavailable(Txt, Lang),
     ejabberd_router:route_error(Packet, Err),
     {stop, Acc};
@@ -212,7 +211,7 @@ bounce_sm_packet({_, Packet} = Acc) ->
 -spec disconnect_removed_user(binary(), binary()) -> ok.
 
 disconnect_removed_user(User, Server) ->
-    route(jid:make(User, Server), {exit, <<"User removed">>}).
+    route(jid:make(User, Server), {exit, ?T("User removed")}).
 
 get_user_resources(User, Server) ->
     LUser = jid:nodeprep(User),
@@ -442,10 +441,10 @@ get_vh_session_number(Server) ->
 %% Why the hell do we have so many similar kicks?
 c2s_handle_info(#{lang := Lang} = State, replaced) ->
     State1 = State#{replaced => true},
-    Err = xmpp:serr_conflict(<<"Replaced by new connection">>, Lang),
+    Err = xmpp:serr_conflict(?T("Replaced by new connection"), Lang),
     {stop, ejabberd_c2s:send(State1, Err)};
 c2s_handle_info(#{lang := Lang} = State, kick) ->
-    Err = xmpp:serr_policy_violation(<<"has been kicked">>, Lang),
+    Err = xmpp:serr_policy_violation(?T("has been kicked"), Lang),
     c2s_handle_info(State, {kick, kicked_by_admin, Err});
 c2s_handle_info(State, {kick, _Reason, Err}) ->
     {stop, ejabberd_c2s:send(State, Err)};
index 5eaef7582ce7b0a876bff5c689ca1af1d759d08a..256920c25d9a04d0bc98fd3a31f759b5e5958af2 100644 (file)
@@ -41,6 +41,8 @@
 
 -include("ejabberd_web_admin.hrl").
 
+-include("translate.hrl").
+
 -define(INPUTATTRS(Type, Name, Value, Attrs),
        ?XA(<<"input">>,
            (Attrs ++
@@ -191,7 +193,7 @@ process([<<"server">>, SHost | RPath] = Path,
                 [{<<"WWW-Authenticate">>,
                   <<"basic realm=\"ejabberd\"">>}],
                 ejabberd_web:make_xhtml([?XCT(<<"h1">>,
-                                              <<"Unauthorized">>)])};
+                                              ?T("Unauthorized"))])};
            {unauthorized, Error} ->
                {BadUser, _BadPass} = Auth,
                {IPT, _Port} = Request#request.ip,
@@ -203,7 +205,7 @@ process([<<"server">>, SHost | RPath] = Path,
                   <<"basic realm=\"auth error, retry login "
                     "to ejabberd\"">>}],
                 ejabberd_web:make_xhtml([?XCT(<<"h1">>,
-                                              <<"Unauthorized">>)])}
+                                              ?T("Unauthorized"))])}
          end;
       false -> ejabberd_web:error(not_found)
     end;
@@ -223,7 +225,7 @@ process(RPath,
           [{<<"WWW-Authenticate">>,
             <<"basic realm=\"ejabberd\"">>}],
           ejabberd_web:make_xhtml([?XCT(<<"h1">>,
-                                        <<"Unauthorized">>)])};
+                                        ?T("Unauthorized"))])};
       {unauthorized, Error} ->
          {BadUser, _BadPass} = Auth,
          {IPT, _Port} = Request#request.ip,
@@ -235,7 +237,7 @@ process(RPath,
             <<"basic realm=\"auth error, retry login "
               "to ejabberd\"">>}],
           ejabberd_web:make_xhtml([?XCT(<<"h1">>,
-                                        <<"Unauthorized">>)])}
+                                        ?T("Unauthorized"))])}
     end.
 
 get_auth_admin(Auth, HostHTTP, RPath, Method) ->
@@ -294,7 +296,7 @@ make_xhtml(Els, Host, Node, Lang, JID) ->
            children =
                [#xmlel{name = <<"head">>, attrs = [],
                        children =
-                           [?XCT(<<"title">>, <<"ejabberd Web Admin">>),
+                           [?XCT(<<"title">>, ?T("ejabberd Web Admin")),
                             #xmlel{name = <<"meta">>,
                                    attrs =
                                        [{<<"http-equiv">>, <<"Content-Type">>},
@@ -393,7 +395,7 @@ logo_fill() ->
 %%%% process_admin
 
 process_admin(global, #request{path = [], lang = Lang}, AJID) ->
-    make_xhtml((?H1GL((?T(<<"Administration">>)), <<"">>,
+    make_xhtml((?H1GL((translate:translate(Lang, ?T("Administration"))), <<"">>,
                      <<"Contents">>))
                 ++
                 [?XE(<<"ul">>,
@@ -402,7 +404,7 @@ process_admin(global, #request{path = [], lang = Lang}, AJID) ->
                              <- get_menu_items(global, cluster, Lang, AJID)])],
               global, Lang, AJID);
 process_admin(Host, #request{path = [], lang = Lang}, AJID) ->
-    make_xhtml([?XCT(<<"h1">>, <<"Administration">>),
+    make_xhtml([?XCT(<<"h1">>, ?T("Administration")),
                ?XE(<<"ul">>,
                    [?LI([?ACT(MIU, MIN)])
                     || {MIU, MIN}
@@ -435,28 +437,28 @@ process_admin(_Host, #request{path = [<<"additions.js">>]}, _) ->
      additions_js()};
 process_admin(global, #request{path = [<<"vhosts">>], lang = Lang}, AJID) ->
     Res = list_vhosts(Lang, AJID),
-    make_xhtml((?H1GL((?T(<<"Virtual Hosts">>)),
-                     <<"virtualhosting">>, <<"Virtual Hosting">>))
+    make_xhtml((?H1GL((translate:translate(Lang, ?T("Virtual Hosts"))),
+                     <<"virtualhosting">>, ?T("Virtual Hosting")))
                 ++ Res,
               global, Lang, AJID);
 process_admin(Host,  #request{path = [<<"users">>], q = Query,
                              lang = Lang}, AJID)
     when is_binary(Host) ->
     Res = list_users(Host, Query, Lang, fun url_func/1),
-    make_xhtml([?XCT(<<"h1">>, <<"Users">>)] ++ Res, Host,
+    make_xhtml([?XCT(<<"h1">>, ?T("Users"))] ++ Res, Host,
               Lang, AJID);
 process_admin(Host, #request{path = [<<"users">>, Diap],
                             lang = Lang}, AJID)
     when is_binary(Host) ->
     Res = list_users_in_diapason(Host, Diap, Lang,
                                 fun url_func/1),
-    make_xhtml([?XCT(<<"h1">>, <<"Users">>)] ++ Res, Host,
+    make_xhtml([?XCT(<<"h1">>, ?T("Users"))] ++ Res, Host,
               Lang, AJID);
 process_admin(Host, #request{path = [<<"online-users">>],
                             lang = Lang}, AJID)
     when is_binary(Host) ->
     Res = list_online_users(Host, Lang),
-    make_xhtml([?XCT(<<"h1">>, <<"Online Users">>)] ++ Res,
+    make_xhtml([?XCT(<<"h1">>, ?T("Online Users"))] ++ Res,
               Host, Lang, AJID);
 process_admin(Host, #request{path = [<<"last-activity">>],
                             q = Query, lang = Lang}, AJID)
@@ -471,11 +473,11 @@ process_admin(Host, #request{path = [<<"last-activity">>],
                list_last_activity(Host, Lang, false, Month);
            _ -> list_last_activity(Host, Lang, true, Month)
          end,
-    make_xhtml([?XCT(<<"h1">>, <<"Users Last Activity">>)]
+    make_xhtml([?XCT(<<"h1">>, ?T("Users Last Activity"))]
                 ++
                 [?XAE(<<"form">>,
                       [{<<"action">>, <<"">>}, {<<"method">>, <<"post">>}],
-                      [?CT(<<"Period: ">>),
+                      [?CT(?T("Period: ")),
                        ?XAE(<<"select">>, [{<<"name">>, <<"period">>}],
                             (lists:map(fun ({O, V}) ->
                                                Sel = if O == Month ->
@@ -488,21 +490,21 @@ process_admin(Host, #request{path = [<<"last-activity">>],
                                                        [{<<"value">>, O}]),
                                                     V)
                                        end,
-                                       [{<<"month">>, ?T(<<"Last month">>)},
-                                        {<<"year">>, ?T(<<"Last year">>)},
+                                       [{<<"month">>, translate:translate(Lang, ?T("Last month"))},
+                                        {<<"year">>, translate:translate(Lang, ?T("Last year"))},
                                         {<<"all">>,
-                                         ?T(<<"All activity">>)}]))),
+                                         translate:translate(Lang, ?T("All activity"))}]))),
                        ?C(<<" ">>),
                        ?INPUTT(<<"submit">>, <<"ordinary">>,
-                               <<"Show Ordinary Table">>),
+                               ?T("Show Ordinary Table")),
                        ?C(<<" ">>),
                        ?INPUTT(<<"submit">>, <<"integral">>,
-                               <<"Show Integral Table">>)])]
+                               ?T("Show Integral Table"))])]
                   ++ Res,
               Host, Lang, AJID);
 process_admin(Host, #request{path = [<<"stats">>], lang = Lang}, AJID) ->
     Res = get_stats(Host, Lang),
-    make_xhtml([?XCT(<<"h1">>, <<"Statistics">>)] ++ Res,
+    make_xhtml([?XCT(<<"h1">>, ?T("Statistics"))] ++ Res,
               Host, Lang, AJID);
 process_admin(Host, #request{path = [<<"user">>, U],
                             q = Query, lang = Lang}, AJID) ->
@@ -511,7 +513,7 @@ process_admin(Host, #request{path = [<<"user">>, U],
          Res = user_info(U, Host, Query, Lang),
          make_xhtml(Res, Host, Lang, AJID);
       false ->
-         make_xhtml([?XCT(<<"h1">>, <<"Not Found">>)], Host,
+         make_xhtml([?XCT(<<"h1">>, ?T("Not Found"))], Host,
                     Lang, AJID)
     end;
 process_admin(Host, #request{path = [<<"nodes">>], lang = Lang}, AJID) ->
@@ -521,7 +523,7 @@ process_admin(Host, #request{path = [<<"node">>, SNode | NPath],
                             q = Query, lang = Lang}, AJID) ->
     case search_running_node(SNode) of
       false ->
-         make_xhtml([?XCT(<<"h1">>, <<"Node not found">>)], Host,
+         make_xhtml([?XCT(<<"h1">>, ?T("Node not found"))], Host,
                     Lang, AJID);
       Node ->
          Res = get_node(Host, Node, NPath, Query, Lang),
@@ -567,9 +569,9 @@ list_vhosts2(Lang, Hosts) ->
     [?XE(<<"table">>,
         [?XE(<<"thead">>,
              [?XE(<<"tr">>,
-                  [?XCT(<<"td">>, <<"Host">>),
-                   ?XCT(<<"td">>, <<"Registered Users">>),
-                   ?XCT(<<"td">>, <<"Online Users">>)])]),
+                  [?XCT(<<"td">>, ?T("Host")),
+                   ?XCT(<<"td">>, ?T("Registered Users")),
+                   ?XCT(<<"td">>, ?T("Online Users"))])]),
          ?XE(<<"tbody">>,
              (lists:map(fun (Host) ->
                                 OnlineUsers =
@@ -623,8 +625,8 @@ list_users(Host, Query, Lang, URLFunc) ->
             end,
     case Res of
 %% Parse user creation query and try register:
-      ok -> [?XREST(<<"Submitted">>)];
-      error -> [?XREST(<<"Bad format">>)];
+      ok -> [?XREST(?T("Submitted"))];
+      error -> [?XREST(?T("Bad format"))];
       nothing -> []
     end
       ++
@@ -632,12 +634,12 @@ list_users(Host, Query, Lang, URLFunc) ->
            [{<<"action">>, <<"">>}, {<<"method">>, <<"post">>}],
            ([?XE(<<"table">>,
                  [?XE(<<"tr">>,
-                      [?XC(<<"td">>, <<(?T(<<"User">>))/binary, ":">>),
+                      [?XC(<<"td">>, <<(translate:translate(Lang, ?T("User")))/binary, ":">>),
                        ?XE(<<"td">>,
                            [?INPUT(<<"text">>, <<"newusername">>, <<"">>)]),
                        ?XE(<<"td">>, [?C(<<" @ ", Host/binary>>)])]),
                   ?XE(<<"tr">>,
-                      [?XC(<<"td">>, <<(?T(<<"Password">>))/binary, ":">>),
+                      [?XC(<<"td">>, <<(translate:translate(Lang, ?T("Password")))/binary, ":">>),
                        ?XE(<<"td">>,
                            [?INPUT(<<"password">>, <<"newuserpassword">>,
                                    <<"">>)]),
@@ -646,7 +648,7 @@ list_users(Host, Query, Lang, URLFunc) ->
                       [?X(<<"td">>),
                        ?XAE(<<"td">>, [{<<"class">>, <<"alignright">>}],
                             [?INPUTT(<<"submit">>, <<"addnewuser">>,
-                                     <<"Add User">>)]),
+                                     ?T("Add User"))]),
                        ?X(<<"td">>)])]),
              ?P]
               ++ FUsers))].
@@ -688,9 +690,9 @@ list_given_users(Host, Users, Prefix, Lang, URLFunc) ->
     ?XE(<<"table">>,
        [?XE(<<"thead">>,
             [?XE(<<"tr">>,
-                 [?XCT(<<"td">>, <<"User">>),
-                  ?XCT(<<"td">>, <<"Offline Messages">>),
-                  ?XCT(<<"td">>, <<"Last Activity">>)])]),
+                 [?XCT(<<"td">>, ?T("User")),
+                  ?XCT(<<"td">>, ?T("Offline Messages")),
+                  ?XCT(<<"td">>, ?T("Last Activity"))])]),
         ?XE(<<"tbody">>,
             (lists:map(fun (_SU = {Server, User}) ->
                                US = {User, Server},
@@ -708,7 +710,7 @@ list_given_users(Host, Users, Prefix, Lang, URLFunc) ->
                                              case mod_last:get_last_info(User,
                                                                          Server)
                                                  of
-                                               not_found -> ?T(<<"Never">>);
+                                               not_found -> translate:translate(Lang, ?T("Never"));
                                                {ok, Shift, _Status} ->
                                                    TimeStamp = {Shift div
                                                                   1000000,
@@ -726,7 +728,7 @@ list_given_users(Host, Users, Prefix, Lang, URLFunc) ->
                                                                                    Minute,
                                                                                    Second]))
                                              end;
-                                         _ -> ?T(<<"Online">>)
+                                         _ -> translate:translate(Lang, ?T("Online"))
                                        end,
                                ?XE(<<"tr">>,
                                    [?XE(<<"td">>,
@@ -754,7 +756,7 @@ get_offlinemsg_module(Server) ->
 
 get_lastactivity_menuitem_list(Server) ->
     case mod_last_opt:db_type(Server) of
-      mnesia -> [{<<"last-activity">>, <<"Last Activity">>}];
+      mnesia -> [{<<"last-activity">>, ?T("Last Activity")}];
       _ -> []
     end.
 
@@ -779,16 +781,16 @@ get_stats(global, Lang) ->
     [?XAE(<<"table">>, [],
          [?XE(<<"tbody">>,
               [?XE(<<"tr">>,
-                   [?XCT(<<"td">>, <<"Registered Users:">>),
+                   [?XCT(<<"td">>, ?T("Registered Users:")),
                     ?XC(<<"td">>, (pretty_string_int(RegisteredUsers)))]),
                ?XE(<<"tr">>,
-                   [?XCT(<<"td">>, <<"Online Users:">>),
+                   [?XCT(<<"td">>, ?T("Online Users:")),
                     ?XC(<<"td">>, (pretty_string_int(OnlineUsers)))]),
                ?XE(<<"tr">>,
-                   [?XCT(<<"td">>, <<"Outgoing s2s Connections:">>),
+                   [?XCT(<<"td">>, ?T("Outgoing s2s Connections:")),
                     ?XC(<<"td">>, (pretty_string_int(OutS2SNumber)))]),
                ?XE(<<"tr">>,
-                   [?XCT(<<"td">>, <<"Incoming s2s Connections:">>),
+                   [?XCT(<<"td">>, ?T("Incoming s2s Connections:")),
                     ?XC(<<"td">>, (pretty_string_int(InS2SNumber)))])])])];
 get_stats(Host, Lang) ->
     OnlineUsers =
@@ -798,10 +800,10 @@ get_stats(Host, Lang) ->
     [?XAE(<<"table">>, [],
          [?XE(<<"tbody">>,
               [?XE(<<"tr">>,
-                   [?XCT(<<"td">>, <<"Registered Users:">>),
+                   [?XCT(<<"td">>, ?T("Registered Users:")),
                     ?XC(<<"td">>, (pretty_string_int(RegisteredUsers)))]),
                ?XE(<<"tr">>,
-                   [?XCT(<<"td">>, <<"Online Users:">>),
+                   [?XCT(<<"td">>, ?T("Online Users:")),
                     ?XC(<<"td">>, (pretty_string_int(OnlineUsers)))])])])].
 
 list_online_users(Host, _Lang) ->
@@ -824,7 +826,7 @@ user_info(User, Server, Query, Lang) ->
                                               Server),
     FResources =
         case Resources of
-            [] -> [?CT(<<"None">>)];
+            [] -> [?CT(?T("None"))];
             _ ->
                 [?XE(<<"ul">>,
                      (lists:map(
@@ -881,7 +883,7 @@ user_info(User, Server, Query, Lang) ->
     FPassword = [?INPUT(<<"text">>, <<"password">>, <<"">>),
                 ?C(<<" ">>),
                 ?INPUTT(<<"submit">>, <<"chpassword">>,
-                        <<"Change Password">>)],
+                        ?T("Change Password"))],
     UserItems = ejabberd_hooks:run_fold(webadmin_user,
                                        LServer, [], [User, Server, Lang]),
     LastActivity = case ejabberd_sm:get_user_resources(User,
@@ -889,7 +891,7 @@ user_info(User, Server, Query, Lang) ->
                       of
                     [] ->
                         case mod_last:get_last_info(User, Server) of
-                          not_found -> ?T(<<"Never">>);
+                          not_found -> translate:translate(Lang, ?T("Never"));
                           {ok, Shift, _Status} ->
                               TimeStamp = {Shift div 1000000,
                                            Shift rem 1000000, 0},
@@ -900,29 +902,29 @@ user_info(User, Server, Query, Lang) ->
                                                               Hour, Minute,
                                                               Second]))
                         end;
-                    _ -> ?T(<<"Online">>)
+                    _ -> translate:translate(Lang, ?T("Online"))
                   end,
-    [?XC(<<"h1">>, (str:format(?T(<<"User ~s">>),
+    [?XC(<<"h1">>, (str:format(translate:translate(Lang, ?T("User ~s")),
                                                 [us_to_list(US)])))]
       ++
       case Res of
-       ok -> [?XREST(<<"Submitted">>)];
-       error -> [?XREST(<<"Bad format">>)];
+       ok -> [?XREST(?T("Submitted"))];
+       error -> [?XREST(?T("Bad format"))];
        nothing -> []
       end
        ++
        [?XAE(<<"form">>,
              [{<<"action">>, <<"">>}, {<<"method">>, <<"post">>}],
-             ([?XCT(<<"h3">>, <<"Connected Resources:">>)] ++
+             ([?XCT(<<"h3">>, ?T("Connected Resources:"))] ++
                 FResources ++
-                  [?XCT(<<"h3">>, <<"Password:">>)] ++
+                  [?XCT(<<"h3">>, ?T("Password:"))] ++
                     FPassword ++
-                      [?XCT(<<"h3">>, <<"Last Activity">>)] ++
+                      [?XCT(<<"h3">>, ?T("Last Activity"))] ++
                         [?C(LastActivity)] ++
                           UserItems ++
                             [?P,
                              ?INPUTT(<<"submit">>, <<"removeuser">>,
-                                     <<"Remove User">>)]))].
+                                     ?T("Remove User"))]))].
 
 user_parse_query(User, Server, Query) ->
     lists:foldl(fun ({Action, _Value}, Acc)
@@ -969,7 +971,7 @@ list_last_activity(Host, Lang, Integral, Period) ->
       {'EXIT', _Reason} -> [];
       Vals ->
          Hist = histogram(Vals, Integral),
-         if Hist == [] -> [?CT(<<"No Data">>)];
+         if Hist == [] -> [?CT(?T("No Data"))];
             true ->
                 Left = if Days == infinity -> 0;
                           true -> Days - length(Hist)
@@ -1020,7 +1022,7 @@ get_nodes(Lang) ->
     RunningNodes = ejabberd_cluster:get_nodes(),
     StoppedNodes = ejabberd_cluster:get_known_nodes()
                     -- RunningNodes,
-    FRN = if RunningNodes == [] -> ?CT(<<"None">>);
+    FRN = if RunningNodes == [] -> ?CT(?T("None"));
             true ->
                 ?XE(<<"ul">>,
                     (lists:map(fun (N) ->
@@ -1030,7 +1032,7 @@ get_nodes(Lang) ->
                                end,
                                lists:sort(RunningNodes))))
          end,
-    FSN = if StoppedNodes == [] -> ?CT(<<"None">>);
+    FSN = if StoppedNodes == [] -> ?CT(?T("None"));
             true ->
                 ?XE(<<"ul">>,
                     (lists:map(fun (N) ->
@@ -1039,9 +1041,9 @@ get_nodes(Lang) ->
                                end,
                                lists:sort(StoppedNodes))))
          end,
-    [?XCT(<<"h1">>, <<"Nodes">>),
-     ?XCT(<<"h3">>, <<"Running Nodes">>), FRN,
-     ?XCT(<<"h3">>, <<"Stopped Nodes">>), FSN].
+    [?XCT(<<"h1">>, ?T("Nodes")),
+     ?XCT(<<"h3">>, ?T("Running Nodes")), FRN,
+     ?XCT(<<"h3">>, ?T("Stopped Nodes")), FSN].
 
 search_running_node(SNode) ->
     RunningNodes = ejabberd_cluster:get_nodes(),
@@ -1059,39 +1061,38 @@ get_node(global, Node, [], Query, Lang) ->
     Base = get_base_path(global, Node),
     MenuItems2 = make_menu_items(global, Node, Base, Lang),
     [?XC(<<"h1">>,
-        (str:format(?T(<<"Node ~p">>), [Node])))]
+        (str:format(translate:translate(Lang, ?T("Node ~p")), [Node])))]
       ++
       case Res of
-       ok -> [?XREST(<<"Submitted">>)];
-       error -> [?XREST(<<"Bad format">>)];
+       ok -> [?XREST(?T("Submitted"))];
+       error -> [?XREST(?T("Bad format"))];
        nothing -> []
       end
        ++
        [?XE(<<"ul">>,
-            ([?LI([?ACT(<<Base/binary, "db/">>, <<"Database">>)]),
-              ?LI([?ACT(<<Base/binary, "backup/">>, <<"Backup">>)]),
-              ?LI([?ACT(<<Base/binary, "stats/">>,
-                        <<"Statistics">>)]),
-              ?LI([?ACT(<<Base/binary, "update/">>, <<"Update">>)])]
+            ([?LI([?ACT(<<Base/binary, "db/">>, ?T("Database"))]),
+              ?LI([?ACT(<<Base/binary, "backup/">>, ?T("Backup"))]),
+              ?LI([?ACT(<<Base/binary, "stats/">>, ?T("Statistics"))]),
+              ?LI([?ACT(<<Base/binary, "update/">>, ?T("Update"))])]
                ++ MenuItems2)),
         ?XAE(<<"form">>,
              [{<<"action">>, <<"">>}, {<<"method">>, <<"post">>}],
-             [?INPUTT(<<"submit">>, <<"restart">>, <<"Restart">>),
+             [?INPUTT(<<"submit">>, <<"restart">>, ?T("Restart")),
               ?C(<<" ">>),
-              ?INPUTT(<<"submit">>, <<"stop">>, <<"Stop">>)])];
+              ?INPUTT(<<"submit">>, <<"stop">>, ?T("Stop"))])];
 get_node(Host, Node, [], _Query, Lang) ->
     Base = get_base_path(Host, Node),
     MenuItems2 = make_menu_items(Host, Node, Base, Lang),
-    [?XC(<<"h1">>, (str:format(?T(<<"Node ~p">>), [Node]))),
+    [?XC(<<"h1">>, (str:format(translate:translate(Lang, ?T("Node ~p")), [Node]))),
      ?XE(<<"ul">>, MenuItems2)];
 get_node(global, Node, [<<"db">>], Query, Lang) ->
     case ejabberd_cluster:call(Node, mnesia, system_info, [tables]) of
       {badrpc, _Reason} ->
-         [?XCT(<<"h1">>, <<"RPC Call Error">>)];
+         [?XCT(<<"h1">>, ?T("RPC Call Error"))];
       Tables ->
          ResS = case node_db_parse_query(Node, Tables, Query) of
                   nothing -> [];
-                  ok -> [?XREST(<<"Submitted">>)]
+                  ok -> [?XREST(?T("Submitted"))]
                 end,
          STables = lists:sort(Tables),
          Rows = lists:map(fun (Table) ->
@@ -1138,7 +1139,7 @@ get_node(global, Node, [<<"db">>], Query, Lang) ->
                           end,
                           STables),
          [?XC(<<"h1">>,
-              (str:format(?T(<<"Database Tables at ~p">>),
+              (str:format(translate:translate(Lang, ?T("Database Tables at ~p")),
                                             [Node]))
          )]
            ++
@@ -1148,10 +1149,10 @@ get_node(global, Node, [<<"db">>], Query, Lang) ->
                    [?XAE(<<"table">>, [],
                          [?XE(<<"thead">>,
                               [?XE(<<"tr">>,
-                                   [?XCT(<<"td">>, <<"Name">>),
-                                    ?XCT(<<"td">>, <<"Storage Type">>),
-                                    ?XCT(<<"td">>, <<"Elements">>),
-                                    ?XCT(<<"td">>, <<"Memory">>)])]),
+                                   [?XCT(<<"td">>, ?T("Name")),
+                                    ?XCT(<<"td">>, ?T("Storage Type")),
+                                    ?XCT(<<"td">>, ?T("Elements")),
+                                    ?XCT(<<"td">>, ?T("Memory"))])]),
                           ?XE(<<"tbody">>,
                               (Rows ++
                                  [?XE(<<"tr">>,
@@ -1160,7 +1161,7 @@ get_node(global, Node, [<<"db">>], Query, Lang) ->
                                              {<<"class">>, <<"alignright">>}],
                                             [?INPUTT(<<"submit">>,
                                                      <<"submit">>,
-                                                     <<"Submit">>)])])]))])])]
+                                                     ?T("Submit"))])])]))])])]
     end;
 get_node(global, Node, [<<"backup">>], Query, Lang) ->
     HomeDirRaw = case {os:getenv("HOME"), os:type()} of
@@ -1171,77 +1172,77 @@ get_node(global, Node, [<<"backup">>], Query, Lang) ->
     HomeDir = filename:nativename(HomeDirRaw),
     ResS = case node_backup_parse_query(Node, Query) of
             nothing -> [];
-            ok -> [?XREST(<<"Submitted">>)];
+            ok -> [?XREST(?T("Submitted"))];
             {error, Error} ->
-                [?XRES(<<(?T(<<"Error">>))/binary, ": ",
+                [?XRES(<<(translate:translate(Lang, ?T("Error")))/binary, ": ",
                          ((str:format("~p", [Error])))/binary>>)]
           end,
-    [?XC(<<"h1">>, (str:format(?T(<<"Backup of ~p">>), [Node])))]
+    [?XC(<<"h1">>, (str:format(translate:translate(Lang, ?T("Backup of ~p")), [Node])))]
       ++
       ResS ++
        [?XCT(<<"p">>,
-             <<"Please note 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.">>),
+             ?T("Please note 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">>,
                         [?XE(<<"tr">>,
-                             [?XCT(<<"td">>, <<"Store binary backup:">>),
+                             [?XCT(<<"td">>, ?T("Store binary backup:")),
                               ?XE(<<"td">>,
                                   [?INPUT(<<"text">>, <<"storepath">>,
                                           (filename:join(HomeDir,
                                                          "ejabberd.backup")))]),
                               ?XE(<<"td">>,
                                   [?INPUTT(<<"submit">>, <<"store">>,
-                                           <<"OK">>)])]),
+                                           ?T("OK"))])]),
                          ?XE(<<"tr">>,
                              [?XCT(<<"td">>,
-                                   <<"Restore binary backup immediately:">>),
+                                   ?T("Restore binary backup immediately:")),
                               ?XE(<<"td">>,
                                   [?INPUT(<<"text">>, <<"restorepath">>,
                                           (filename:join(HomeDir,
                                                          "ejabberd.backup")))]),
                               ?XE(<<"td">>,
                                   [?INPUTT(<<"submit">>, <<"restore">>,
-                                           <<"OK">>)])]),
+                                           ?T("OK"))])]),
                          ?XE(<<"tr">>,
                              [?XCT(<<"td">>,
-                                   <<"Restore binary backup after next ejabberd "
-                                     "restart (requires less memory):">>),
+                                   ?T("Restore binary backup after next ejabberd "
+                                      "restart (requires less memory):")),
                               ?XE(<<"td">>,
                                   [?INPUT(<<"text">>, <<"fallbackpath">>,
                                           (filename:join(HomeDir,
                                                          "ejabberd.backup")))]),
                               ?XE(<<"td">>,
                                   [?INPUTT(<<"submit">>, <<"fallback">>,
-                                           <<"OK">>)])]),
+                                           ?T("OK"))])]),
                          ?XE(<<"tr">>,
-                             [?XCT(<<"td">>, <<"Store plain text backup:">>),
+                             [?XCT(<<"td">>, ?T("Store plain text backup:")),
                               ?XE(<<"td">>,
                                   [?INPUT(<<"text">>, <<"dumppath">>,
                                           (filename:join(HomeDir,
                                                          "ejabberd.dump")))]),
                               ?XE(<<"td">>,
                                   [?INPUTT(<<"submit">>, <<"dump">>,
-                                           <<"OK">>)])]),
+                                           ?T("OK"))])]),
                          ?XE(<<"tr">>,
                              [?XCT(<<"td">>,
-                                   <<"Restore plain text backup immediately:">>),
+                                   ?T("Restore plain text backup immediately:")),
                               ?XE(<<"td">>,
                                   [?INPUT(<<"text">>, <<"loadpath">>,
                                           (filename:join(HomeDir,
                                                          "ejabberd.dump")))]),
                               ?XE(<<"td">>,
                                   [?INPUTT(<<"submit">>, <<"load">>,
-                                           <<"OK">>)])]),
+                                           ?T("OK"))])]),
                          ?XE(<<"tr">>,
                              [?XCT(<<"td">>,
-                                   <<"Import users data from a PIEFXIS file "
-                                     "(XEP-0227):">>),
+                                   ?T("Import users data from a PIEFXIS file "
+                                      "(XEP-0227):")),
                               ?XE(<<"td">>,
                                   [?INPUT(<<"text">>,
                                           <<"import_piefxis_filepath">>,
@@ -1250,11 +1251,11 @@ get_node(global, Node, [<<"backup">>], Query, Lang) ->
                               ?XE(<<"td">>,
                                   [?INPUTT(<<"submit">>,
                                            <<"import_piefxis_file">>,
-                                           <<"OK">>)])]),
+                                           ?T("OK"))])]),
                          ?XE(<<"tr">>,
                              [?XCT(<<"td">>,
-                                   <<"Export data of all users in the server "
-                                     "to PIEFXIS files (XEP-0227):">>),
+                                   ?T("Export data of all users in the server "
+                                      "to PIEFXIS files (XEP-0227):")),
                               ?XE(<<"td">>,
                                   [?INPUT(<<"text">>,
                                           <<"export_piefxis_dirpath">>,
@@ -1262,11 +1263,11 @@ get_node(global, Node, [<<"backup">>], Query, Lang) ->
                               ?XE(<<"td">>,
                                   [?INPUTT(<<"submit">>,
                                            <<"export_piefxis_dir">>,
-                                           <<"OK">>)])]),
+                                           ?T("OK"))])]),
                          ?XE(<<"tr">>,
                              [?XE(<<"td">>,
-                                  [?CT(<<"Export data of users in a host to PIEFXIS "
-                                         "files (XEP-0227):">>),
+                                  [?CT(?T("Export data of users in a host to PIEFXIS "
+                                          "files (XEP-0227):")),
                                    ?C(<<" ">>),
                                    ?INPUT(<<"text">>,
                                           <<"export_piefxis_host_dirhost">>,
@@ -1278,11 +1279,11 @@ get_node(global, Node, [<<"backup">>], Query, Lang) ->
                               ?XE(<<"td">>,
                                   [?INPUTT(<<"submit">>,
                                            <<"export_piefxis_host_dir">>,
-                                           <<"OK">>)])]),
+                                           ?T("OK"))])]),
                           ?XE(<<"tr">>,
                               [?XE(<<"td">>,
-                                   [?CT(<<"Export all tables as SQL queries "
-                                          "to a file:">>),
+                                   [?CT(?T("Export all tables as SQL queries "
+                                          "to a file:")),
                                     ?C(<<" ">>),
                                     ?INPUT(<<"text">>,
                                            <<"export_sql_filehost">>,
@@ -1294,28 +1295,28 @@ get_node(global, Node, [<<"backup">>], Query, Lang) ->
                                                          "db.sql")))]),
                               ?XE(<<"td">>,
                                   [?INPUTT(<<"submit">>, <<"export_sql_file">>,
-                                           <<"OK">>)])]),
+                                           ?T("OK"))])]),
                          ?XE(<<"tr">>,
                              [?XCT(<<"td">>,
-                                   <<"Import user data from jabberd14 spool "
-                                     "file:">>),
+                                   ?T("Import user data from jabberd14 spool "
+                                      "file:")),
                               ?XE(<<"td">>,
                                   [?INPUT(<<"text">>, <<"import_filepath">>,
                                           (filename:join(HomeDir,
                                                          "user1.xml")))]),
                               ?XE(<<"td">>,
                                   [?INPUTT(<<"submit">>, <<"import_file">>,
-                                           <<"OK">>)])]),
+                                           ?T("OK"))])]),
                          ?XE(<<"tr">>,
                              [?XCT(<<"td">>,
-                                   <<"Import users data from jabberd14 spool "
-                                     "directory:">>),
+                                   ?T("Import users data from jabberd14 spool "
+                                      "directory:")),
                               ?XE(<<"td">>,
                                   [?INPUT(<<"text">>, <<"import_dirpath">>,
                                           <<"/var/spool/jabber/">>)]),
                               ?XE(<<"td">>,
                                   [?INPUTT(<<"submit">>, <<"import_dir">>,
-                                           <<"OK">>)])])])])])];
+                                           ?T("OK"))])])])])])];
 get_node(global, Node, [<<"stats">>], _Query, Lang) ->
     UpTime = ejabberd_cluster:call(Node, erlang, statistics,
                      [wall_clock]),
@@ -1334,35 +1335,35 @@ get_node(global, Node, [<<"stats">>], _Query, Lang) ->
     TransactionsLogged = ejabberd_cluster:call(Node, mnesia, system_info,
                                  [transaction_log_writes]),
     [?XC(<<"h1">>,
-        (str:format(?T(<<"Statistics of ~p">>), [Node]))),
+        (str:format(translate:translate(Lang, ?T("Statistics of ~p")), [Node]))),
      ?XAE(<<"table">>, [],
          [?XE(<<"tbody">>,
               [?XE(<<"tr">>,
-                   [?XCT(<<"td">>, <<"Uptime:">>),
+                   [?XCT(<<"td">>, ?T("Uptime:")),
                     ?XAC(<<"td">>, [{<<"class">>, <<"alignright">>}],
                          UpTimeS)]),
                ?XE(<<"tr">>,
-                   [?XCT(<<"td">>, <<"CPU Time:">>),
+                   [?XCT(<<"td">>, ?T("CPU Time:")),
                     ?XAC(<<"td">>, [{<<"class">>, <<"alignright">>}],
                          CPUTimeS)]),
                ?XE(<<"tr">>,
-                   [?XCT(<<"td">>, <<"Online Users:">>),
+                   [?XCT(<<"td">>, ?T("Online Users:")),
                     ?XAC(<<"td">>, [{<<"class">>, <<"alignright">>}],
                          (pretty_string_int(OnlineUsers)))]),
                ?XE(<<"tr">>,
-                   [?XCT(<<"td">>, <<"Transactions Committed:">>),
+                   [?XCT(<<"td">>, ?T("Transactions Committed:")),
                     ?XAC(<<"td">>, [{<<"class">>, <<"alignright">>}],
                          (pretty_string_int(TransactionsCommitted)))]),
                ?XE(<<"tr">>,
-                   [?XCT(<<"td">>, <<"Transactions Aborted:">>),
+                   [?XCT(<<"td">>, ?T("Transactions Aborted:")),
                     ?XAC(<<"td">>, [{<<"class">>, <<"alignright">>}],
                          (pretty_string_int(TransactionsAborted)))]),
                ?XE(<<"tr">>,
-                   [?XCT(<<"td">>, <<"Transactions Restarted:">>),
+                   [?XCT(<<"td">>, ?T("Transactions Restarted:")),
                     ?XAC(<<"td">>, [{<<"class">>, <<"alignright">>}],
                          (pretty_string_int(TransactionsRestarted)))]),
                ?XE(<<"tr">>,
-                   [?XCT(<<"td">>, <<"Transactions Logged:">>),
+                   [?XCT(<<"td">>, ?T("Transactions Logged:")),
                     ?XAC(<<"td">>, [{<<"class">>, <<"alignright">>}],
                          (pretty_string_int(TransactionsLogged)))])])])];
 get_node(global, Node, [<<"update">>], Query, Lang) ->
@@ -1373,7 +1374,7 @@ get_node(global, Node, [<<"update">>], Query, Lang) ->
      Check} =
        ejabberd_cluster:call(Node, ejabberd_update, update_info, []),
     Mods = case UpdatedBeams of
-            [] -> ?CT(<<"None">>);
+            [] -> ?CT(?T("None"));
             _ ->
                 BeamsLis = lists:map(fun (Beam) ->
                                              BeamString =
@@ -1386,12 +1387,12 @@ get_node(global, Node, [<<"update">>], Query, Lang) ->
                                      UpdatedBeams),
                 SelectButtons = [?BR,
                                  ?INPUTATTRS(<<"button">>, <<"selectall">>,
-                                             <<"Select All">>,
+                                             ?T("Select All"),
                                              [{<<"onClick">>,
                                                <<"selectAll()">>}]),
                                  ?C(<<" ">>),
                                  ?INPUTATTRS(<<"button">>, <<"unselectall">>,
-                                             <<"Unselect All">>,
+                                             ?T("Unselect All"),
                                              [{<<"onClick">>,
                                                <<"unSelectAll()">>}])],
                 ?XAE(<<"ul">>, [{<<"class">>, <<"nolistyle">>}],
@@ -1402,10 +1403,10 @@ get_node(global, Node, [<<"update">>], Query, Lang) ->
     FmtLowLevelScript = (?XC(<<"pre">>,
                             (str:format("~p", [LowLevelScript])))),
     [?XC(<<"h1">>,
-        (str:format(?T(<<"Update ~p">>), [Node])))]
+        (str:format(translate:translate(Lang, ?T("Update ~p")), [Node])))]
       ++
       case Res of
-       ok -> [?XREST(<<"Submitted">>)];
+       ok -> [?XREST(?T("Submitted"))];
        {error, ErrorText} ->
            [?XREST(<<"Error: ", ErrorText/binary>>)];
        nothing -> []
@@ -1413,14 +1414,14 @@ get_node(global, Node, [<<"update">>], Query, Lang) ->
        ++
        [?XAE(<<"form">>,
              [{<<"action">>, <<"">>}, {<<"method">>, <<"post">>}],
-             [?XCT(<<"h2">>, <<"Update plan">>),
-              ?XCT(<<"h3">>, <<"Modified modules">>), Mods,
-              ?XCT(<<"h3">>, <<"Update script">>), FmtScript,
-              ?XCT(<<"h3">>, <<"Low level update script">>),
-              FmtLowLevelScript, ?XCT(<<"h3">>, <<"Script check">>),
+             [?XCT(<<"h2">>, ?T("Update plan")),
+              ?XCT(<<"h3">>, ?T("Modified modules")), Mods,
+              ?XCT(<<"h3">>, ?T("Update script")), FmtScript,
+              ?XCT(<<"h3">>, ?T("Low level update script")),
+              FmtLowLevelScript, ?XCT(<<"h3">>, ?T("Script check")),
               ?XC(<<"pre">>, (misc:atom_to_binary(Check))),
               ?BR,
-              ?INPUTT(<<"submit">>, <<"update">>, <<"Update">>)])];
+              ?INPUTT(<<"submit">>, <<"update">>, ?T("Update"))])];
 get_node(Host, Node, NPath, Query, Lang) ->
     Res = case Host of
              global ->
@@ -1470,12 +1471,12 @@ db_storage_select(ID, Opt, Lang) ->
                                       iolist_to_binary(atom_to_list(O))}]),
                                  Desc)
                    end,
-                   [{ram_copies, <<"RAM copy">>},
-                    {disc_copies, <<"RAM and disc copy">>},
-                    {disc_only_copies, <<"Disc only copy">>},
-                    {unknown, <<"Remote copy">>},
-                    {delete_content, <<"Delete content">>},
-                    {delete_table, <<"Delete table">>}]))).
+                   [{ram_copies, ?T("RAM copy")},
+                    {disc_copies, ?T("RAM and disc copy")},
+                    {disc_only_copies, ?T("Disc only copy")},
+                    {unknown, ?T("Remote copy")},
+                    {delete_content, ?T("Delete content")},
+                    {delete_table, ?T("Delete table")}]))).
 
 node_db_parse_query(_Node, _Tables, [{nokey, <<>>}]) ->
     nothing;
@@ -1756,12 +1757,12 @@ make_host_menu(global, _HostNodeMenu, _Lang, _JID) ->
     {<<"">>, <<"">>, []};
 make_host_menu(Host, HostNodeMenu, Lang, JID) ->
     HostBase = get_base_path(Host, cluster),
-    HostFixed = [{<<"users">>, <<"Users">>},
-                {<<"online-users">>, <<"Online Users">>}]
+    HostFixed = [{<<"users">>, ?T("Users")},
+                {<<"online-users">>, ?T("Online Users")}]
                  ++
                  get_lastactivity_menuitem_list(Host) ++
-                   [{<<"nodes">>, <<"Nodes">>, HostNodeMenu},
-                    {<<"stats">>, <<"Statistics">>}]
+                   [{<<"nodes">>, ?T("Nodes"), HostNodeMenu},
+                    {<<"stats">>, ?T("Statistics")}]
                      ++ get_menu_items_hook({host, Host}, Lang),
     HostBasePath = url_to_path(HostBase),
     HostFixed2 = [Tuple
@@ -1773,10 +1774,10 @@ make_node_menu(_Host, cluster, _Lang) ->
     {<<"">>, <<"">>, []};
 make_node_menu(global, Node, Lang) ->
     NodeBase = get_base_path(global, Node),
-    NodeFixed = [{<<"db/">>, <<"Database">>},
-                {<<"backup/">>, <<"Backup">>},
-                {<<"stats/">>, <<"Statistics">>},
-                {<<"update/">>, <<"Update">>}]
+    NodeFixed = [{<<"db/">>, ?T("Database")},
+                {<<"backup/">>, ?T("Backup")},
+                {<<"stats/">>, ?T("Statistics")},
+                {<<"update/">>, ?T("Update")}]
                  ++ get_menu_items_hook({node, Node}, Lang),
     {NodeBase, iolist_to_binary(atom_to_list(Node)),
      NodeFixed};
@@ -1785,9 +1786,9 @@ make_node_menu(_Host, _Node, _Lang) ->
 
 make_server_menu(HostMenu, NodeMenu, Lang, JID) ->
     Base = get_base_path(global, cluster),
-    Fixed = [{<<"vhosts">>, <<"Virtual Hosts">>, HostMenu},
-            {<<"nodes">>, <<"Nodes">>, NodeMenu},
-            {<<"stats">>, <<"Statistics">>}]
+    Fixed = [{<<"vhosts">>, ?T("Virtual Hosts"), HostMenu},
+            {<<"nodes">>, ?T("Nodes"), NodeMenu},
+            {<<"stats">>, ?T("Statistics")}]
              ++ get_menu_items_hook(server, Lang),
     BasePath = url_to_path(Base),
     Fixed2 = [Tuple
index cd94f0575fcf3111c75fb3922a086ee957b0d36b..c0b7a9dd449c5f454eb41e0ec5c37a7b025bc3f7 100644 (file)
@@ -79,7 +79,7 @@ handle(Component,
        [{_, Module, Function}] ->
            process_iq(Host, Module, Function, Packet);
        [] ->
-           Txt = <<"No module is handling this query">>,
+           Txt = ?T("No module is handling this query"),
            Err = xmpp:err_service_unavailable(Txt, Lang),
            ejabberd_router:route_error(Packet, Err)
     end;
@@ -114,7 +114,7 @@ process_iq(_Host, Module, Function, IQ) ->
     catch ?EX_RULE(E, R, St) ->
            ?ERROR_MSG("failed to process iq:~n~s~nReason = ~p",
                       [xmpp:pp(IQ), {E, {R, ?EX_STACK(St)}}]),
-           Txt = <<"Module failed to handle the query">>,
+           Txt = ?T("Module failed to handle the query"),
            Err = xmpp:err_internal_server_error(Txt, IQ#iq.lang),
            ejabberd_router:route_error(IQ, Err)
     end.
index 528da91d64f8012487476f20e15d40b0c2df5edc..0f97a834d183639b2f6d7d95a04bd2031686eb4e 100644 (file)
@@ -40,6 +40,7 @@
 
 -include("logger.hrl").
 -include("xmpp.hrl").
+-include("translate.hrl").
 
 start(Host, _Opts) ->
     gen_iq_handler:add_iq_handler(ejabberd_local, Host,
@@ -103,7 +104,7 @@ get_local_commands(Acc, _From,
                  end,
          Nodes = [#disco_item{jid = jid:make(Server),
                               node = ?NS_COMMANDS,
-                              name = translate:translate(Lang, <<"Commands">>)}],
+                              name = translate:translate(Lang, ?T("Commands"))}],
          {result, Items ++ Nodes}
     end;
 get_local_commands(_Acc, From,
@@ -130,7 +131,7 @@ get_sm_commands(Acc, _From,
                  end,
          Nodes = [#disco_item{jid = To,
                               node = ?NS_COMMANDS,
-                              name = translate:translate(Lang, <<"Commands">>)}],
+                              name = translate:translate(Lang, ?T("Commands"))}],
          {result, Items ++ Nodes}
     end;
 get_sm_commands(_Acc, From,
@@ -146,12 +147,12 @@ get_local_identity(Acc, _From, _To, ?NS_COMMANDS,
                   Lang) ->
     [#identity{category = <<"automation">>,
               type = <<"command-list">>,
-              name = translate:translate(Lang, <<"Commands">>)}
+              name = translate:translate(Lang, ?T("Commands"))}
      | Acc];
 get_local_identity(Acc, _From, _To, <<"ping">>, Lang) ->
     [#identity{category = <<"automation">>,
               type = <<"command-node">>,
-              name = translate:translate(Lang, <<"Ping">>)}
+              name = translate:translate(Lang, ?T("Ping"))}
      | Acc];
 get_local_identity(Acc, _From, _To, _Node, _Lang) ->
     Acc.
@@ -162,7 +163,7 @@ get_local_identity(Acc, _From, _To, _Node, _Lang) ->
 get_sm_identity(Acc, _From, _To, ?NS_COMMANDS, Lang) ->
     [#identity{category = <<"automation">>,
               type = <<"command-list">>,
-              name = translate:translate(Lang, <<"Commands">>)}
+              name = translate:translate(Lang, ?T("Commands"))}
      | Acc];
 get_sm_identity(Acc, _From, _To, _Node, _Lang) -> Acc.
 
@@ -222,7 +223,7 @@ process_adhoc_request(#iq{from = From, to = To,
        ignore ->
            ignore;
        empty ->
-           Txt = <<"No hook has processed this command">>,
+           Txt = ?T("No hook has processed this command"),
            xmpp:make_error(IQ, xmpp:err_item_not_found(Txt, Lang));
        {error, Error} ->
            xmpp:make_error(IQ, Error);
@@ -242,7 +243,7 @@ ping_item(Acc, _From, #jid{server = Server} = _To,
            end,
     Nodes = [#disco_item{jid = jid:make(Server),
                         node = <<"ping">>,
-                        name = translate:translate(Lang, <<"Ping">>)}],
+                        name = translate:translate(Lang, ?T("Ping"))}],
     {result, Items ++ Nodes}.
 
 -spec ping_command(adhoc_command(), jid(), jid(), adhoc_command()) ->
@@ -257,9 +258,9 @@ ping_command(_Acc, _From, _To,
                 status = completed,
                 notes = [#adhoc_note{
                             type = info,
-                            data = translate:translate(Lang, <<"Pong">>)}]});
+                            data = translate:translate(Lang, ?T("Pong"))}]});
        true ->
-           Txt = <<"Incorrect value of 'action' attribute">>,
+           Txt = ?T("Incorrect value of 'action' attribute"),
            {error, xmpp:err_bad_request(Txt, Lang)}
     end;
 ping_command(Acc, _From, _To, _Request) -> Acc.
index f4df6fe4c3fdd50e616ae15ecbaf8577e6e38052..69251e665a6faa176bec397f1b118d9a26584d82 100644 (file)
@@ -53,6 +53,7 @@
 -include("logger.hrl").
 -include("xmpp.hrl").
 -include("mod_announce.hrl").
+-include("translate.hrl").
 
 -callback init(binary(), gen_mod:opts()) -> any().
 -callback import(binary(), binary(), [binary()]) -> ok.
@@ -236,7 +237,7 @@ disco_identity(Acc, _From, _To, Node, Lang) ->
 -define(INFO_RESULT(Allow, Feats, Lang),
        case Allow of
            deny ->
-               {error, xmpp:err_forbidden(<<"Access denied by service policy">>, Lang)};
+               {error, xmpp:err_forbidden(?T("Access denied by service policy"), Lang)};
            allow ->
                {result, Feats}
        end).
@@ -251,7 +252,7 @@ disco_features(Acc, From, #jid{lserver = LServer} = _To, <<"announce">>, Lang) -
            case {acl:match_rule(LServer, Access1, From),
                  acl:match_rule(global, Access2, From)} of
                {deny, deny} ->
-                   Txt = <<"Access denied by service policy">>,
+                   Txt = ?T("Access denied by service policy"),
                    {error, xmpp:err_forbidden(Txt, Lang)};
                _ ->
                    {result, []}
@@ -302,7 +303,7 @@ disco_features(Acc, From, #jid{lserver = LServer} = _To, Node, Lang) ->
 -define(ITEMS_RESULT(Allow, Items, Lang),
        case Allow of
            deny ->
-               {error, xmpp:err_forbidden(<<"Access denied by service policy">>, Lang)};
+               {error, xmpp:err_forbidden(?T("Access denied by service policy"), Lang)};
            allow ->
                {result, Items}
        end).
@@ -416,7 +417,7 @@ commands_result(Allow, From, To, Request) ->
     case Allow of
        deny ->
            Lang = Request#adhoc_command.lang,
-           {error, xmpp:err_forbidden(<<"Access denied by service policy">>, Lang)};
+           {error, xmpp:err_forbidden(?T("Access denied by service policy"), Lang)};
        allow ->
            announce_commands(From, To, Request)
     end.
@@ -487,7 +488,7 @@ announce_commands(From, To,
                    Err
            end;
        true ->
-           Txt = <<"Unexpected action">>,
+           Txt = ?T("Unexpected action"),
            {error, xmpp:err_bad_request(Txt, Lang)}
     end.
 
@@ -513,16 +514,16 @@ generate_adhoc_form(Lang, Node, ServerHost) ->
                 [#xdata_field{type = boolean,
                               var = <<"confirm">>,
                               label = translate:translate(
-                                        Lang, <<"Really delete message of the day?">>),
+                                        Lang, ?T("Really delete message of the day?")),
                               values = [<<"true">>]}];
            true ->
                 [#xdata_field{type = 'text-single',
                               var = <<"subject">>,
-                              label = translate:translate(Lang, <<"Subject">>),
+                              label = translate:translate(Lang, ?T("Subject")),
                               values = vvaluel(OldSubject)},
                  #xdata_field{type = 'text-multi',
                               var = <<"body">>,
-                              label = translate:translate(Lang, <<"Message body">>),
+                              label = translate:translate(Lang, ?T("Message body")),
                               values = vvaluel(OldBody)}]
         end,
     #xdata{type = form,
@@ -573,7 +574,7 @@ handle_adhoc_form(From, #jid{lserver = LServer} = To,
            %% An announce message with no body is definitely an operator error.
            %% Throw an error and give him/her a chance to send message again.
            {error, xmpp:err_not_acceptable(
-                     <<"No body provided for announce message">>, Lang)};
+                     ?T("No body provided for announce message"), Lang)};
        %% Now send the packet to ?MODULE.
        %% We don't use direct announce_* functions because it
        %% leads to large delay in response and <iq/> queries processing
@@ -601,27 +602,27 @@ handle_adhoc_form(From, #jid{lserver = LServer} = To,
     end.
 
 get_title(Lang, <<"announce">>) ->
-    translate:translate(Lang, <<"Announcements">>);
+    translate:translate(Lang, ?T("Announcements"));
 get_title(Lang, ?NS_ADMIN_ANNOUNCE_ALL) ->
-    translate:translate(Lang, <<"Send announcement to all users">>);
+    translate:translate(Lang, ?T("Send announcement to all users"));
 get_title(Lang, ?NS_ADMIN_ANNOUNCE_ALL_ALLHOSTS) ->
-    translate:translate(Lang, <<"Send announcement to all users on all hosts">>);
+    translate:translate(Lang, ?T("Send announcement to all users on all hosts"));
 get_title(Lang, ?NS_ADMIN_ANNOUNCE) ->
-    translate:translate(Lang, <<"Send announcement to all online users">>);
+    translate:translate(Lang, ?T("Send announcement to all online users"));
 get_title(Lang, ?NS_ADMIN_ANNOUNCE_ALLHOSTS) ->
-    translate:translate(Lang, <<"Send announcement to all online users on all hosts">>);
+    translate:translate(Lang, ?T("Send announcement to all online users on all hosts"));
 get_title(Lang, ?NS_ADMIN_SET_MOTD) ->
-    translate:translate(Lang, <<"Set message of the day and send to online users">>);
+    translate:translate(Lang, ?T("Set message of the day and send to online users"));
 get_title(Lang, ?NS_ADMIN_SET_MOTD_ALLHOSTS) ->
-    translate:translate(Lang, <<"Set message of the day on all hosts and send to online users">>);
+    translate:translate(Lang, ?T("Set message of the day on all hosts and send to online users"));
 get_title(Lang, ?NS_ADMIN_EDIT_MOTD) ->
-    translate:translate(Lang, <<"Update message of the day (don't send)">>);
+    translate:translate(Lang, ?T("Update message of the day (don't send)"));
 get_title(Lang, ?NS_ADMIN_EDIT_MOTD_ALLHOSTS) ->
-    translate:translate(Lang, <<"Update message of the day on all hosts (don't send)">>);
+    translate:translate(Lang, ?T("Update message of the day on all hosts (don't send)"));
 get_title(Lang, ?NS_ADMIN_DELETE_MOTD) ->
-    translate:translate(Lang, <<"Delete message of the day">>);
+    translate:translate(Lang, ?T("Delete message of the day"));
 get_title(Lang, ?NS_ADMIN_DELETE_MOTD_ALLHOSTS) ->
-    translate:translate(Lang, <<"Delete message of the day on all hosts">>).
+    translate:translate(Lang, ?T("Delete message of the day on all hosts")).
 
 %%-------------------------------------------------------------------------
 
@@ -838,7 +839,7 @@ add_store_hint(El) ->
 -spec route_forbidden_error(stanza()) -> ok.
 route_forbidden_error(Packet) ->
     Lang = xmpp:get_lang(Packet),
-    Err = xmpp:err_forbidden(<<"Access denied by service policy">>, Lang),
+    Err = xmpp:err_forbidden(?T("Access denied by service policy"), Lang),
     ejabberd_router:route_error(Packet, Err).
 
 -spec init_cache(module(), binary(), gen_mod:opts()) -> ok.
index 80504c9fb7c5f56c5d0b76b01a097d09ed6d29bd..5f59978a36bf42b70cd8a03b5588c3a07937fce9 100644 (file)
@@ -36,6 +36,7 @@
 
 -include("xmpp.hrl").
 -include("logger.hrl").
+-include("translate.hrl").
 
 -define(SETS, gb_sets).
 
@@ -117,11 +118,11 @@ filter_subscription(Acc, #presence{from = From, to = To, lang = Lang,
                            end,
                            ejabberd_router:route(Msg);
                        {error, limit} ->
-                           ErrText = <<"Too many CAPTCHA requests">>,
+                           ErrText = ?T("Too many CAPTCHA requests"),
                            Err = xmpp:err_resource_constraint(ErrText, Lang),
                            ejabberd_router:route_error(Pres, Err);
                        _ ->
-                           ErrText = <<"Unable to generate a CAPTCHA">>,
+                           ErrText = ?T("Unable to generate a CAPTCHA"),
                            Err = xmpp:err_internal_server_error(ErrText, Lang),
                            ejabberd_router:route_error(Pres, Err)
                    end,
@@ -139,7 +140,7 @@ handle_captcha_result(captcha_succeed, Pres) ->
     Pres1 = xmpp:put_meta(Pres, captcha, passed),
     ejabberd_router:route(Pres1);
 handle_captcha_result(captcha_failed, #presence{lang = Lang} = Pres) ->
-    Txt = <<"The CAPTCHA verification has failed">>,
+    Txt = ?T("The CAPTCHA verification has failed"),
     ejabberd_router:route_error(Pres, xmpp:err_not_allowed(Txt, Lang)).
 
 %%%===================================================================
@@ -165,7 +166,7 @@ check_message(#message{from = From, to = To, lang = Lang} = Msg) ->
                    end,
                    if
                        Drop ->
-                           Txt = <<"Messages from strangers are rejected">>,
+                           Txt = ?T("Messages from strangers are rejected"),
                            Err = xmpp:err_policy_violation(Txt, Lang),
                            Msg1 = maybe_adjust_from(Msg),
                            ejabberd_router:route_error(Msg1, Err),
index b1856c9370a98e320238aaced3e47032ce556563..233ce95aea8554cf2dca122bbf3d1b4c45cd499e 100644 (file)
         disco_features/5, mod_options/1]).
 
 -include("logger.hrl").
-
 -include("xmpp.hrl").
-
 -include("mod_privacy.hrl").
+-include("translate.hrl").
 
 start(Host, _Opts) ->
     ejabberd_hooks:add(disco_local_features, Host, ?MODULE, disco_features, 50),
@@ -74,21 +73,21 @@ process_iq(#iq{type = Type,
        set -> process_iq_set(IQ)
     end;
 process_iq(#iq{lang = Lang} = IQ) ->
-    Txt = <<"Query to another users is forbidden">>,
+    Txt = ?T("Query to another users is forbidden"),
     xmpp:make_error(IQ, xmpp:err_forbidden(Txt, Lang)).
 
 -spec process_iq_get(iq()) -> iq().
 process_iq_get(#iq{sub_els = [#block_list{}]} = IQ) ->
     process_get(IQ);
 process_iq_get(#iq{lang = Lang} = IQ) ->
-    Txt = <<"No module is handling this query">>,
+    Txt = ?T("No module is handling this query"),
     xmpp:make_error(IQ, xmpp:err_service_unavailable(Txt, Lang)).
 
 -spec process_iq_set(iq()) -> iq().
 process_iq_set(#iq{lang = Lang, sub_els = [SubEl]} = IQ) ->
     case SubEl of
        #block{items = []} ->
-           Txt = <<"No items found in this query">>,
+           Txt = ?T("No items found in this query"),
            xmpp:make_error(IQ, xmpp:err_bad_request(Txt, Lang));
        #block{items = Items} ->
            JIDs = [jid:tolower(JID) || #block_item{jid = JID} <- Items],
@@ -99,7 +98,7 @@ process_iq_set(#iq{lang = Lang, sub_els = [SubEl]} = IQ) ->
            JIDs = [jid:tolower(JID) || #block_item{jid = JID} <- Items],
            process_unblock(IQ, JIDs);
        _ ->
-           Txt = <<"No module is handling this query">>,
+           Txt = ?T("No module is handling this query"),
            xmpp:make_error(IQ, xmpp:err_service_unavailable(Txt, Lang))
     end.
 
@@ -260,7 +259,7 @@ process_get(#iq{from = #jid{luser = LUser, lserver = LServer}} = IQ) ->
     end.
 
 err_db_failure(#iq{lang = Lang} = IQ) ->
-    Txt = <<"Database failure">>,
+    Txt = ?T("Database failure"),
     xmpp:make_error(IQ, xmpp:err_internal_server_error(Txt, Lang)).
 
 mod_options(_Host) ->
index 4fe9540435e458848f52ad793cdcebc2d0399733..634d02be97e06a98ddd4aee8f12df029bfe7cabd 100644 (file)
@@ -44,6 +44,7 @@
 
 -include("logger.hrl").
 -include("xmpp.hrl").
+-include("translate.hrl").
 
 -type direction() :: sent | received.
 -type c2s_state() :: ejabberd_c2s:state().
@@ -102,14 +103,14 @@ iq_handler(#iq{type = set, lang = Lang, from = From,
        ok ->
            xmpp:make_iq_result(IQ);
        {error, _} ->
-           Txt = <<"Database failure">>,
+           Txt = ?T("Database failure"),
            xmpp:make_error(IQ, xmpp:err_internal_server_error(Txt, Lang))
     end;
 iq_handler(#iq{type = set, lang = Lang} = IQ) ->
-    Txt = <<"Only <enable/> or <disable/> tags are allowed">>,
+    Txt = ?T("Only <enable/> or <disable/> tags are allowed"),
     xmpp:make_error(IQ, xmpp:err_bad_request(Txt, Lang));
 iq_handler(#iq{type = get, lang = Lang} = IQ)->
-    Txt = <<"Value 'get' of 'type' attribute is not allowed">>,
+    Txt = ?T("Value 'get' of 'type' attribute is not allowed"),
     xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang)).
 
 -spec user_send_packet({stanza(), ejabberd_c2s:state()})
index 915fa4a87514fb0cd0d4ed9e5666a91035ea8680..ebdfadeebfbdf9a4927fbfa32325d1763352a55a 100644 (file)
 -include("logger.hrl").
 -include("xmpp.hrl").
 -include("ejabberd_sm.hrl").
+-include("translate.hrl").
 -include_lib("stdlib/include/ms_transform.hrl").
 
--define(T(Lang, Text), translate:translate(Lang, Text)).
-
 start(Host, _Opts) ->
     ejabberd_hooks:add(disco_local_items, Host, ?MODULE,
                       get_local_items, 50),
@@ -99,19 +98,19 @@ depends(_Host, _Opts) ->
 %%%-----------------------------------------------------------------------
 
 -define(INFO_IDENTITY(Category, Type, Name, Lang),
-       [#identity{category = Category, type = Type, name = ?T(Lang, Name)}]).
+       [#identity{category = Category, type = Type, name = tr(Lang, Name)}]).
 
 -define(INFO_COMMAND(Name, Lang),
        ?INFO_IDENTITY(<<"automation">>, <<"command-node">>,
                       Name, Lang)).
 
 -define(NODEJID(To, Name, Node),
-       #disco_item{jid = To, name = ?T(Lang, Name), node = Node}).
+       #disco_item{jid = To, name = tr(Lang, Name), node = Node}).
 
 -define(NODE(Name, Node),
        #disco_item{jid = jid:make(Server),
                    node = Node,
-                   name = ?T(Lang, Name)}).
+                   name = tr(Lang, Name)}).
 
 -define(NS_ADMINX(Sub),
        <<(?NS_ADMIN)/binary, "#", Sub/binary>>).
@@ -125,7 +124,7 @@ tokenize(Node) -> str:tokens(Node, <<"/#">>).
 get_sm_identity(Acc, _From, _To, Node, Lang) ->
     case Node of
       <<"config">> ->
-         ?INFO_COMMAND(<<"Configuration">>, Lang);
+         ?INFO_COMMAND(?T("Configuration"), Lang);
       _ -> Acc
     end.
 
@@ -135,51 +134,51 @@ get_local_identity(Acc, _From, _To, Node, Lang) ->
       [<<"running nodes">>, ENode] ->
          ?INFO_IDENTITY(<<"ejabberd">>, <<"node">>, ENode, Lang);
       [<<"running nodes">>, _ENode, <<"DB">>] ->
-         ?INFO_COMMAND(<<"Database">>, Lang);
+         ?INFO_COMMAND(?T("Database"), Lang);
       [<<"running nodes">>, _ENode, <<"modules">>,
        <<"start">>] ->
-         ?INFO_COMMAND(<<"Start Modules">>, Lang);
+         ?INFO_COMMAND(?T("Start Modules"), Lang);
       [<<"running nodes">>, _ENode, <<"modules">>,
        <<"stop">>] ->
-         ?INFO_COMMAND(<<"Stop Modules">>, Lang);
+         ?INFO_COMMAND(?T("Stop Modules"), Lang);
       [<<"running nodes">>, _ENode, <<"backup">>,
        <<"backup">>] ->
-         ?INFO_COMMAND(<<"Backup">>, Lang);
+         ?INFO_COMMAND(?T("Backup"), Lang);
       [<<"running nodes">>, _ENode, <<"backup">>,
        <<"restore">>] ->
-         ?INFO_COMMAND(<<"Restore">>, Lang);
+         ?INFO_COMMAND(?T("Restore"), Lang);
       [<<"running nodes">>, _ENode, <<"backup">>,
        <<"textfile">>] ->
-         ?INFO_COMMAND(<<"Dump to Text File">>, Lang);
+         ?INFO_COMMAND(?T("Dump to Text File"), Lang);
       [<<"running nodes">>, _ENode, <<"import">>,
        <<"file">>] ->
-         ?INFO_COMMAND(<<"Import File">>, Lang);
+         ?INFO_COMMAND(?T("Import File"), Lang);
       [<<"running nodes">>, _ENode, <<"import">>,
        <<"dir">>] ->
-         ?INFO_COMMAND(<<"Import Directory">>, Lang);
+         ?INFO_COMMAND(?T("Import Directory"), Lang);
       [<<"running nodes">>, _ENode, <<"restart">>] ->
-         ?INFO_COMMAND(<<"Restart Service">>, Lang);
+         ?INFO_COMMAND(?T("Restart Service"), Lang);
       [<<"running nodes">>, _ENode, <<"shutdown">>] ->
-         ?INFO_COMMAND(<<"Shut Down Service">>, Lang);
+         ?INFO_COMMAND(?T("Shut Down Service"), Lang);
       ?NS_ADMINL(<<"add-user">>) ->
-         ?INFO_COMMAND(<<"Add User">>, Lang);
+         ?INFO_COMMAND(?T("Add User"), Lang);
       ?NS_ADMINL(<<"delete-user">>) ->
-         ?INFO_COMMAND(<<"Delete User">>, Lang);
+         ?INFO_COMMAND(?T("Delete User"), Lang);
       ?NS_ADMINL(<<"end-user-session">>) ->
-         ?INFO_COMMAND(<<"End User Session">>, Lang);
+         ?INFO_COMMAND(?T("End User Session"), Lang);
       ?NS_ADMINL(<<"get-user-password">>) ->
-         ?INFO_COMMAND(<<"Get User Password">>, Lang);
+         ?INFO_COMMAND(?T("Get User Password"), Lang);
       ?NS_ADMINL(<<"change-user-password">>) ->
-         ?INFO_COMMAND(<<"Change User Password">>, Lang);
+         ?INFO_COMMAND(?T("Change User Password"), Lang);
       ?NS_ADMINL(<<"get-user-lastlogin">>) ->
-         ?INFO_COMMAND(<<"Get User Last Login Time">>, Lang);
+         ?INFO_COMMAND(?T("Get User Last Login Time"), Lang);
       ?NS_ADMINL(<<"user-stats">>) ->
-         ?INFO_COMMAND(<<"Get User Statistics">>, Lang);
+         ?INFO_COMMAND(?T("Get User Statistics"), Lang);
       ?NS_ADMINL(<<"get-registered-users-num">>) ->
-         ?INFO_COMMAND(<<"Get Number of Registered Users">>,
+         ?INFO_COMMAND(?T("Get Number of Registered Users"),
                        Lang);
       ?NS_ADMINL(<<"get-online-users-num">>) ->
-         ?INFO_COMMAND(<<"Get Number of Online Users">>, Lang);
+         ?INFO_COMMAND(?T("Get Number of Online Users"), Lang);
       _ -> Acc
     end.
 
@@ -187,7 +186,7 @@ get_local_identity(Acc, _From, _To, Node, Lang) ->
 
 -define(INFO_RESULT(Allow, Feats, Lang),
        case Allow of
-         deny -> {error, xmpp:err_forbidden(<<"Access denied by service policy">>, Lang)};
+         deny -> {error, xmpp:err_forbidden(?T("Access denied by service policy"), Lang)};
          allow -> {result, Feats}
        end).
 
@@ -278,7 +277,7 @@ adhoc_sm_items(Acc, From, #jid{lserver = LServer} = To,
                    empty -> []
                  end,
          Nodes = [#disco_item{jid = To, node = <<"config">>,
-                              name = ?T(Lang, <<"Configuration">>)}],
+                              name = tr(Lang, ?T("Configuration"))}],
          {result, Items ++ Nodes};
       _ -> Acc
     end.
@@ -298,14 +297,14 @@ get_sm_items(Acc, From,
                  end,
          case {acl:match_rule(LServer, configure, From), Node} of
            {allow, <<"">>} ->
-               Nodes = [?NODEJID(To, <<"Configuration">>,
+               Nodes = [?NODEJID(To, ?T("Configuration"),
                                  <<"config">>),
-                        ?NODEJID(To, <<"User Management">>, <<"user">>)],
+                        ?NODEJID(To, ?T("User Management"), <<"user">>)],
                {result,
                 Items ++ Nodes ++ get_user_resources(User, Server)};
            {allow, <<"config">>} -> {result, []};
            {_, <<"config">>} ->
-                 {error, xmpp:err_forbidden(<<"Access denied by service policy">>, Lang)};
+                 {error, xmpp:err_forbidden(?T("Access denied by service policy"), Lang)};
            _ -> Acc
          end
     end.
@@ -427,7 +426,7 @@ get_local_items(Acc, From, #jid{lserver = LServer} = To,
       _ ->
          LNode = tokenize(Node),
          Allow = acl:match_rule(LServer, configure, From),
-         Err = xmpp:err_forbidden(<<"Access denied by service policy">>, Lang),
+         Err = xmpp:err_forbidden(?T("Access denied by service policy"), Lang),
          case LNode of
            [<<"config">>] ->
                ?ITEMS_RESULT(Allow, LNode, {error, Err});
@@ -496,35 +495,35 @@ get_local_items(Acc, From, #jid{lserver = LServer} = To,
 %%       PermissionLevel = global | vhost
 get_local_items(_Host, [], Server, Lang) ->
     {result,
-     [?NODE(<<"Configuration">>, <<"config">>),
-      ?NODE(<<"User Management">>, <<"user">>),
-      ?NODE(<<"Online Users">>, <<"online users">>),
-      ?NODE(<<"All Users">>, <<"all users">>),
-      ?NODE(<<"Outgoing s2s Connections">>,
+     [?NODE(?T("Configuration"), <<"config">>),
+      ?NODE(?T("User Management"), <<"user">>),
+      ?NODE(?T("Online Users"), <<"online users">>),
+      ?NODE(?T("All Users"), <<"all users">>),
+      ?NODE(?T("Outgoing s2s Connections"),
            <<"outgoing s2s">>),
-      ?NODE(<<"Running Nodes">>, <<"running nodes">>),
-      ?NODE(<<"Stopped Nodes">>, <<"stopped nodes">>)]};
+      ?NODE(?T("Running Nodes"), <<"running nodes">>),
+      ?NODE(?T("Stopped Nodes"), <<"stopped nodes">>)]};
 get_local_items(_Host, [<<"config">>, _], _Server,
                _Lang) ->
     {result, []};
 get_local_items(_Host, [<<"user">>], Server, Lang) ->
     {result,
-     [?NODE(<<"Add User">>, (?NS_ADMINX(<<"add-user">>))),
-      ?NODE(<<"Delete User">>,
+     [?NODE(?T("Add User"), (?NS_ADMINX(<<"add-user">>))),
+      ?NODE(?T("Delete User"),
            (?NS_ADMINX(<<"delete-user">>))),
-      ?NODE(<<"End User Session">>,
+      ?NODE(?T("End User Session"),
            (?NS_ADMINX(<<"end-user-session">>))),
-      ?NODE(<<"Get User Password">>,
+      ?NODE(?T("Get User Password"),
            (?NS_ADMINX(<<"get-user-password">>))),
-      ?NODE(<<"Change User Password">>,
+      ?NODE(?T("Change User Password"),
            (?NS_ADMINX(<<"change-user-password">>))),
-      ?NODE(<<"Get User Last Login Time">>,
+      ?NODE(?T("Get User Last Login Time"),
            (?NS_ADMINX(<<"get-user-lastlogin">>))),
-      ?NODE(<<"Get User Statistics">>,
+      ?NODE(?T("Get User Statistics"),
            (?NS_ADMINX(<<"user-stats">>))),
-      ?NODE(<<"Get Number of Registered Users">>,
+      ?NODE(?T("Get Number of Registered Users"),
            (?NS_ADMINX(<<"get-registered-users-num">>))),
-      ?NODE(<<"Get Number of Online Users">>,
+      ?NODE(?T("Get Number of Online Users"),
            (?NS_ADMINX(<<"get-online-users-num">>)))]};
 get_local_items(_Host, [<<"http:">> | _], _Server,
                _Lang) ->
@@ -568,22 +567,22 @@ get_local_items(_Host, [<<"stopped nodes">>], _Server,
 get_local_items({global, _Host},
                [<<"running nodes">>, ENode], Server, Lang) ->
     {result,
-     [?NODE(<<"Database">>,
+     [?NODE(?T("Database"),
            <<"running nodes/", ENode/binary, "/DB">>),
-      ?NODE(<<"Modules">>,
+      ?NODE(?T("Modules"),
            <<"running nodes/", ENode/binary, "/modules">>),
-      ?NODE(<<"Backup Management">>,
+      ?NODE(?T("Backup Management"),
            <<"running nodes/", ENode/binary, "/backup">>),
-      ?NODE(<<"Import Users From jabberd14 Spool Files">>,
+      ?NODE(?T("Import Users From jabberd14 Spool Files"),
            <<"running nodes/", ENode/binary, "/import">>),
-      ?NODE(<<"Restart Service">>,
+      ?NODE(?T("Restart Service"),
            <<"running nodes/", ENode/binary, "/restart">>),
-      ?NODE(<<"Shut Down Service">>,
+      ?NODE(?T("Shut Down Service"),
            <<"running nodes/", ENode/binary, "/shutdown">>)]};
 get_local_items({vhost, _Host},
                [<<"running nodes">>, ENode], Server, Lang) ->
     {result,
-     [?NODE(<<"Modules">>,
+     [?NODE(?T("Modules"),
            <<"running nodes/", ENode/binary, "/modules">>)]};
 get_local_items(_Host,
                [<<"running nodes">>, _ENode, <<"DB">>], _Server,
@@ -593,9 +592,9 @@ get_local_items(_Host,
                [<<"running nodes">>, ENode, <<"modules">>], Server,
                Lang) ->
     {result,
-     [?NODE(<<"Start Modules">>,
+     [?NODE(?T("Start Modules"),
            <<"running nodes/", ENode/binary, "/modules/start">>),
-      ?NODE(<<"Stop Modules">>,
+      ?NODE(?T("Stop Modules"),
            <<"running nodes/", ENode/binary, "/modules/stop">>)]};
 get_local_items(_Host,
                [<<"running nodes">>, _ENode, <<"modules">>, _],
@@ -605,11 +604,11 @@ get_local_items(_Host,
                [<<"running nodes">>, ENode, <<"backup">>], Server,
                Lang) ->
     {result,
-     [?NODE(<<"Backup">>,
+     [?NODE(?T("Backup"),
            <<"running nodes/", ENode/binary, "/backup/backup">>),
-      ?NODE(<<"Restore">>,
+      ?NODE(?T("Restore"),
            <<"running nodes/", ENode/binary, "/backup/restore">>),
-      ?NODE(<<"Dump to Text File">>,
+      ?NODE(?T("Dump to Text File"),
            <<"running nodes/", ENode/binary,
              "/backup/textfile">>)]};
 get_local_items(_Host,
@@ -620,9 +619,9 @@ get_local_items(_Host,
                [<<"running nodes">>, ENode, <<"import">>], Server,
                Lang) ->
     {result,
-     [?NODE(<<"Import File">>,
+     [?NODE(?T("Import File"),
            <<"running nodes/", ENode/binary, "/import/file">>),
-      ?NODE(<<"Import Directory">>,
+      ?NODE(?T("Import Directory"),
            <<"running nodes/", ENode/binary, "/import/dir">>)]};
 get_local_items(_Host,
                [<<"running nodes">>, _ENode, <<"import">>, _], _Server,
@@ -697,7 +696,7 @@ get_outgoing_s2s(Host, Lang) ->
                       Host == FH orelse str:suffix(DotHost, FH)],
          lists:map(
            fun (T) ->
-                   Name = str:format(?T(Lang, <<"To ~s">>),[T]),
+                   Name = str:format(tr(Lang, ?T("To ~s")),[T]),
                    #disco_item{jid = jid:make(Host),
                                node = <<"outgoing s2s/", T/binary>>,
                                name = Name}
@@ -711,7 +710,7 @@ get_outgoing_s2s(Host, Lang, To) ->
          lists:map(
            fun ({F, _T}) ->
                    Node = <<"outgoing s2s/", To/binary, "/", F/binary>>,
-                   Name = str:format(?T(Lang, <<"From ~s">>), [F]),
+                   Name = str:format(tr(Lang, ?T("From ~s")), [F]),
                    #disco_item{jid = jid:make(Host), node = Node, name = Name}
            end,
            lists:keysort(1,
@@ -756,7 +755,7 @@ get_stopped_nodes(_Lang) ->
 -define(COMMANDS_RESULT(LServerOrGlobal, From, To,
                        Request, Lang),
        case acl:match_rule(LServerOrGlobal, configure, From) of
-         deny -> {error, xmpp:err_forbidden(<<"Access denied by service policy">>, Lang)};
+         deny -> {error, xmpp:err_forbidden(?T("Access denied by service policy"), Lang)};
          allow -> adhoc_local_commands(From, To, Request)
        end).
 
@@ -818,7 +817,7 @@ adhoc_local_commands(From,
                {error, Error} -> {error, Error}
            end;
        true ->
-         {error, xmpp:err_bad_request(<<"Unexpected action">>, Lang)}
+         {error, xmpp:err_bad_request(?T("Unexpected action"), Lang)}
     end.
 
 -define(TVFIELD(Type, Var, Val),
@@ -828,14 +827,14 @@ adhoc_local_commands(From,
        ?TVFIELD(hidden, <<"FORM_TYPE">>, (?NS_ADMIN))).
 
 -define(TLFIELD(Type, Label, Var),
-       #xdata_field{type = Type, label = ?T(Lang, Label), var = Var}).
+       #xdata_field{type = Type, label = tr(Lang, Label), var = Var}).
 
 -define(XFIELD(Type, Label, Var, Val),
-       #xdata_field{type = Type, label = ?T(Lang, Label),
+       #xdata_field{type = Type, label = tr(Lang, Label),
                     var = Var, values = [Val]}).
 
 -define(XMFIELD(Type, Label, Var, Vals),
-       #xdata_field{type = Type, label = ?T(Lang, Label),
+       #xdata_field{type = Type, label = tr(Lang, Label),
                     var = Var, values = Vals}).
 
 -define(TABLEFIELD(Table, Val),
@@ -844,20 +843,20 @@ adhoc_local_commands(From,
           label = iolist_to_binary(atom_to_list(Table)),
           var = iolist_to_binary(atom_to_list(Table)),
           values = [iolist_to_binary(atom_to_list(Val))],
-          options = [#xdata_option{label = ?T(Lang, <<"RAM copy">>),
+          options = [#xdata_option{label = tr(Lang, ?T("RAM copy")),
                                    value = <<"ram_copies">>},
-                     #xdata_option{label = ?T(Lang, <<"RAM and disc copy">>),
+                     #xdata_option{label = tr(Lang, ?T("RAM and disc copy")),
                                    value = <<"disc_copies">>},
-                     #xdata_option{label = ?T(Lang, <<"Disc only copy">>),
+                     #xdata_option{label = tr(Lang, ?T("Disc only copy")),
                                    value =  <<"disc_only_copies">>},
-                     #xdata_option{label = ?T(Lang, <<"Remote copy">>),
+                     #xdata_option{label = tr(Lang, ?T("Remote copy")),
                                    value = <<"unknown">>}]}).
 
 get_form(_Host, [<<"running nodes">>, ENode, <<"DB">>],
         Lang) ->
     case search_running_node(ENode) of
       false ->
-         Txt = <<"No running node found">>,
+         Txt = ?T("No running node found"),
          {error, xmpp:err_item_not_found(Txt, Lang)};
       Node ->
          case ejabberd_cluster:call(Node, mnesia, system_info, [tables]) of
@@ -867,9 +866,9 @@ get_form(_Host, [<<"running nodes">>, ENode, <<"DB">>],
                {error, xmpp:err_internal_server_error()};
            Tables ->
                STables = lists:sort(Tables),
-               Title = <<(?T(Lang, <<"Database Tables Configuration at ">>))/binary,
+               Title = <<(tr(Lang, ?T("Database Tables Configuration at ")))/binary,
                          ENode/binary>>,
-               Instr = ?T(Lang, <<"Choose storage type of tables">>),
+               Instr = tr(Lang, ?T("Choose storage type of tables")),
                try
                    Fs = lists:map(
                           fun(Table) ->
@@ -896,7 +895,7 @@ get_form(Host,
         Lang) ->
     case search_running_node(ENode) of
       false ->
-         Txt = <<"No running node found">>,
+         Txt = ?T("No running node found"),
          {error, xmpp:err_item_not_found(Txt, Lang)};
       Node ->
          case ejabberd_cluster:call(Node, gen_mod, loaded_modules, [Host]) of
@@ -906,9 +905,9 @@ get_form(Host,
                {error, xmpp:err_internal_server_error()};
            Modules ->
                SModules = lists:sort(Modules),
-               Title = <<(?T(Lang, <<"Stop Modules at ">>))/binary,
+               Title = <<(tr(Lang, ?T("Stop Modules at ")))/binary,
                          ENode/binary>>,
-               Instr = ?T(Lang, <<"Choose modules to stop">>),
+               Instr = tr(Lang, ?T("Choose modules to stop")),
                Fs = lists:map(fun(M) ->
                                       S = misc:atom_to_binary(M),
                                       ?XFIELD(boolean, S, S, <<"0">>)
@@ -924,85 +923,85 @@ get_form(_Host,
          <<"start">>],
         Lang) ->
     {result,
-     #xdata{title = <<(?T(Lang, <<"Start Modules at ">>))/binary, ENode/binary>>,
+     #xdata{title = <<(tr(Lang, ?T("Start Modules at ")))/binary, ENode/binary>>,
            type = form,
-           instructions = [?T(Lang, <<"Enter list of {Module, [Options]}">>)],
+           instructions = [tr(Lang, ?T("Enter list of {Module, [Options]}"))],
            fields = [?HFIELD(),
                      ?XFIELD('text-multi',
-                             <<"List of modules to start">>, <<"modules">>,
+                             ?T("List of modules to start"), <<"modules">>,
                              <<"[].">>)]}};
 get_form(_Host,
         [<<"running nodes">>, ENode, <<"backup">>,
          <<"backup">>],
         Lang) ->
     {result,
-     #xdata{title = <<(?T(Lang, <<"Backup to File at ">>))/binary, ENode/binary>>,
+     #xdata{title = <<(tr(Lang, ?T("Backup to File at ")))/binary, ENode/binary>>,
            type = form,
-           instructions = [?T(Lang, <<"Enter path to backup file">>)],
+           instructions = [tr(Lang, ?T("Enter path to backup file"))],
            fields = [?HFIELD(),
-                     ?XFIELD('text-single', <<"Path to File">>,
+                     ?XFIELD('text-single', ?T("Path to File"),
                              <<"path">>, <<"">>)]}};
 get_form(_Host,
         [<<"running nodes">>, ENode, <<"backup">>,
          <<"restore">>],
         Lang) ->
     {result,
-     #xdata{title = <<(?T(Lang, <<"Restore Backup from File at ">>))/binary,
+     #xdata{title = <<(tr(Lang, ?T("Restore Backup from File at ")))/binary,
                      ENode/binary>>,
            type = form,
-           instructions = [?T(Lang, <<"Enter path to backup file">>)],
+           instructions = [tr(Lang, ?T("Enter path to backup file"))],
            fields = [?HFIELD(),
-                     ?XFIELD('text-single', <<"Path to File">>,
+                     ?XFIELD('text-single', ?T("Path to File"),
                              <<"path">>, <<"">>)]}};
 get_form(_Host,
         [<<"running nodes">>, ENode, <<"backup">>,
          <<"textfile">>],
         Lang) ->
     {result,
-     #xdata{title = <<(?T(Lang, <<"Dump Backup to Text File at ">>))/binary,
+     #xdata{title = <<(tr(Lang, ?T("Dump Backup to Text File at ")))/binary,
                      ENode/binary>>,
            type = form,
-           instructions = [?T(Lang, <<"Enter path to text file">>)],
+           instructions = [tr(Lang, ?T("Enter path to text file"))],
            fields = [?HFIELD(),
-                     ?XFIELD('text-single', <<"Path to File">>,
+                     ?XFIELD('text-single', ?T("Path to File"),
                              <<"path">>, <<"">>)]}};
 get_form(_Host,
         [<<"running nodes">>, ENode, <<"import">>, <<"file">>],
         Lang) ->
     {result,
-     #xdata{title = <<(?T(Lang, <<"Import User from File at ">>))/binary,
+     #xdata{title = <<(tr(Lang, ?T("Import User from File at ")))/binary,
                      ENode/binary>>,
            type = form,
-           instructions = [?T(Lang, <<"Enter path to jabberd14 spool file">>)],
+           instructions = [tr(Lang, ?T("Enter path to jabberd14 spool file"))],
            fields = [?HFIELD(),
-                     ?XFIELD('text-single', <<"Path to File">>,
+                     ?XFIELD('text-single', ?T("Path to File"),
                              <<"path">>, <<"">>)]}};
 get_form(_Host,
         [<<"running nodes">>, ENode, <<"import">>, <<"dir">>],
         Lang) ->
     {result,
-     #xdata{title = <<(?T(Lang, <<"Import Users from Dir at ">>))/binary,
+     #xdata{title = <<(tr(Lang, ?T("Import Users from Dir at ")))/binary,
                      ENode/binary>>,
            type = form,
-           instructions = [?T(Lang, <<"Enter path to jabberd14 spool dir">>)],
+           instructions = [tr(Lang, ?T("Enter path to jabberd14 spool dir"))],
            fields = [?HFIELD(),
-                     ?XFIELD('text-single', <<"Path to Dir">>,
+                     ?XFIELD('text-single', ?T("Path to Dir"),
                              <<"path">>, <<"">>)]}};
 get_form(_Host,
         [<<"running nodes">>, _ENode, <<"restart">>], Lang) ->
     Make_option =
        fun (LabelNum, LabelUnit, Value) ->
                #xdata_option{
-                  label = <<LabelNum/binary, (?T(Lang, LabelUnit))/binary>>,
+                  label = <<LabelNum/binary, (tr(Lang, LabelUnit))/binary>>,
                   value = Value}
        end,
     {result,
-     #xdata{title = ?T(Lang, <<"Restart Service">>),
+     #xdata{title = tr(Lang, ?T("Restart Service")),
            type = form,
            fields = [?HFIELD(),
                      #xdata_field{
                         type = 'list-single',
-                        label = ?T(Lang, <<"Time delay">>),
+                        label = tr(Lang, ?T("Time delay")),
                         var = <<"delay">>,
                         required = true,
                         options =
@@ -1019,30 +1018,30 @@ get_form(_Host,
                              Make_option(<<"15 ">>, <<"minutes">>, <<"900">>),
                              Make_option(<<"30 ">>, <<"minutes">>, <<"1800">>)]},
                      #xdata_field{type = fixed,
-                                  label = ?T(Lang,
-                                             <<"Send announcement to all online users "
-                                               "on all hosts">>)},
+                                  label = tr(Lang,
+                                             ?T("Send announcement to all online users "
+                                                "on all hosts"))},
                      #xdata_field{var = <<"subject">>,
                                   type = 'text-single',
-                                  label = ?T(Lang, <<"Subject">>)},
+                                  label = tr(Lang, ?T("Subject"))},
                      #xdata_field{var = <<"announcement">>,
                                   type = 'text-multi',
-                                  label = ?T(Lang, <<"Message body">>)}]}};
+                                  label = tr(Lang, ?T("Message body"))}]}};
 get_form(_Host,
         [<<"running nodes">>, _ENode, <<"shutdown">>], Lang) ->
     Make_option =
        fun (LabelNum, LabelUnit, Value) ->
                #xdata_option{
-                  label = <<LabelNum/binary, (?T(Lang, LabelUnit))/binary>>,
+                  label = <<LabelNum/binary, (tr(Lang, LabelUnit))/binary>>,
                   value = Value}
        end,
     {result,
-     #xdata{title = ?T(Lang, <<"Shut Down Service">>),
+     #xdata{title = tr(Lang, ?T("Shut Down Service")),
            type = form,
            fields = [?HFIELD(),
                      #xdata_field{
                         type = 'list-single',
-                        label = ?T(Lang, <<"Time delay">>),
+                        label = tr(Lang, ?T("Time delay")),
                         var = <<"delay">>,
                         required = true,
                         options =
@@ -1059,92 +1058,92 @@ get_form(_Host,
                              Make_option(<<"15 ">>, <<"minutes">>, <<"900">>),
                              Make_option(<<"30 ">>, <<"minutes">>, <<"1800">>)]},
                      #xdata_field{type = fixed,
-                                  label = ?T(Lang,
-                                             <<"Send announcement to all online users "
-                                               "on all hosts">>)},
+                                  label = tr(Lang,
+                                             ?T("Send announcement to all online users "
+                                                "on all hosts"))},
                      #xdata_field{var = <<"subject">>,
                                   type = 'text-single',
-                                  label = ?T(Lang, <<"Subject">>)},
+                                  label = tr(Lang, ?T("Subject"))},
                      #xdata_field{var = <<"announcement">>,
                                   type = 'text-multi',
-                                  label = ?T(Lang, <<"Message body">>)}]}};
+                                  label = tr(Lang, ?T("Message body"))}]}};
 get_form(_Host, ?NS_ADMINL(<<"add-user">>), Lang) ->
     {result,
-     #xdata{title = ?T(Lang, <<"Add User">>),
+     #xdata{title = tr(Lang, ?T("Add User")),
            type = form,
            fields = [?HFIELD(),
                      #xdata_field{type = 'jid-single',
-                                  label = ?T(Lang, <<"Jabber ID">>),
+                                  label = tr(Lang, ?T("Jabber ID")),
                                   required = true,
                                   var = <<"accountjid">>},
                      #xdata_field{type = 'text-private',
-                                  label = ?T(Lang, <<"Password">>),
+                                  label = tr(Lang, ?T("Password")),
                                   required = true,
                                   var = <<"password">>},
                      #xdata_field{type = 'text-private',
-                                  label = ?T(Lang, <<"Password Verification">>),
+                                  label = tr(Lang, ?T("Password Verification")),
                                   required = true,
                                   var = <<"password-verify">>}]}};
 get_form(_Host, ?NS_ADMINL(<<"delete-user">>), Lang) ->
     {result,
-     #xdata{title = ?T(Lang, <<"Delete User">>),
+     #xdata{title = tr(Lang, ?T("Delete User")),
            type = form,
            fields = [?HFIELD(),
                      #xdata_field{type = 'jid-multi',
-                                  label = ?T(Lang, <<"Jabber ID">>),
+                                  label = tr(Lang, ?T("Jabber ID")),
                                   required = true,
                                   var = <<"accountjids">>}]}};
 get_form(_Host, ?NS_ADMINL(<<"end-user-session">>),
         Lang) ->
     {result,
-     #xdata{title = ?T(Lang, <<"End User Session">>),
+     #xdata{title = tr(Lang, ?T("End User Session")),
            type = form,
            fields = [?HFIELD(),
                      #xdata_field{type = 'jid-single',
-                                  label = ?T(Lang, <<"Jabber ID">>),
+                                  label = tr(Lang, ?T("Jabber ID")),
                                   required = true,
                                   var = <<"accountjid">>}]}};
 get_form(_Host, ?NS_ADMINL(<<"get-user-password">>),
         Lang) ->
     {result,
-     #xdata{title = ?T(Lang, <<"Get User Password">>),
+     #xdata{title = tr(Lang, ?T("Get User Password")),
            type = form,
            fields = [?HFIELD(),
                      #xdata_field{type = 'jid-single',
-                                  label = ?T(Lang, <<"Jabber ID">>),
+                                  label = tr(Lang, ?T("Jabber ID")),
                                   var = <<"accountjid">>,
                                   required = true}]}};
 get_form(_Host, ?NS_ADMINL(<<"change-user-password">>),
         Lang) ->
     {result,
-     #xdata{title = ?T(Lang, <<"Change User Password">>),
+     #xdata{title = tr(Lang, ?T("Change User Password")),
            type = form,
            fields = [?HFIELD(),
                      #xdata_field{type = 'jid-single',
-                                  label = ?T(Lang, <<"Jabber ID">>),
+                                  label = tr(Lang, ?T("Jabber ID")),
                                   required = true,
                                   var = <<"accountjid">>},
                      #xdata_field{type = 'text-private',
-                                  label = ?T(Lang, <<"Password">>),
+                                  label = tr(Lang, ?T("Password")),
                                   required = true,
                                   var = <<"password">>}]}};
 get_form(_Host, ?NS_ADMINL(<<"get-user-lastlogin">>),
         Lang) ->
     {result,
-     #xdata{title = ?T(Lang, <<"Get User Last Login Time">>),
+     #xdata{title = tr(Lang, ?T("Get User Last Login Time")),
            type = form,
            fields = [?HFIELD(),
                      #xdata_field{type = 'jid-single',
-                                  label = ?T(Lang, <<"Jabber ID">>),
+                                  label = tr(Lang, ?T("Jabber ID")),
                                   var = <<"accountjid">>,
                                   required = true}]}};
 get_form(_Host, ?NS_ADMINL(<<"user-stats">>), Lang) ->
     {result,
-     #xdata{title = ?T(Lang, <<"Get User Statistics">>),
+     #xdata{title = tr(Lang, ?T("Get User Statistics")),
            type = form,
            fields = [?HFIELD(),
                      #xdata_field{type = 'jid-single',
-                                  label = ?T(Lang, <<"Jabber ID">>),
+                                  label = tr(Lang, ?T("Jabber ID")),
                                   var = <<"accountjid">>,
                                   required = true}]}};
 get_form(Host,
@@ -1154,7 +1153,7 @@ get_form(Host,
      #xdata{type = form,
            fields = [?HFIELD(),
                      #xdata_field{type = 'text-single',
-                                  label = ?T(Lang, <<"Number of registered users">>),
+                                  label = tr(Lang, ?T("Number of registered users")),
                                   var = <<"registeredusersnum">>,
                                   values = [Num]}]}};
 get_form(Host, ?NS_ADMINL(<<"get-online-users-num">>),
@@ -1164,7 +1163,7 @@ get_form(Host, ?NS_ADMINL(<<"get-online-users-num">>),
      #xdata{type = form,
            fields = [?HFIELD(),
                      #xdata_field{type = 'text-single',
-                                  label = ?T(Lang, <<"Number of online users">>),
+                                  label = tr(Lang, ?T("Number of online users")),
                                   var = <<"onlineusersnum">>,
                                   values = [Num]}]}};
 get_form(_Host, _, _Lang) ->
@@ -1174,7 +1173,7 @@ set_form(_From, _Host,
         [<<"running nodes">>, ENode, <<"DB">>], Lang, XData) ->
     case search_running_node(ENode) of
       false ->
-         Txt = <<"No running node found">>,
+         Txt = ?T("No running node found"),
          {error, xmpp:err_item_not_found(Txt, Lang)};
       Node ->
          lists:foreach(
@@ -1206,7 +1205,7 @@ set_form(_From, Host,
         Lang, XData) ->
     case search_running_node(ENode) of
       false ->
-         Txt = <<"No running node found">>,
+         Txt = ?T("No running node found"),
          {error, xmpp:err_item_not_found(Txt, Lang)};
       Node ->
          lists:foreach(
@@ -1227,12 +1226,12 @@ set_form(_From, Host,
         Lang, XData) ->
     case search_running_node(ENode) of
        false ->
-           Txt = <<"No running node found">>,
+           Txt = ?T("No running node found"),
            {error, xmpp:err_item_not_found(Txt, Lang)};
        Node ->
            case xmpp_util:get_xdata_values(<<"modules">>, XData) of
                [] ->
-                   Txt = <<"No 'modules' found in data form">>,
+                   Txt = ?T("No 'modules' found in data form"),
                    {error, xmpp:err_bad_request(Txt, Lang)};
                Strings ->
                    String = lists:foldl(fun (S, Res) ->
@@ -1251,11 +1250,11 @@ set_form(_From, Host,
                                      Modules),
                                    {result, undefined};
                                _ ->
-                                   Txt = <<"Parse failed">>,
+                                   Txt = ?T("Parse failed"),
                                    {error, xmpp:err_bad_request(Txt, Lang)}
                            end;
                        _ ->
-                           Txt = <<"Scan failed">>,
+                           Txt = ?T("Scan failed"),
                            {error, xmpp:err_bad_request(Txt, Lang)}
                    end
            end
@@ -1266,12 +1265,12 @@ set_form(_From, _Host,
         Lang, XData) ->
     case search_running_node(ENode) of
        false ->
-           Txt = <<"No running node found">>,
+           Txt = ?T("No running node found"),
            {error, xmpp:err_item_not_found(Txt, Lang)};
        Node ->
            case xmpp_util:get_xdata_values(<<"path">>, XData) of
                [] ->
-                   Txt = <<"No 'path' found in data form">>,
+                   Txt = ?T("No 'path' found in data form"),
                    {error, xmpp:err_bad_request(Txt, Lang)};
                [String] ->
                    case ejabberd_cluster:call(Node, mnesia, backup, [String]) of
@@ -1287,7 +1286,7 @@ set_form(_From, _Host,
                            {result, undefined}
                    end;
                _ ->
-                   Txt = <<"Incorrect value of 'path' in data form">>,
+                   Txt = ?T("Incorrect value of 'path' in data form"),
                    {error, xmpp:err_bad_request(Txt, Lang)}
            end
     end;
@@ -1297,12 +1296,12 @@ set_form(_From, _Host,
         Lang, XData) ->
     case search_running_node(ENode) of
        false ->
-           Txt = <<"No running node found">>,
+           Txt = ?T("No running node found"),
            {error, xmpp:err_item_not_found(Txt, Lang)};
        Node ->
            case xmpp_util:get_xdata_values(<<"path">>, XData) of
                [] ->
-                   Txt = <<"No 'path' found in data form">>,
+                   Txt = ?T("No 'path' found in data form"),
                    {error, xmpp:err_bad_request(Txt, Lang)};
                [String] ->
                    case ejabberd_cluster:call(Node, ejabberd_admin,
@@ -1319,7 +1318,7 @@ set_form(_From, _Host,
                            {result, undefined}
                    end;
                _ ->
-                   Txt = <<"Incorrect value of 'path' in data form">>,
+                   Txt = ?T("Incorrect value of 'path' in data form"),
                    {error, xmpp:err_bad_request(Txt, Lang)}
            end
     end;
@@ -1329,12 +1328,12 @@ set_form(_From, _Host,
         Lang, XData) ->
     case search_running_node(ENode) of
        false ->
-           Txt = <<"No running node found">>,
+           Txt = ?T("No running node found"),
            {error, xmpp:err_item_not_found(Txt, Lang)};
        Node ->
            case xmpp_util:get_xdata_values(<<"path">>, XData) of
                [] ->
-                   Txt = <<"No 'path' found in data form">>,
+                   Txt = ?T("No 'path' found in data form"),
                    {error, xmpp:err_bad_request(Txt, Lang)};
                [String] ->
                    case ejabberd_cluster:call(Node, ejabberd_admin,
@@ -1351,7 +1350,7 @@ set_form(_From, _Host,
                            {result, undefined}
                    end;
                _ ->
-                   Txt = <<"Incorrect value of 'path' in data form">>,
+                   Txt = ?T("Incorrect value of 'path' in data form"),
                    {error, xmpp:err_bad_request(Txt, Lang)}
            end
     end;
@@ -1360,18 +1359,18 @@ set_form(_From, _Host,
         Lang, XData) ->
     case search_running_node(ENode) of
        false ->
-           Txt = <<"No running node found">>,
+           Txt = ?T("No running node found"),
            {error, xmpp:err_item_not_found(Txt, Lang)};
        Node ->
            case xmpp_util:get_xdata_values(<<"path">>, XData) of
                [] ->
-                   Txt = <<"No 'path' found in data form">>,
+                   Txt = ?T("No 'path' found in data form"),
                    {error, xmpp:err_bad_request(Txt, Lang)};
                [String] ->
                    ejabberd_cluster:call(Node, jd2ejd, import_file, [String]),
                    {result, undefined};
                _ ->
-                   Txt = <<"Incorrect value of 'path' in data form">>,
+                   Txt = ?T("Incorrect value of 'path' in data form"),
                    {error, xmpp:err_bad_request(Txt, Lang)}
            end
     end;
@@ -1380,18 +1379,18 @@ set_form(_From, _Host,
         Lang, XData) ->
     case search_running_node(ENode) of
        false ->
-           Txt = <<"No running node found">>,
+           Txt = ?T("No running node found"),
            {error, xmpp:err_item_not_found(Txt, Lang)};
        Node ->
            case xmpp_util:get_xdata_values(<<"path">>, XData) of
                [] ->
-                   Txt = <<"No 'path' found in data form">>,
+                   Txt = ?T("No 'path' found in data form"),
                    {error, xmpp:err_bad_request(Txt, Lang)};
                [String] ->
                    ejabberd_cluster:call(Node, jd2ejd, import_dir, [String]),
                    {result, undefined};
                _ ->
-                   Txt = <<"Incorrect value of 'path' in data form">>,
+                   Txt = ?T("Incorrect value of 'path' in data form"),
                    {error, xmpp:err_bad_request(Txt, Lang)}
            end
     end;
@@ -1464,9 +1463,9 @@ set_form(From, Host,
     {result,
      #xdata{type = form,
            fields = [?HFIELD(),
-                     ?XFIELD('jid-single', <<"Jabber ID">>,
+                     ?XFIELD('jid-single', ?T("Jabber ID"),
                              <<"accountjid">>, AccountString),
-                     ?XFIELD('text-single', <<"Password">>,
+                     ?XFIELD('text-single', ?T("Password"),
                              <<"password">>, Password)]}};
 set_form(From, Host,
         ?NS_ADMINL(<<"change-user-password">>), _Lang, XData) ->
@@ -1493,7 +1492,7 @@ set_form(From, Host,
                of
              [] ->
                  case get_last_info(User, Server) of
-                   not_found -> ?T(Lang, <<"Never">>);
+                   not_found -> tr(Lang, ?T("Never"));
                    {ok, Timestamp, _Status} ->
                        Shift = Timestamp,
                        TimeStamp = {Shift div 1000000, Shift rem 1000000, 0},
@@ -1503,14 +1502,14 @@ set_form(From, Host,
                                                       [Year, Month, Day, Hour,
                                                        Minute, Second]))
                  end;
-             _ -> ?T(Lang, <<"Online">>)
+             _ -> tr(Lang, ?T("Online"))
            end,
     {result,
      #xdata{type = form,
            fields = [?HFIELD(),
-                     ?XFIELD('jid-single', <<"Jabber ID">>,
+                     ?XFIELD('jid-single', ?T("Jabber ID"),
                              <<"accountjid">>, AccountString),
-                     ?XFIELD('text-single', <<"Last login">>,
+                     ?XFIELD('text-single', ?T("Last login"),
                              <<"lastlogin">>, FLast)]}};
 set_form(From, Host, ?NS_ADMINL(<<"user-stats">>), Lang,
         XData) ->
@@ -1533,13 +1532,13 @@ set_form(From, Host, ?NS_ADMINL(<<"user-stats">>), Lang,
     {result,
      #xdata{type = form,
            fields = [?HFIELD(),
-                     ?XFIELD('jid-single', <<"Jabber ID">>,
+                     ?XFIELD('jid-single', ?T("Jabber ID"),
                              <<"accountjid">>, AccountString),
-                     ?XFIELD('text-single', <<"Roster size">>,
+                     ?XFIELD('text-single', ?T("Roster size"),
                              <<"rostersize">>, Rostersize),
-                     ?XMFIELD('text-multi', <<"IP addresses">>,
+                     ?XMFIELD('text-multi', ?T("IP addresses"),
                               <<"ipaddresses">>, IPs),
-                     ?XMFIELD('text-multi', <<"Resources">>,
+                     ?XMFIELD('text-multi', ?T("Resources"),
                               <<"onlineresources">>, Resources)]}};
 set_form(_From, _Host, _, _Lang, _XData) ->
     {error, xmpp:err_service_unavailable()}.
@@ -1604,7 +1603,7 @@ adhoc_sm_commands(_Acc, From,
                                 action = Action, xdata = XData} = Request) ->
     case acl:match_rule(LServer, configure, From) of
        deny ->
-           {error, xmpp:err_forbidden(<<"Access denied by service policy">>, Lang)};
+           {error, xmpp:err_forbidden(?T("Access denied by service policy"), Lang)};
        allow ->
            ActionIsExecute = Action == execute orelse Action == complete,
            if Action == cancel ->
@@ -1622,7 +1621,7 @@ adhoc_sm_commands(_Acc, From,
               XData /= undefined, ActionIsExecute ->
                    set_sm_form(User, Server, <<"config">>, Request);
               true ->
-                   Txt = <<"Unexpected action">>,
+                   Txt = ?T("Unexpected action"),
                    {error, xmpp:err_bad_request(Txt, Lang)}
            end
     end;
@@ -1631,21 +1630,21 @@ adhoc_sm_commands(Acc, _From, _To, _Request) -> Acc.
 get_sm_form(User, Server, <<"config">>, Lang) ->
     {result,
      #xdata{type = form,
-           title = <<(?T(Lang, <<"Administration of ">>))/binary, User/binary>>,
+           title = <<(tr(Lang, ?T("Administration of ")))/binary, User/binary>>,
            fields =
                [?HFIELD(),
                 #xdata_field{
                    type = 'list-single',
-                   label = ?T(Lang, <<"Action on user">>),
+                   label = tr(Lang, ?T("Action on user")),
                    var = <<"action">>,
                    values = [<<"edit">>],
                    options = [#xdata_option{
-                                 label = ?T(Lang, <<"Edit Properties">>),
+                                 label = tr(Lang, ?T("Edit Properties")),
                                  value = <<"edit">>},
                               #xdata_option{
-                                 label = ?T(Lang, <<"Remove User">>),
+                                 label = tr(Lang, ?T("Remove User")),
                                  value = <<"remove">>}]},
-                ?XFIELD('text-private', <<"Password">>,
+                ?XFIELD('text-private', ?T("Password"),
                         <<"password">>,
                         ejabberd_auth:get_password_s(User, Server))]}};
 get_sm_form(_User, _Server, _Node, _Lang) ->
@@ -1663,17 +1662,21 @@ set_sm_form(User, Server, <<"config">>,
                    ejabberd_auth:set_password(User, Server, Password),
                    xmpp_util:make_adhoc_response(Response);
                _ ->
-                   Txt = <<"No 'password' found in data form">>,
+                   Txt = ?T("No 'password' found in data form"),
                    {error, xmpp:err_not_acceptable(Txt, Lang)}
            end;
        [<<"remove">>] ->
            catch ejabberd_auth:remove_user(User, Server),
            xmpp_util:make_adhoc_response(Response);
        _ ->
-           Txt = <<"Incorrect value of 'action' in data form">>,
+           Txt = ?T("Incorrect value of 'action' in data form"),
            {error, xmpp:err_not_acceptable(Txt, Lang)}
     end;
 set_sm_form(_User, _Server, _Node, _Request) ->
     {error, xmpp:err_service_unavailable()}.
 
+-spec tr(binary(), binary()) -> binary().
+tr(Lang, Text) ->
+    translate:translate(Lang, Text).
+
 mod_options(_) -> [].
index 78a1345c3f4b38983d2f0e67069b5675d3114b9a..0009cd619a68d5735625607cdd23bc670614f39d 100644 (file)
@@ -42,6 +42,7 @@
 
 -include("logger.hrl").
 -include("xmpp.hrl").
+-include("translate.hrl").
 
 -type disco_acc() :: {error, stanza_error()} | {result, [binary()]} | empty.
 -record(state, {server_host = <<"">> :: binary(),
@@ -259,7 +260,7 @@ process_iq(#iq{to = To, lang = Lang, sub_els = [SubEl]} = IQ, Type) ->
              IQ, gen_mod:get_module_proc(LServer, ?MODULE)),
            ignore;
        error ->
-           Txt = <<"Failed to map delegated namespace to external component">>,
+           Txt = ?T("Failed to map delegated namespace to external component"),
            xmpp:make_error(IQ, xmpp:err_internal_server_error(Txt, Lang))
     end.
 
@@ -278,7 +279,7 @@ process_iq_result(#iq{from = From, to = To, id = ID, lang = Lang} = IQ,
     catch _:_ ->
            ?ERROR_MSG("got iq-result with invalid delegated "
                       "payload:~n~s", [xmpp:pp(ResIQ)]),
-           Txt = <<"External component failure">>,
+           Txt = ?T("External component failure"),
            Err = xmpp:err_internal_server_error(Txt, Lang),
            ejabberd_router:route_error(IQ, Err)
     end;
@@ -286,7 +287,7 @@ process_iq_result(#iq{from = From, to = To}, #iq{type = error} = ResIQ) ->
     Err = xmpp:set_from_to(ResIQ, To, From),
     ejabberd_router:route(Err);
 process_iq_result(#iq{lang = Lang} = IQ, timeout) ->
-    Txt = <<"External component timeout">>,
+    Txt = ?T("External component timeout"),
     Err = xmpp:err_internal_server_error(Txt, Lang),
     ejabberd_router:route_error(IQ, Err).
 
index fd992d49df2f7508e5caa840f72297eab98ba8b3..4405ca1ec4320ee7d656569cf1c072b2cdc51c1e 100644 (file)
@@ -132,7 +132,7 @@ unregister_extra_domain(Host, Domain) ->
 
 -spec process_local_iq_items(iq()) -> iq().
 process_local_iq_items(#iq{type = set, lang = Lang} = IQ) ->
-    Txt = <<"Value 'set' of 'type' attribute is not allowed">>,
+    Txt = ?T("Value 'set' of 'type' attribute is not allowed"),
     xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang));
 process_local_iq_items(#iq{type = get, lang = Lang,
                           from = From, to = To,
@@ -148,7 +148,7 @@ process_local_iq_items(#iq{type = get, lang = Lang,
 
 -spec process_local_iq_info(iq()) -> iq().
 process_local_iq_info(#iq{type = set, lang = Lang} = IQ) ->
-    Txt = <<"Value 'set' of 'type' attribute is not allowed">>,
+    Txt = ?T("Value 'set' of 'type' attribute is not allowed"),
     xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang));
 process_local_iq_info(#iq{type = get, lang = Lang,
                          from = From, to = To,
@@ -199,7 +199,7 @@ get_local_features(Acc, _From, _To, _Node, Lang) ->
     case Acc of
       {result, _Features} -> Acc;
       empty ->
-           Txt = <<"No features available">>,
+           Txt = ?T("No features available"),
            {error, xmpp:err_item_not_found(Txt, Lang)}
     end.
 
@@ -227,7 +227,7 @@ get_local_services({result, _} = Acc, _From, _To, _Node,
                   _Lang) ->
     Acc;
 get_local_services(empty, _From, _To, _Node, Lang) ->
-    {error, xmpp:err_item_not_found(<<"No services available">>, Lang)}.
+    {error, xmpp:err_item_not_found(?T("No services available"), Lang)}.
 
 -spec get_vh_services(binary()) -> [binary()].
 get_vh_services(Host) ->
@@ -254,7 +254,7 @@ get_vh_services(Host) ->
 
 -spec process_sm_iq_items(iq()) -> iq().
 process_sm_iq_items(#iq{type = set, lang = Lang} = IQ) ->
-    Txt = <<"Value 'set' of 'type' attribute is not allowed">>,
+    Txt = ?T("Value 'set' of 'type' attribute is not allowed"),
     xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang));
 process_sm_iq_items(#iq{type = get, lang = Lang,
                        from = From, to = To,
@@ -271,7 +271,7 @@ process_sm_iq_items(#iq{type = get, lang = Lang,
                    xmpp:make_error(IQ, Error)
            end;
        false ->
-           Txt = <<"Not subscribed">>,
+           Txt = ?T("Not subscribed"),
            xmpp:make_error(IQ, xmpp:err_subscription_required(Txt, Lang))
     end.
 
@@ -300,13 +300,13 @@ get_sm_items(empty, From, To, _Node, Lang) ->
     case {LFrom, LSFrom} of
       {LTo, LSTo} -> {error, xmpp:err_item_not_found()};
       _ ->
-           Txt = <<"Query to another users is forbidden">>,
+           Txt = ?T("Query to another users is forbidden"),
            {error, xmpp:err_not_allowed(Txt, Lang)}
     end.
 
 -spec process_sm_iq_info(iq()) -> iq().
 process_sm_iq_info(#iq{type = set, lang = Lang} = IQ) ->
-    Txt = <<"Value 'set' of 'type' attribute is not allowed">>,
+    Txt = ?T("Value 'set' of 'type' attribute is not allowed"),
     xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang));
 process_sm_iq_info(#iq{type = get, lang = Lang,
                       from = From, to = To,
@@ -330,7 +330,7 @@ process_sm_iq_info(#iq{type = get, lang = Lang,
                    xmpp:make_error(IQ, Error)
            end;
        false ->
-           Txt = <<"Not subscribed">>,
+           Txt = ?T("Not subscribed"),
            xmpp:make_error(IQ, xmpp:err_subscription_required(Txt, Lang))
     end.
 
@@ -357,7 +357,7 @@ get_sm_features(empty, From, To, Node, Lang) ->
                _ -> {error, xmpp:err_item_not_found()}
            end;
        _ ->
-           Txt = <<"Query to another users is forbidden">>,
+           Txt = ?T("Query to another users is forbidden"),
            {error, xmpp:err_not_allowed(Txt, Lang)}
     end;
 get_sm_features({result, Features}, _From, _To, <<"">>, _Lang) ->
index 6ee65ca3e82baac55aaec33c36704265b8225a86..025d462447eb43eda97e4db2ca66af863f336f0a 100644 (file)
@@ -43,6 +43,7 @@
 -include("ejabberd_commands.hrl").
 -include("logger.hrl").
 -include("xmpp.hrl").
+-include("translate.hrl").
 
 -define(CLEAN_INTERVAL, timer:minutes(10)).
 
@@ -215,9 +216,9 @@ log_and_disconnect(#{ip := {Addr, _}, lang := Lang} = State, Attempts, UnbanTS)
     IP = misc:ip_to_list(Addr),
     UnbanDate = format_date(
                  calendar:now_to_universal_time(seconds_to_now(UnbanTS))),
-    Format = <<"Too many (~p) failed authentications "
-              "from this IP address (~s). The address "
-              "will be unblocked at ~s UTC">>,
+    Format = ?T("Too many (~p) failed authentications "
+               "from this IP address (~s). The address "
+               "will be unblocked at ~s UTC"),
     Args = [Attempts, IP, UnbanDate],
     ?WARNING_MSG("Connection attempt from blacklisted IP ~s: ~s",
                 [IP, io_lib:fwrite(Format, Args)]),
index 7d10430be42338e4127c36c2f97dc8e9bd303c38..2da64bc845ec12398784bf653864727dbae94b6d 100644 (file)
@@ -529,7 +529,7 @@ process_iq(#iq{type = get, sub_els = [#upload_request_0{filename = File,
           State) ->
     process_slot_request(IQ, File, Size, CType, XMLNS, State);
 process_iq(#iq{type = T, lang = Lang} = IQ, _State) when T == get; T == set ->
-    Txt = <<"No module is handling this query">>,
+    Txt = ?T("No module is handling this query"),
     xmpp:make_error(IQ, xmpp:err_service_unavailable(Txt, Lang));
 process_iq(#iq{}, _State) ->
     not_request.
@@ -559,7 +559,7 @@ process_slot_request(#iq{lang = Lang, from = From} = IQ,
        deny ->
            ?DEBUG("Denying HTTP upload slot request from ~s",
                   [jid:encode(From)]),
-           Txt = <<"Access denied by service policy">>,
+           Txt = ?T("Access denied by service policy"),
            xmpp:make_error(IQ, xmpp:err_forbidden(Txt, Lang))
     end.
 
@@ -570,7 +570,7 @@ create_slot(#state{service_url = undefined, max_size = MaxSize},
            JID, File, Size, _ContentType, XMLNS, Lang)
   when MaxSize /= infinity,
        Size > MaxSize ->
-    Text = {<<"File larger than ~w bytes">>, [MaxSize]},
+    Text = {?T("File larger than ~w bytes"), [MaxSize]},
     ?WARNING_MSG("Rejecting file ~s from ~s (too large: ~B bytes)",
              [File, jid:encode(JID), Size]),
     Error = xmpp:err_not_acceptable(Text, Lang),
@@ -624,7 +624,7 @@ create_slot(#state{service_url = ServiceURL},
                Lines ->
                    ?ERROR_MSG("Can't parse data received for ~s from <~s>: ~p",
                               [jid:encode(JID), ServiceURL, Lines]),
-                   Txt = <<"Failed to parse HTTP response">>,
+                   Txt = ?T("Failed to parse HTTP response"),
                    {error, xmpp:err_service_unavailable(Txt, Lang)}
            end;
        {ok, {402, _Body}} ->
index 558c105bfb2cb8649071c709f97695b8fa21a762..ec08a6449d0a1fa19a19fafa79d90b1491b25cf4 100644 (file)
         register_user/2, depends/2, privacy_check_packet/4]).
 
 -include("logger.hrl").
-
 -include("xmpp.hrl").
-
 -include("mod_privacy.hrl").
 -include("mod_last.hrl").
+-include("translate.hrl").
 
 -define(LAST_CACHE, last_activity_cache).
 
@@ -104,7 +103,7 @@ reload(Host, NewOpts, OldOpts) ->
 
 -spec process_local_iq(iq()) -> iq().
 process_local_iq(#iq{type = set, lang = Lang} = IQ) ->
-    Txt = <<"Value 'set' of 'type' attribute is not allowed">>,
+    Txt = ?T("Value 'set' of 'type' attribute is not allowed"),
     xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang));
 process_local_iq(#iq{type = get} = IQ) ->
     xmpp:make_iq_result(IQ, #last{seconds = get_node_uptime()}).
@@ -122,7 +121,7 @@ get_node_uptime() ->
 
 -spec process_sm_iq(iq()) -> iq().
 process_sm_iq(#iq{type = set, lang = Lang} = IQ) ->
-    Txt = <<"Value 'set' of 'type' attribute is not allowed">>,
+    Txt = ?T("Value 'set' of 'type' attribute is not allowed"),
     xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang));
 process_sm_iq(#iq{from = From, to = To, lang = Lang} = IQ) ->
     User = To#jid.luser,
@@ -141,7 +140,7 @@ process_sm_iq(#iq{from = From, to = To, lang = Lang} = IQ) ->
                deny -> xmpp:make_error(IQ, xmpp:err_forbidden())
            end;
        true ->
-           Txt = <<"Not subscribed">>,
+           Txt = ?T("Not subscribed"),
            xmpp:make_error(IQ, xmpp:err_subscription_required(Txt, Lang))
     end.
 
@@ -197,10 +196,10 @@ get_last_iq(#iq{lang = Lang} = IQ, LUser, LServer) ->
       [] ->
          case get_last(LUser, LServer) of
            {error, _Reason} ->
-               Txt = <<"Database failure">>,
+               Txt = ?T("Database failure"),
                xmpp:make_error(IQ, xmpp:err_internal_server_error(Txt, Lang));
            not_found ->
-               Txt = <<"No info about last activity found">>,
+               Txt = ?T("No info about last activity found"),
                xmpp:make_error(IQ, xmpp:err_service_unavailable(Txt, Lang));
            {ok, TimeStamp, Status} ->
                TimeStamp2 = erlang:system_time(second),
index 064d7eb3e904f19509c1b288c4c096d4ee5314fc..a48ef8de5564e15dc66c3d0afe2343b7a5f9098e 100644 (file)
@@ -30,6 +30,7 @@
 -export([c2s_unauthenticated_packet/2, c2s_stream_features/2]).
 
 -include("xmpp.hrl").
+-include("translate.hrl").
 
 -type c2s_state() :: ejabberd_c2s:state().
 
@@ -104,7 +105,7 @@ authenticate(State,
                 sub_els = [#legacy_auth{username = U,
                                         resource = R}]} = IQ)
   when U == undefined; R == undefined; U == <<"">>; R == <<"">> ->
-    Txt = <<"Both the username and the resource are required">>,
+    Txt = ?T("Both the username and the resource are required"),
     Err = xmpp:make_error(IQ, xmpp:err_not_acceptable(Txt, Lang)),
     ejabberd_c2s:send(State, Err);
 authenticate(#{stream_id := StreamID, server := Server,
@@ -138,7 +139,7 @@ authenticate(#{stream_id := StreamID, server := Server,
            Err = xmpp:make_error(IQ, xmpp:err_jid_malformed()),
            process_auth_failure(State, U, Err, 'jid-malformed');
        false ->
-           Txt = <<"Access denied by service policy">>,
+           Txt = ?T("Access denied by service policy"),
            Err = xmpp:make_error(IQ, xmpp:err_forbidden(Txt, Lang)),
            process_auth_failure(State, U, Err, 'forbidden')
     end.
index 3458a0c7272b61808de5c832a22fa893e41edeec..c40141592dcf06cfc5190dc34ba470ac05504789 100644 (file)
@@ -49,6 +49,7 @@
 -include("mod_muc_room.hrl").
 -include("ejabberd_commands.hrl").
 -include("mod_mam.hrl").
+-include("translate.hrl").
 
 -define(DEF_PAGE_SIZE, 50).
 -define(MAX_PAGE_SIZE, 250).
@@ -509,7 +510,7 @@ muc_process_iq(#iq{type = T, lang = Lang,
            Role = mod_muc_room:get_role(From, MUCState),
            process_iq(LServer, IQ, {groupchat, Role, MUCState});
        false ->
-           Text = <<"Only members may query archives of this room">>,
+           Text = ?T("Only members may query archives of this room"),
            xmpp:make_error(IQ, xmpp:err_forbidden(Text, Lang))
     end;
 muc_process_iq(#iq{type = get,
@@ -648,11 +649,11 @@ process_iq(#iq{from = #jid{luser = LUser, lserver = LServer},
                    NewPrefs = prefs_el(Default, Always, Never, NS),
                    xmpp:make_iq_result(IQ, NewPrefs);
                _Err ->
-                   Txt = <<"Database failure">>,
+                   Txt = ?T("Database failure"),
                    xmpp:make_error(IQ, xmpp:err_internal_server_error(Txt, Lang))
            end;
        deny ->
-           Txt = <<"MAM preference modification denied by service policy">>,
+           Txt = ?T("MAM preference modification denied by service policy"),
            xmpp:make_error(IQ, xmpp:err_forbidden(Txt, Lang))
     end;
 process_iq(#iq{from = #jid{luser = LUser, lserver = LServer},
@@ -666,7 +667,7 @@ process_iq(#iq{from = #jid{luser = LUser, lserver = LServer},
                               NS),
            xmpp:make_iq_result(IQ, PrefsEl);
        {error, _} ->
-           Txt = <<"Database failure">>,
+           Txt = ?T("Database failure"),
            xmpp:make_error(IQ, xmpp:err_internal_server_error(Txt, Lang))
     end;
 process_iq(IQ) ->
@@ -684,7 +685,7 @@ process_iq(LServer, #iq{from = #jid{luser = LUser}, lang = Lang,
        ok ->
            case SubEl of
                #mam_query{rsm = #rsm_set{index = I}} when is_integer(I) ->
-                   Txt = <<"Unsupported <index/> element">>,
+                   Txt = ?T("Unsupported <index/> element"),
                    xmpp:make_error(IQ, xmpp:err_feature_not_implemented(Txt, Lang));
                #mam_query{rsm = RSM, xmlns = NS} ->
                    case parse_query(SubEl, Lang) of
@@ -696,7 +697,7 @@ process_iq(LServer, #iq{from = #jid{luser = LUser}, lang = Lang,
                    end
            end;
        {error, _} ->
-            Txt = <<"Database failure">>,
+            Txt = ?T("Database failure"),
            xmpp:make_error(IQ, xmpp:err_internal_server_error(Txt, Lang))
     end.
 
@@ -1028,7 +1029,7 @@ select_and_send(LServer, Query, RSM, #iq{from = From, to = To} = IQ, MsgType) ->
            SortedMsgs = lists:keysort(2, Msgs),
            send(SortedMsgs, Count, IsComplete, IQ);
        {error, _} ->
-           Txt = <<"Database failure">>,
+           Txt = ?T("Database failure"),
            Err = xmpp:err_internal_server_error(Txt, IQ#iq.lang),
            xmpp:make_error(IQ, Err)
     end.
index 3bf387ced16e1ec58779648a623a860f88c9a90a..042b7dfefcabdcf8e26a84b7964b1708ba2fb6d6 100644 (file)
@@ -102,7 +102,7 @@ route(#message{type = groupchat, id = ID, lang = Lang,
               to = #jid{luser = <<_, _/binary>>}} = Msg) ->
     case ID of
        <<>> ->
-           Txt = <<"Attribute 'id' is mandatory for MIX messages">>,
+           Txt = ?T("Attribute 'id' is mandatory for MIX messages"),
            Err = xmpp:err_bad_request(Txt, Lang),
            ejabberd_router:route_error(Msg, Err);
        _ ->
@@ -113,7 +113,7 @@ route(Pkt) ->
 
 -spec process_disco_info(iq()) -> iq().
 process_disco_info(#iq{type = set, lang = Lang} = IQ) ->
-    Txt = <<"Value 'set' of 'type' attribute is not allowed">>,
+    Txt = ?T("Value 'set' of 'type' attribute is not allowed"),
     xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang));
 process_disco_info(#iq{type = get, to = #jid{luser = <<>>} = To,
                       from = _From, lang = Lang,
@@ -160,7 +160,7 @@ process_disco_info(IQ) ->
 
 -spec process_disco_items(iq()) -> iq().
 process_disco_items(#iq{type = set, lang = Lang} = IQ) ->
-    Txt = <<"Value 'set' of 'type' attribute is not allowed">>,
+    Txt = ?T("Value 'set' of 'type' attribute is not allowed"),
     xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang));
 process_disco_items(#iq{type = get, to = #jid{luser = <<>>} = To,
                        sub_els = [#disco_items{node = <<>>}]} = IQ) ->
@@ -596,32 +596,32 @@ make_id(JID, Key) ->
 %%%===================================================================
 -spec db_error(stanza()) -> stanza_error().
 db_error(Pkt) ->
-    Txt = <<"Database failure">>,
+    Txt = ?T("Database failure"),
     xmpp:err_internal_server_error(Txt, xmpp:get_lang(Pkt)).
 
 -spec channel_exists_error(stanza()) -> stanza_error().
 channel_exists_error(Pkt) ->
-    Txt = <<"Channel already exists">>,
+    Txt = ?T("Channel already exists"),
     xmpp:err_conflict(Txt, xmpp:get_lang(Pkt)).
 
 -spec no_channel_error(stanza()) -> stanza_error().
 no_channel_error(Pkt) ->
-    Txt = <<"Channel does not exist">>,
+    Txt = ?T("Channel does not exist"),
     xmpp:err_item_not_found(Txt, xmpp:get_lang(Pkt)).
 
 -spec not_joined_error(stanza()) -> stanza_error().
 not_joined_error(Pkt) ->
-    Txt = <<"You are not joined to the channel">>,
+    Txt = ?T("You are not joined to the channel"),
     xmpp:err_forbidden(Txt, xmpp:get_lang(Pkt)).
 
 -spec unsupported_error(stanza()) -> stanza_error().
 unsupported_error(Pkt) ->
-    Txt = <<"No module is handling this query">>,
+    Txt = ?T("No module is handling this query"),
     xmpp:err_service_unavailable(Txt, xmpp:get_lang(Pkt)).
 
 -spec ownership_error(stanza()) -> stanza_error().
 ownership_error(Pkt) ->
-    Txt = <<"Owner privileges required">>,
+    Txt = ?T("Owner privileges required"),
     xmpp:err_forbidden(Txt, xmpp:get_lang(Pkt)).
 
 %%%===================================================================
index 773ca08937e258e6fcb04c77617897c55a4c84ca..7b01965c704a4dc3f98966ebd30509f56cb1ec4a 100644 (file)
@@ -34,6 +34,7 @@
 
 -include("xmpp.hrl").
 -include("logger.hrl").
+-include("translate.hrl").
 
 -define(MIX_PAM_CACHE, mix_pam_cache).
 
@@ -253,7 +254,7 @@ process_iq_error(#iq{type = error} = ErrIQ, #iq{sub_els = [El]} = IQ) ->
            ejabberd_router:route_error(IQ, Err)
     end;
 process_iq_error(timeout, IQ) ->
-    Txt = <<"Request has timed out">>,
+    Txt = ?T("Request has timed out"),
     Err = xmpp:err_recipient_unavailable(Txt, IQ#iq.lang),
     ejabberd_router:route_error(IQ, Err).
 
@@ -267,22 +268,22 @@ make_channel_id(JID, ID) ->
 %%%===================================================================
 -spec missing_channel_error(stanza()) -> stanza_error().
 missing_channel_error(Pkt) ->
-    Txt = <<"Attribute 'channel' is required for this request">>,
+    Txt = ?T("Attribute 'channel' is required for this request"),
     xmpp:err_bad_request(Txt, xmpp:get_lang(Pkt)).
 
 -spec forbidden_query_error(stanza()) -> stanza_error().
 forbidden_query_error(Pkt) ->
-    Txt = <<"Query to another users is forbidden">>,
+    Txt = ?T("Query to another users is forbidden"),
     xmpp:err_forbidden(Txt, xmpp:get_lang(Pkt)).
 
 -spec unsupported_query_error(stanza()) -> stanza_error().
 unsupported_query_error(Pkt) ->
-    Txt = <<"No module is handling this query">>,
+    Txt = ?T("No module is handling this query"),
     xmpp:err_service_unavailable(Txt, xmpp:get_lang(Pkt)).
 
 -spec db_error(stanza()) -> stanza_error().
 db_error(Pkt) ->
-    Txt = <<"Database failure">>,
+    Txt = ?T("Database failure"),
     xmpp:err_internal_server_error(Txt, xmpp:get_lang(Pkt)).
 
 %%%===================================================================
index c04996a1f9b59dee7db2f2c3c89daf0f8abbd71f..3823489167b45e8cf594d8530b62d5a94701054c 100644 (file)
@@ -404,7 +404,7 @@ do_route(Host, ServerHost, Access, HistorySize, RoomShaper,
                      From, To, Packet, DefRoomOpts, QueueType);
        deny ->
            Lang = xmpp:get_lang(Packet),
-           ErrText = <<"Access denied by service policy">>,
+           ErrText = ?T("Access denied by service policy"),
            Err = xmpp:err_forbidden(ErrText, Lang),
            ejabberd_router:route_error(Packet, Err)
     end.
@@ -425,8 +425,8 @@ do_route1(Host, ServerHost, Access, _HistorySize, _RoomShaper,
                    Msg = xmpp:get_text(Body),
                    broadcast_service_message(ServerHost, Host, Msg);
                deny ->
-                   ErrText = <<"Only service administrators are allowed "
-                               "to send service messages">>,
+                   ErrText = ?T("Only service administrators are allowed "
+                                "to send service messages"),
                    Err = xmpp:err_forbidden(ErrText, Lang),
                    ejabberd_router:route_error(Packet, Err)
            end
@@ -456,13 +456,13 @@ do_route1(Host, ServerHost, Access, HistorySize, RoomShaper,
                            ok;
                        false ->
                            Lang = xmpp:get_lang(Packet),
-                           ErrText = <<"Room creation is denied by service policy">>,
+                           ErrText = ?T("Room creation is denied by service policy"),
                            Err = xmpp:err_forbidden(ErrText, Lang),
                            ejabberd_router:route_error(Packet, Err)
                    end;
                false ->
                    Lang = xmpp:get_lang(Packet),
-                   ErrText = <<"Conference room does not exist">>,
+                   ErrText = ?T("Conference room does not exist"),
                    Err = xmpp:err_item_not_found(ErrText, Lang),
                    ejabberd_router:route_error(Packet, Err)
            end;
@@ -479,10 +479,10 @@ process_vcard(#iq{type = get, lang = Lang, sub_els = [#vcard_temp{}]} = IQ) ->
                      url = ejabberd_config:get_uri(),
                      desc = misc:get_descr(Lang, ?T("ejabberd MUC module"))});
 process_vcard(#iq{type = set, lang = Lang} = IQ) ->
-    Txt = <<"Value 'set' of 'type' attribute is not allowed">>,
+    Txt = ?T("Value 'set' of 'type' attribute is not allowed"),
     xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang));
 process_vcard(#iq{lang = Lang} = IQ) ->
-    Txt = <<"No module is handling this query">>,
+    Txt = ?T("No module is handling this query"),
     xmpp:make_error(IQ, xmpp:err_service_unavailable(Txt, Lang)).
 
 -spec process_register(iq()) -> iq().
@@ -506,14 +506,14 @@ process_register(#iq{type = Type, from = From, to = To, lang = Lang,
                    end
            end;
        deny ->
-           ErrText = <<"Access denied by service policy">>,
+           ErrText = ?T("Access denied by service policy"),
            Err = xmpp:err_forbidden(ErrText, Lang),
            xmpp:make_error(IQ, Err)
     end.
 
 -spec process_disco_info(iq()) -> iq().
 process_disco_info(#iq{type = set, lang = Lang} = IQ) ->
-    Txt = <<"Value 'set' of 'type' attribute is not allowed">>,
+    Txt = ?T("Value 'set' of 'type' attribute is not allowed"),
     xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang));
 process_disco_info(#iq{type = get, from = From, to = To, lang = Lang,
                       sub_els = [#disco_info{node = <<"">>}]} = IQ) ->
@@ -547,14 +547,14 @@ process_disco_info(#iq{type = get, from = From, to = To, lang = Lang,
                      xdata = X});
 process_disco_info(#iq{type = get, lang = Lang,
                       sub_els = [#disco_info{}]} = IQ) ->
-    xmpp:make_error(IQ, xmpp:err_item_not_found(<<"Node not found">>, Lang));
+    xmpp:make_error(IQ, xmpp:err_item_not_found(?T("Node not found"), Lang));
 process_disco_info(#iq{lang = Lang} = IQ) ->
-    Txt = <<"No module is handling this query">>,
+    Txt = ?T("No module is handling this query"),
     xmpp:make_error(IQ, xmpp:err_service_unavailable(Txt, Lang)).
 
 -spec process_disco_items(iq()) -> iq().
 process_disco_items(#iq{type = set, lang = Lang} = IQ) ->
-    Txt = <<"Value 'set' of 'type' attribute is not allowed">>,
+    Txt = ?T("Value 'set' of 'type' attribute is not allowed"),
     xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang));
 process_disco_items(#iq{type = get, from = From, to = To, lang = Lang,
                        sub_els = [#disco_items{node = Node, rsm = RSM}]} = IQ) ->
@@ -569,12 +569,12 @@ process_disco_items(#iq{type = get, from = From, to = To, lang = Lang,
            xmpp:make_iq_result(IQ, Result)
     end;
 process_disco_items(#iq{lang = Lang} = IQ) ->
-    Txt = <<"No module is handling this query">>,
+    Txt = ?T("No module is handling this query"),
     xmpp:make_error(IQ, xmpp:err_service_unavailable(Txt, Lang)).
 
 -spec process_muc_unique(iq()) -> iq().
 process_muc_unique(#iq{type = set, lang = Lang} = IQ) ->
-    Txt = <<"Value 'set' of 'type' attribute is not allowed">>,
+    Txt = ?T("Value 'set' of 'type' attribute is not allowed"),
     xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang));
 process_muc_unique(#iq{from = From, type = get,
                       sub_els = [#muc_unique{}]} = IQ) ->
@@ -584,7 +584,7 @@ process_muc_unique(#iq{from = From, type = get,
 
 -spec process_mucsub(iq()) -> iq().
 process_mucsub(#iq{type = set, lang = Lang} = IQ) ->
-    Txt = <<"Value 'set' of 'type' attribute is not allowed">>,
+    Txt = ?T("Value 'set' of 'type' attribute is not allowed"),
     xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang));
 process_mucsub(#iq{type = get, from = From, to = To, lang = Lang,
                   sub_els = [#muc_subscriptions{}]} = IQ) ->
@@ -596,11 +596,11 @@ process_mucsub(#iq{type = get, from = From, to = To, lang = Lang,
                    || {JID, Nodes} <- Subs],
            xmpp:make_iq_result(IQ, #muc_subscriptions{list = List});
        {error, _} ->
-           Txt = <<"Database failure">>,
+           Txt = ?T("Database failure"),
            xmpp:make_error(IQ, xmpp:err_internal_server_error(Txt, Lang))
     end;
 process_mucsub(#iq{lang = Lang} = IQ) ->
-    Txt = <<"No module is handling this query">>,
+    Txt = ?T("No module is handling this query"),
     xmpp:make_error(IQ, xmpp:err_service_unavailable(Txt, Lang)).
 
 -spec is_create_request(stanza()) -> boolean().
@@ -733,7 +733,7 @@ iq_disco_items(ServerHost, Host, From, Lang, MaxRoomsDiscoItems, Node, RSM)
             end,
     {result, #disco_items{node = Node, items = Items, rsm = ResRSM}};
 iq_disco_items(_ServerHost, _Host, _From, Lang, _MaxRoomsDiscoItems, _Node, _RSM) ->
-    {error, xmpp:err_item_not_found(<<"Node not found">>, Lang)}.
+    {error, xmpp:err_item_not_found(?T("Node not found"), Lang)}.
 
 -spec get_room_disco_item({binary(), binary(), pid()},
                          term()) -> {ok, disco_item()} |
@@ -807,8 +807,8 @@ iq_get_register_info(ServerHost, Host, From, Lang) ->
                             N -> {N, true}
                         end,
     Title = <<(translate:translate(
-                Lang, <<"Nickname Registration at ">>))/binary, Host/binary>>,
-    Inst = translate:translate(Lang, <<"Enter nickname you want to register">>),
+                Lang, ?T("Nickname Registration at ")))/binary, Host/binary>>,
+    Inst = translate:translate(Lang, ?T("Enter nickname you want to register")),
     Fields = muc_register:encode([{roomnick, Nick}], Lang),
     X = #xdata{type = form, title = Title,
               instructions = [Inst], fields = Fields},
@@ -816,8 +816,8 @@ iq_get_register_info(ServerHost, Host, From, Lang) ->
              registered = Registered,
              instructions =
                  translate:translate(
-                   Lang, <<"You need a client that supports x:data "
-                           "to register the nickname">>),
+                   Lang, ?T("You need a client that supports x:data "
+                            "to register the nickname")),
              xdata = X}.
 
 set_nick(ServerHost, Host, From, Nick) ->
@@ -830,11 +830,10 @@ iq_set_register_info(ServerHost, Host, From, Nick,
     case set_nick(ServerHost, Host, From, Nick) of
       {atomic, ok} -> {result, undefined};
       {atomic, false} ->
-         ErrText = <<"That nickname is registered by another "
-                     "person">>,
+         ErrText = ?T("That nickname is registered by another person"),
          {error, xmpp:err_conflict(ErrText, Lang)};
       _ ->
-         Txt = <<"Database failure">>,
+         Txt = ?T("Database failure"),
          {error, xmpp:err_internal_server_error(Txt, Lang)}
     end.
 
@@ -857,12 +856,12 @@ process_iq_register_set(ServerHost, Host, From,
                    {error, xmpp:err_bad_request(ErrText, Lang)}
            end;
        #xdata{} ->
-           Txt = <<"Incorrect data form">>,
+           Txt = ?T("Incorrect data form"),
            {error, xmpp:err_bad_request(Txt, Lang)};
        _ when is_binary(Nick), Nick /= <<"">> ->
            iq_set_register_info(ServerHost, Host, From, Nick, Lang);
        _ ->
-           ErrText = <<"You must fill in field \"Nickname\" in the form">>,
+           ErrText = ?T("You must fill in field \"Nickname\" in the form"),
            {error, xmpp:err_not_acceptable(ErrText, Lang)}
     end.
 
index 499987e1e1c31a09fcc400c67ecb2b3e83272fd9..422dc075be0290d6a7694dab20c4ee889519676c 100644 (file)
@@ -50,6 +50,7 @@
 -include("ejabberd_http.hrl").
 -include("ejabberd_web_admin.hrl").
 -include("ejabberd_commands.hrl").
+-include("translate.hrl").
 
 %%----------------------------
 %% gen_mod
@@ -426,10 +427,10 @@ get_user_rooms(User, Server) ->
 %% Web Admin Menu
 
 web_menu_main(Acc, Lang) ->
-    Acc ++ [{<<"muc">>, ?T(<<"Multi-User Chat">>)}].
+    Acc ++ [{<<"muc">>, translate:translate(Lang, ?T("Multi-User Chat"))}].
 
 web_menu_host(Acc, _Host, Lang) ->
-    Acc ++ [{<<"muc">>, ?T(<<"Multi-User Chat">>)}].
+    Acc ++ [{<<"muc">>, translate:translate(Lang, ?T("Multi-User Chat"))}].
 
 
 %%---------------
@@ -445,13 +446,13 @@ web_page_main(_, #request{path=[<<"muc">>], lang = Lang} = _Request) ->
                          fun(Host, Acc) ->
                                  Acc + mod_muc:count_online_rooms(Host)
                          end, 0, find_hosts(global)),
-    Res = [?XCT(<<"h1">>, <<"Multi-User Chat">>),
-          ?XCT(<<"h3">>, <<"Statistics">>),
+    Res = [?XCT(<<"h1">>, ?T("Multi-User Chat")),
+          ?XCT(<<"h3">>, ?T("Statistics")),
           ?XAE(<<"table">>, [],
-               [?XE(<<"tbody">>, [?TDTD(<<"Total rooms">>, OnlineRoomsNumber)
+               [?XE(<<"tbody">>, [?TDTD(?T("Total rooms"), OnlineRoomsNumber)
                                  ])
                ]),
-          ?XE(<<"ul">>, [?LI([?ACT(<<"rooms">>, <<"List of rooms">>)])])
+          ?XE(<<"ul">>, [?LI([?ACT(<<"rooms">>, ?T("List of rooms"))])])
          ],
     {stop, Res};
 
@@ -517,8 +518,8 @@ make_rooms_page(Host, Lang, {Sort_direction, Sort_column}) ->
          end,
          1,
          Titles),
-    [?XCT(<<"h1">>, <<"Multi-User Chat">>),
-     ?XCT(<<"h2">>, <<"Chatrooms">>),
+    [?XCT(<<"h1">>, ?T("Multi-User Chat")),
+     ?XCT(<<"h2">>, ?T("Chatrooms")),
      ?XE(<<"table">>,
         [?XE(<<"thead">>,
              [?XE(<<"tr">>, Titles_TR)]
index 0e2ff69846e68556437b77de7a04940b3fc80a94..4b9a6154d87fbd67e7d2fb8d32870246cd488676 100644 (file)
         mod_opt_type/1, mod_options/1, depends/2]).
 
 -include("logger.hrl").
-
 -include("xmpp.hrl").
 -include("mod_muc_room.hrl").
+-include("translate.hrl").
 
--define(T(Text), translate:translate(Lang, Text)).
 -record(room, {jid, title, subject, subject_author, config}).
 
 -define(PLAINTEXT_CO, <<"ZZCZZ">>).
@@ -346,7 +345,7 @@ add_message_to_log(Nick1, Message, RoomJID, Opts,
                                                   Lang, FileFormat),
                 put_room_config(F, RoomConfig, Lang, FileFormat),
                 io_lib:format("<font class=\"mrcm\">~s</font><br/>",
-                              [?T(<<"Chatroom configuration modified">>)]);
+                              [tr(Lang, ?T("Chatroom configuration modified"))]);
             {roomconfig_change, Occupants} ->
                 RoomConfig = roomconfig_to_string(Room#room.config,
                                                   Lang, FileFormat),
@@ -355,53 +354,53 @@ add_message_to_log(Nick1, Message, RoomJID, Opts,
                                                         FileFormat),
                 put_room_occupants(F, RoomOccupants, Lang, FileFormat),
                 io_lib:format("<font class=\"mrcm\">~s</font><br/>",
-                              [?T(<<"Chatroom configuration modified">>)]);
+                              [tr(Lang, ?T("Chatroom configuration modified"))]);
             join ->
                 io_lib:format("<font class=\"mj\">~s ~s</font><br/>",
-                              [Nick, ?T(<<"joins the room">>)]);
+                              [Nick, tr(Lang, ?T("joins the room"))]);
             leave ->
                 io_lib:format("<font class=\"ml\">~s ~s</font><br/>",
-                              [Nick, ?T(<<"leaves the room">>)]);
+                              [Nick, tr(Lang, ?T("leaves the room"))]);
             {leave, Reason} ->
                 io_lib:format("<font class=\"ml\">~s ~s: ~s</font><br/>",
-                              [Nick, ?T(<<"leaves the room">>),
+                              [Nick, tr(Lang, ?T("leaves the room")),
                                htmlize(Reason, NoFollow, FileFormat)]);
             {kickban, 301, <<"">>} ->
                 io_lib:format("<font class=\"mb\">~s ~s</font><br/>",
-                              [Nick, ?T(<<"has been banned">>)]);
+                              [Nick, tr(Lang, ?T("has been banned"))]);
             {kickban, 301, Reason} ->
                 io_lib:format("<font class=\"mb\">~s ~s: ~s</font><br/>",
-                              [Nick, ?T(<<"has been banned">>),
+                              [Nick, tr(Lang, ?T("has been banned")),
                                htmlize(Reason, FileFormat)]);
             {kickban, 307, <<"">>} ->
                 io_lib:format("<font class=\"mk\">~s ~s</font><br/>",
-                              [Nick, ?T(<<"has been kicked">>)]);
+                              [Nick, tr(Lang, ?T("has been kicked"))]);
             {kickban, 307, Reason} ->
                 io_lib:format("<font class=\"mk\">~s ~s: ~s</font><br/>",
-                              [Nick, ?T(<<"has been kicked">>),
+                              [Nick, tr(Lang, ?T("has been kicked")),
                                htmlize(Reason, FileFormat)]);
             {kickban, 321, <<"">>} ->
                 io_lib:format("<font class=\"mk\">~s ~s</font><br/>",
                               [Nick,
-                               ?T(<<"has been kicked because of an affiliation "
-                                    "change">>)]);
+                               tr(Lang, ?T("has been kicked because of an affiliation "
+                                           "change"))]);
             {kickban, 322, <<"">>} ->
                 io_lib:format("<font class=\"mk\">~s ~s</font><br/>",
                               [Nick,
-                               ?T(<<"has been kicked because the room has "
-                                    "been changed to members-only">>)]);
+                               tr(Lang, ?T("has been kicked because the room has "
+                                           "been changed to members-only"))]);
             {kickban, 332, <<"">>} ->
                 io_lib:format("<font class=\"mk\">~s ~s</font><br/>",
                               [Nick,
-                               ?T(<<"has been kicked because of a system "
-                                    "shutdown">>)]);
+                               tr(Lang, ?T("has been kicked because of a system "
+                                           "shutdown"))]);
             {nickchange, OldNick} ->
                 io_lib:format("<font class=\"mnc\">~s ~s ~s</font><br/>",
                               [htmlize(OldNick, FileFormat),
-                               ?T(<<"is now known as">>), Nick]);
+                               tr(Lang, ?T("is now known as")), Nick]);
             {subject, T} ->
                 io_lib:format("<font class=\"msc\">~s~s~s</font><br/>",
-                              [Nick, ?T(<<" has set the subject to: ">>),
+                              [Nick, tr(Lang, ?T(" has set the subject to: ")),
                                htmlize(T, NoFollow, FileFormat)]);
             {body, T} ->
                 case {ejabberd_regexp:run(T, <<"^/me ">>), Nick} of
@@ -441,38 +440,38 @@ add_message_to_log(Nick1, Message, RoomJID, Opts,
 %% Utilities
 
 get_room_existence_string(created, Lang) ->
-    ?T(<<"Chatroom is created">>);
+    tr(Lang, ?T("Chatroom is created"));
 get_room_existence_string(destroyed, Lang) ->
-    ?T(<<"Chatroom is destroyed">>);
+    tr(Lang, ?T("Chatroom is destroyed"));
 get_room_existence_string(started, Lang) ->
-    ?T(<<"Chatroom is started">>);
+    tr(Lang, ?T("Chatroom is started"));
 get_room_existence_string(stopped, Lang) ->
-    ?T(<<"Chatroom is stopped">>).
+    tr(Lang, ?T("Chatroom is stopped")).
 
 get_dateweek(Date, Lang) ->
     Weekday = case calendar:day_of_the_week(Date) of
-               1 -> ?T(<<"Monday">>);
-               2 -> ?T(<<"Tuesday">>);
-               3 -> ?T(<<"Wednesday">>);
-               4 -> ?T(<<"Thursday">>);
-               5 -> ?T(<<"Friday">>);
-               6 -> ?T(<<"Saturday">>);
-               7 -> ?T(<<"Sunday">>)
+               1 -> tr(Lang, ?T("Monday"));
+               2 -> tr(Lang, ?T("Tuesday"));
+               3 -> tr(Lang, ?T("Wednesday"));
+               4 -> tr(Lang, ?T("Thursday"));
+               5 -> tr(Lang, ?T("Friday"));
+               6 -> tr(Lang, ?T("Saturday"));
+               7 -> tr(Lang, ?T("Sunday"))
              end,
     {Y, M, D} = Date,
     Month = case M of
-             1 -> ?T(<<"January">>);
-             2 -> ?T(<<"February">>);
-             3 -> ?T(<<"March">>);
-             4 -> ?T(<<"April">>);
-             5 -> ?T(<<"May">>);
-             6 -> ?T(<<"June">>);
-             7 -> ?T(<<"July">>);
-             8 -> ?T(<<"August">>);
-             9 -> ?T(<<"September">>);
-             10 -> ?T(<<"October">>);
-             11 -> ?T(<<"November">>);
-             12 -> ?T(<<"December">>)
+             1 -> tr(Lang, ?T("January"));
+             2 -> tr(Lang, ?T("February"));
+             3 -> tr(Lang, ?T("March"));
+             4 -> tr(Lang, ?T("April"));
+             5 -> tr(Lang, ?T("May"));
+             6 -> tr(Lang, ?T("June"));
+             7 -> tr(Lang, ?T("July"));
+             8 -> tr(Lang, ?T("August"));
+             9 -> tr(Lang, ?T("September"));
+             10 -> tr(Lang, ?T("October"));
+             11 -> tr(Lang, ?T("November"));
+             12 -> tr(Lang, ?T("December"))
            end,
     list_to_binary(
       case Lang of
@@ -575,7 +574,7 @@ put_header(F, Room, Date, CSSFile, Lang, Hour_offset,
       {<<"">>, <<"">>} -> ok;
       {SuA, Su} ->
          fw(F, <<"<div class=\"roomsubject\">~s~s~s</div>">>,
-            [SuA, ?T(<<" has set the subject to: ">>), Su])
+            [SuA, tr(Lang, ?T(" has set the subject to: ")), Su])
     end,
     RoomConfig = roomconfig_to_string(Room#room.config,
                                      Lang, FileFormat),
@@ -622,7 +621,7 @@ put_room_config(F, RoomConfig, Lang, _FileFormat) ->
     fw(F,
        <<"<div class=\"rct\" onclick=\"sh('a~p');return "
         "false;\">~s</div>">>,
-       [Now2, ?T(<<"Room Configuration">>)]),
+       [Now2, tr(Lang, ?T("Room Configuration"))]),
     fw(F,
        <<"<div class=\"rcos\" id=\"a~p\" style=\"displa"
         "y: none;\" ><br/>~s</div>">>,
@@ -642,7 +641,7 @@ put_room_occupants(F, RoomOccupants, Lang,
     fw(F,
        <<"<div class=\"rct\" onclick=\"sh('o~p');return "
         "false;\">~s</div>">>,
-       [Now2, ?T(<<"Room Occupants">>)]),
+       [Now2, tr(Lang, ?T("Room Occupants"))]),
     fw(F,
        <<"<div class=\"rcos\" id=\"o~p\" style=\"displa"
         "y: none;\" ><br/>~s</div>">>,
@@ -766,7 +765,7 @@ roomconfig_to_string(Options, Lang, FileFormat) ->
                                           allow_private_messages_from_visitors ->
                                               <<"<div class=\"rcot\">",
                                                 OptText/binary, ": \"",
-                                                (htmlize(?T(misc:atom_to_binary(T)),
+                                                (htmlize(tr(Lang, misc:atom_to_binary(T)),
                                                          FileFormat))/binary,
                                                 "\"</div>">>;
                                           _ -> <<"\"", T/binary, "\"">>
@@ -777,48 +776,47 @@ roomconfig_to_string(Options, Lang, FileFormat) ->
                end,
                <<"">>, Options2).
 
-get_roomconfig_text(title, Lang) -> ?T(<<"Room title">>);
+get_roomconfig_text(title, Lang) -> tr(Lang, ?T("Room title"));
 get_roomconfig_text(persistent, Lang) ->
-    ?T(<<"Make room persistent">>);
+    tr(Lang, ?T("Make room persistent"));
 get_roomconfig_text(public, Lang) ->
-    ?T(<<"Make room public searchable">>);
+    tr(Lang, ?T("Make room public searchable"));
 get_roomconfig_text(public_list, Lang) ->
-    ?T(<<"Make participants list public">>);
+    tr(Lang, ?T("Make participants list public"));
 get_roomconfig_text(password_protected, Lang) ->
-    ?T(<<"Make room password protected">>);
-get_roomconfig_text(password, Lang) -> ?T(<<"Password">>);
+    tr(Lang, ?T("Make room password protected"));
+get_roomconfig_text(password, Lang) -> tr(Lang, ?T("Password"));
 get_roomconfig_text(anonymous, Lang) ->
-    ?T(<<"This room is not anonymous">>);
+    tr(Lang, ?T("This room is not anonymous"));
 get_roomconfig_text(members_only, Lang) ->
-    ?T(<<"Make room members-only">>);
+    tr(Lang, ?T("Make room members-only"));
 get_roomconfig_text(moderated, Lang) ->
-    ?T(<<"Make room moderated">>);
+    tr(Lang, ?T("Make room moderated"));
 get_roomconfig_text(members_by_default, Lang) ->
-    ?T(<<"Default users as participants">>);
+    tr(Lang, ?T("Default users as participants"));
 get_roomconfig_text(allow_change_subj, Lang) ->
-    ?T(<<"Allow users to change the subject">>);
+    tr(Lang, ?T("Allow users to change the subject"));
 get_roomconfig_text(allow_private_messages, Lang) ->
-    ?T(<<"Allow users to send private messages">>);
+    tr(Lang, ?T("Allow users to send private messages"));
 get_roomconfig_text(allow_private_messages_from_visitors, Lang) ->
-    ?T(<<"Allow visitors to send private messages to">>);
+    tr(Lang, ?T("Allow visitors to send private messages to"));
 get_roomconfig_text(allow_query_users, Lang) ->
-    ?T(<<"Allow users to query other users">>);
+    tr(Lang, ?T("Allow users to query other users"));
 get_roomconfig_text(allow_user_invites, Lang) ->
-    ?T(<<"Allow users to send invites">>);
-get_roomconfig_text(logging, Lang) -> ?T(<<"Enable logging">>);
+    tr(Lang, ?T("Allow users to send invites"));
+get_roomconfig_text(logging, Lang) -> tr(Lang, ?T("Enable logging"));
 get_roomconfig_text(allow_visitor_nickchange, Lang) ->
-    ?T(<<"Allow visitors to change nickname">>);
+    tr(Lang, ?T("Allow visitors to change nickname"));
 get_roomconfig_text(allow_visitor_status, Lang) ->
-    ?T(<<"Allow visitors to send status text in "
-      "presence updates">>);
+    tr(Lang, ?T("Allow visitors to send status text in presence updates"));
 get_roomconfig_text(captcha_protected, Lang) ->
-    ?T(<<"Make room CAPTCHA protected">>);
+    tr(Lang, ?T("Make room CAPTCHA protected"));
 get_roomconfig_text(description, Lang) ->
-    ?T(<<"Room description">>);
+    tr(Lang, ?T("Room description"));
 %% get_roomconfig_text(subject, Lang) ->  "Subject";
 %% get_roomconfig_text(subject_author, Lang) ->  "Subject author";
 get_roomconfig_text(max_users, Lang) ->
-    ?T(<<"Maximum Number of Occupants">>);
+    tr(Lang, ?T("Maximum Number of Occupants"));
 get_roomconfig_text(_, _) -> undefined.
 
 %% Users = [{JID, Nick, Role}]
@@ -918,6 +916,10 @@ calc_hour_offset(TimeHere) ->
 fjoin(FileList) ->
     list_to_binary(filename:join([binary_to_list(File) || File <- FileList])).
 
+-spec tr(binary(), binary()) -> binary().
+tr(Lang, Text) ->
+    translate:translate(Lang, Text).
+
 has_no_permanent_store_hint(Packet) ->
     xmpp:has_subtag(Packet, #hint{type = 'no-store'}) orelse
     xmpp:has_subtag(Packet, #hint{type = 'no-storage'}) orelse
index e41b737f5335dc6d91275e9fb2c3ced999f7a9f4..27d9ef2d67a7b839d37fb706851af66ce3f3f5a0 100644 (file)
@@ -168,7 +168,7 @@ normal_state({route, <<"">>,
            {MessageShaper, MessageShaperInterval} =
                ejabberd_shaper:update(Activity#activity.message_shaper, Size),
            if Activity#activity.message /= undefined ->
-                   ErrText = <<"Traffic rate limit is exceeded">>,
+                   ErrText = ?T("Traffic rate limit is exceeded"),
                    Err = xmpp:err_resource_constraint(ErrText, Lang),
                    ejabberd_router:route_error(Packet, Err),
                    {next_state, normal_state, StateData};
@@ -228,9 +228,9 @@ normal_state({route, <<"">>,
        true when Type == error ->
            case is_user_online(From, StateData) of
                true ->
-                   ErrorText = <<"It is not allowed to send error messages to the"
-                                 " room. The participant (~s) has sent an error "
-                                 "message (~s) and got kicked from the room">>,
+                   ErrorText = ?T("It is not allowed to send error messages to the"
+                                  " room. The participant (~s) has sent an error "
+                                  "message (~s) and got kicked from the room"),
                    NewState = expulse_participant(Packet, From, StateData,
                                                   translate:translate(Lang,
                                                                       ErrorText)),
@@ -239,8 +239,8 @@ normal_state({route, <<"">>,
                    {next_state, normal_state, StateData}
            end;
        true when Type == chat ->
-           ErrText = <<"It is not allowed to send private messages "
-                       "to the conference">>,
+           ErrText = ?T("It is not allowed to send private messages "
+                        "to the conference"),
            Err = xmpp:err_not_acceptable(ErrText, Lang),
            ejabberd_router:route_error(Packet, Err),
            {next_state, normal_state, StateData};
@@ -255,7 +255,7 @@ normal_state({route, <<"">>,
                     StateData
             end};
        true ->
-           ErrText = <<"Improper message type">>,
+           ErrText = ?T("Improper message type"),
            Err = xmpp:err_not_acceptable(ErrText, Lang),
            ejabberd_router:route_error(Packet, Err),
            {next_state, normal_state, StateData};
@@ -297,8 +297,8 @@ normal_state({route, <<"">>,
                           ?NS_CAPTCHA ->
                               process_iq_captcha(From, IQ, StateData);
                           _ ->
-                              Txt = <<"The feature requested is not "
-                                      "supported by the conference">>,
+                              Txt = ?T("The feature requested is not "
+                                       "supported by the conference"),
                               {error, xmpp:err_service_unavailable(Txt, Lang)}
                       end,
                {IQRes, NewStateData} =
@@ -370,9 +370,9 @@ normal_state({route, ToNick,
     case decide_fate_message(Packet, From, StateData) of
        {expulse_sender, Reason} ->
            ?DEBUG(Reason, []),
-           ErrorText = <<"It is not allowed to send error messages to the"
-                         " room. The participant (~s) has sent an error "
-                         "message (~s) and got kicked from the room">>,
+           ErrorText = ?T("It is not allowed to send error messages to the"
+                          " room. The participant (~s) has sent an error "
+                          "message (~s) and got kicked from the room"),
            NewState = expulse_participant(Packet, From, StateData,
                                           translate:translate(Lang, ErrorText)),
            {next_state, normal_state, NewState};
@@ -383,14 +383,14 @@ normal_state({route, ToNick,
                  is_user_online(From, StateData) orelse
                  is_subscriber(From, StateData)} of
                {true, true} when Type == groupchat ->
-                   ErrText = <<"It is not allowed to send private messages "
-                               "of type \"groupchat\"">>,
+                   ErrText = ?T("It is not allowed to send private messages "
+                                "of type \"groupchat\""),
                    Err = xmpp:err_bad_request(ErrText, Lang),
                    ejabberd_router:route_error(Packet, Err);
                {true, true} ->
                    case find_jids_by_nick(ToNick, StateData) of
                        [] ->
-                           ErrText = <<"Recipient is not in the conference room">>,
+                           ErrText = ?T("Recipient is not in the conference room"),
                            Err = xmpp:err_item_not_found(ErrText, Lang),
                            ejabberd_router:route_error(Packet, Err);
                        ToJIDs ->
@@ -415,18 +415,18 @@ normal_state({route, ToNick,
                                              ejabberd_router:route(xmpp:set_to(PrivMsg, ToJID))
                                      end, ToJIDs);
                               true ->
-                                   ErrText = <<"It is not allowed to send private messages">>,
+                                   ErrText = ?T("It is not allowed to send private messages"),
                                    Err = xmpp:err_forbidden(ErrText, Lang),
                                    ejabberd_router:route_error(Packet, Err)
                            end
                    end;
                {true, false} ->
-                   ErrText = <<"Only occupants are allowed to send messages "
-                               "to the conference">>,
+                   ErrText = ?T("Only occupants are allowed to send messages "
+                                "to the conference"),
                    Err = xmpp:err_not_acceptable(ErrText, Lang),
                    ejabberd_router:route_error(Packet, Err);
                {false, _} ->
-                   ErrText = <<"It is not allowed to send private messages">>,
+                   ErrText = ?T("It is not allowed to send private messages"),
                    Err = xmpp:err_forbidden(ErrText, Lang),
                    ejabberd_router:route_error(Packet, Err)
            end,
@@ -439,7 +439,7 @@ normal_state({route, ToNick,
        #user{nick = FromNick} when AllowQuery orelse ToNick == FromNick ->
            case find_jid_by_nick(ToNick, StateData) of
                false ->
-                   ErrText = <<"Recipient is not in the conference room">>,
+                   ErrText = ?T("Recipient is not in the conference room"),
                    Err = xmpp:err_item_not_found(ErrText, Lang),
                    ejabberd_router:route_error(Packet, Err);
                To ->
@@ -462,13 +462,13 @@ normal_state({route, ToNick,
                    end
            end;
        _ ->
-           ErrText = <<"Queries to the conference members are "
-                       "not allowed in this room">>,
+           ErrText = ?T("Queries to the conference members are "
+                        "not allowed in this room"),
            Err = xmpp:err_not_allowed(ErrText, Lang),
            ejabberd_router:route_error(Packet, Err)
     catch _:{badkey, _} ->
-           ErrText = <<"Only occupants are allowed to send queries "
-                       "to the conference">>,
+           ErrText = ?T("Only occupants are allowed to send queries "
+                        "to the conference"),
            Err = xmpp:err_not_acceptable(ErrText, Lang),
            ejabberd_router:route_error(Packet, Err)
     end,
@@ -664,7 +664,7 @@ handle_info({captcha_failed, From}, normal_state,
     NewState = case maps:get(From, StateData#state.robots, passed) of
                   {_Nick, Packet} ->
                       Robots = maps:remove(From, StateData#state.robots),
-                      Txt = <<"The CAPTCHA verification has failed">>,
+                      Txt = ?T("The CAPTCHA verification has failed"),
                       Lang = xmpp:get_lang(Packet),
                       Err = xmpp:err_not_authorized(Txt, Lang),
                       ejabberd_router:route_error(Packet, Err),
@@ -683,7 +683,7 @@ handle_info({iq_reply, #iq{type = Type, sub_els = Els},
        To, From)),
     {next_state, StateName, StateData};
 handle_info({iq_reply, timeout, IQ}, StateName, StateData) ->
-    Txt = <<"Request has timed out">>,
+    Txt = ?T("Request has timed out"),
     Err = xmpp:err_recipient_unavailable(Txt, IQ#iq.lang),
     ejabberd_router:route_error(IQ, Err),
     {next_state, StateName, StateData};
@@ -708,9 +708,9 @@ terminate(Reason, _StateName,
        ?INFO_MSG("Stopping MUC room ~s@~s", [Room, Host]),
        ReasonT = case Reason of
                      shutdown ->
-                         <<"You are being removed from the room "
-                           "because of a system shutdown">>;
-                     _ -> <<"Room terminates">>
+                         ?T("You are being removed from the room "
+                            "because of a system shutdown");
+                     _ -> ?T("Room terminates")
                  end,
        Packet = #presence{
                    type = unavailable,
@@ -819,27 +819,27 @@ process_groupchat_message(#message{from = From, lang = Lang} = Packet, StateData
                       Err = case (StateData#state.config)#config.allow_change_subj of
                               true ->
                                   xmpp:err_forbidden(
-                                    <<"Only moderators and participants are "
-                                      "allowed to change the subject in this "
-                                      "room">>, Lang);
+                                    ?T("Only moderators and participants are "
+                                       "allowed to change the subject in this "
+                                       "room"), Lang);
                               _ ->
                                   xmpp:err_forbidden(
-                                    <<"Only moderators are allowed to change "
-                                      "the subject in this room">>, Lang)
+                                    ?T("Only moderators are allowed to change "
+                                       "the subject in this room"), Lang)
                             end,
                       ejabberd_router:route_error(Packet, Err),
                       {next_state, normal_state, StateData}
                 end;
             true ->
-                ErrText = <<"Visitors are not allowed to send messages "
-                            "to all occupants">>,
+                ErrText = ?T("Visitors are not allowed to send messages "
+                             "to all occupants"),
                 Err = xmpp:err_forbidden(ErrText, Lang),
                 ejabberd_router:route_error(Packet, Err),
                 {next_state, normal_state, StateData}
          end;
       false ->
-         ErrText = <<"Only occupants are allowed to send messages "
-                     "to the conference">>,
+         ErrText = ?T("Only occupants are allowed to send messages "
+                      "to the conference"),
          Err = xmpp:err_not_acceptable(ErrText, Lang),
          ejabberd_router:route_error(Packet, Err),
          {next_state, normal_state, StateData}
@@ -924,14 +924,14 @@ process_voice_request(From, Pkt, StateData) ->
                    send_voice_request(From, Lang, NSD),
                    NSD;
                {ok, _, _} ->
-                   ErrText = <<"Please, wait for a while before sending "
-                               "new voice request">>,
+                   ErrText = ?T("Please, wait for a while before sending "
+                                "new voice request"),
                    Err = xmpp:err_resource_constraint(ErrText, Lang),
                    ejabberd_router:route_error(Pkt, Err),
                    StateData#state{last_voice_request_time = Times}
            end;
        false ->
-           ErrText = <<"Voice requests are disabled in this conference">>,
+           ErrText = ?T("Voice requests are disabled in this conference"),
            Err = xmpp:err_forbidden(ErrText, Lang),
            ejabberd_router:route_error(Pkt, Err),
            StateData
@@ -956,14 +956,14 @@ process_voice_approval(From, Pkt, VoiceApproval, StateData) ->
                            StateData
                    end;
                false ->
-                   ErrText = <<"Failed to extract JID from your voice "
-                               "request approval">>,
+                   ErrText = ?T("Failed to extract JID from your voice "
+                                "request approval"),
                    Err = xmpp:err_bad_request(ErrText, Lang),
                    ejabberd_router:route_error(Pkt, Err),
                    StateData
            end;
        false ->
-           ErrText = <<"Only moderators can approve voice requests">>,
+           ErrText = ?T("Only moderators can approve voice requests"),
            Err = xmpp:err_not_allowed(ErrText, Lang),
            ejabberd_router:route_error(Pkt, Err),
            StateData
@@ -1054,15 +1054,15 @@ do_process_presence(Nick, #presence{from = From, type = available, lang = Lang}
                           is_visitor(From, StateData)}} of
                        {_, _, {false, true}} ->
                            Packet1 = Packet#presence{sub_els = [#muc{}]},
-                           ErrText = <<"Visitors are not allowed to change their "
-                                       "nicknames in this room">>,
+                           ErrText = ?T("Visitors are not allowed to change their "
+                                        "nicknames in this room"),
                            Err = xmpp:err_not_allowed(ErrText, Lang),
                            ejabberd_router:route_error(Packet1, Err),
                            StateData;
                        {true, _, _} ->
                            Packet1 = Packet#presence{sub_els = [#muc{}]},
-                           ErrText = <<"That nickname is already in use by another "
-                                       "occupant">>,
+                           ErrText = ?T("That nickname is already in use by another "
+                                        "occupant"),
                            Err = xmpp:err_conflict(ErrText, Lang),
                            ejabberd_router:route_error(Packet1, Err),
                            StateData;
@@ -1070,11 +1070,11 @@ do_process_presence(Nick, #presence{from = From, type = available, lang = Lang}
                            Packet1 = Packet#presence{sub_els = [#muc{}]},
                            Err = case Nick of
                                      <<>> ->
-                                         xmpp:err_jid_malformed(<<"Nickname can't be empty">>,
+                                         xmpp:err_jid_malformed(?T("Nickname can't be empty"),
                                                                 Lang);
                                      _ ->
-                                         xmpp:err_conflict(<<"That nickname is registered"
-                                                             " by another person">>, Lang)
+                                         xmpp:err_conflict(?T("That nickname is registered"
+                                                              " by another person"), Lang)
                                  end,
                            ejabberd_router:route_error(Packet1, Err),
                            StateData;
@@ -1121,9 +1121,9 @@ do_process_presence(Nick, #presence{from = From, type = unavailable} = Packet,
     remove_online_user(From, NewState, Reason);
 do_process_presence(_Nick, #presence{from = From, type = error, lang = Lang} = Packet,
                    StateData) ->
-    ErrorText = <<"It is not allowed to send error messages to the"
-                 " room. The participant (~s) has sent an error "
-                 "message (~s) and got kicked from the room">>,
+    ErrorText = ?T("It is not allowed to send error messages to the"
+                  " room. The participant (~s) has sent an error "
+                  "message (~s) and got kicked from the room"),
     expulse_participant(Packet, From, StateData,
                        translate:translate(Lang, ErrorText)).
 
@@ -1880,7 +1880,7 @@ add_new_user(From, Nick, Packet, StateData) ->
          get_default_role(Affiliation, StateData)}
        of
       {false, _, _, _} when NUsers >= MaxUsers orelse NUsers >= MaxAdminUsers ->
-         Txt = <<"Too many users in this conference">>,
+         Txt = ?T("Too many users in this conference"),
          Err = xmpp:err_resource_constraint(Txt, Lang),
          if not IsSubscribeRequest ->
                  ejabberd_router:route_error(Packet, Err),
@@ -1889,7 +1889,7 @@ add_new_user(From, Nick, Packet, StateData) ->
                  {error, Err}
          end;
       {false, _, _, _} when NConferences >= MaxConferences ->
-         Txt = <<"You have joined too many conferences">>,
+         Txt = ?T("You have joined too many conferences"),
          Err = xmpp:err_resource_constraint(Txt, Lang),
          if not IsSubscribeRequest ->
                  ejabberd_router:route_error(Packet, Err),
@@ -1908,10 +1908,10 @@ add_new_user(From, Nick, Packet, StateData) ->
       {_, _, _, none} ->
          Err = case Affiliation of
                    outcast ->
-                       ErrText = <<"You have been banned from this room">>,
+                       ErrText = ?T("You have been banned from this room"),
                        xmpp:err_forbidden(ErrText, Lang);
                    _ ->
-                       ErrText = <<"Membership is required to enter this room">>,
+                       ErrText = ?T("Membership is required to enter this room"),
                        xmpp:err_registration_required(ErrText, Lang)
                end,
          if not IsSubscribeRequest ->
@@ -1921,7 +1921,7 @@ add_new_user(From, Nick, Packet, StateData) ->
                  {error, Err}
          end;
       {_, true, _, _} ->
-         ErrText = <<"That nickname is already in use by another occupant">>,
+         ErrText = ?T("That nickname is already in use by another occupant"),
          Err = xmpp:err_conflict(ErrText, Lang),
          if not IsSubscribeRequest ->
                  ejabberd_router:route_error(Packet, Err),
@@ -1932,11 +1932,11 @@ add_new_user(From, Nick, Packet, StateData) ->
       {_, _, false, _} ->
          Err = case Nick of
                        <<>> ->
-                           xmpp:err_jid_malformed(<<"Nickname can't be empty">>,
+                           xmpp:err_jid_malformed(?T("Nickname can't be empty"),
                                                   Lang);
                        _ ->
-                           xmpp:err_conflict(<<"That nickname is registered"
-                                               " by another person">>, Lang)
+                           xmpp:err_conflict(?T("That nickname is registered"
+                                                " by another person"), Lang)
                    end,
          if not IsSubscribeRequest ->
                  ejabberd_router:route_error(Packet, Err),
@@ -1974,7 +1974,7 @@ add_new_user(From, Nick, Packet, StateData) ->
                     true -> {result, subscribe_result(Packet), ResultState}
                  end;
            need_password ->
-               ErrText = <<"A password is required to enter this room">>,
+               ErrText = ?T("A password is required to enter this room"),
                Err = xmpp:err_not_authorized(ErrText, Lang),
                if not IsSubscribeRequest ->
                        ejabberd_router:route_error(Packet, Err),
@@ -2005,7 +2005,7 @@ add_new_user(From, Nick, Packet, StateData) ->
                              {ignore, NewState}
                      end;
                  {error, limit} ->
-                     ErrText = <<"Too many CAPTCHA requests">>,
+                     ErrText = ?T("Too many CAPTCHA requests"),
                      Err = xmpp:err_resource_constraint(ErrText, Lang),
                      if not IsSubscribeRequest ->
                              ejabberd_router:route_error(Packet, Err),
@@ -2014,7 +2014,7 @@ add_new_user(From, Nick, Packet, StateData) ->
                              {error, Err}
                      end;
                  _ ->
-                     ErrText = <<"Unable to generate a CAPTCHA">>,
+                     ErrText = ?T("Unable to generate a CAPTCHA"),
                      Err = xmpp:err_internal_server_error(ErrText, Lang),
                      if not IsSubscribeRequest ->
                              ejabberd_router:route_error(Packet, Err),
@@ -2024,7 +2024,7 @@ add_new_user(From, Nick, Packet, StateData) ->
                      end
                end;
            _ ->
-               ErrText = <<"Incorrect password">>,
+               ErrText = ?T("Incorrect password"),
                Err = xmpp:err_not_authorized(ErrText, Lang),
                if not IsSubscribeRequest ->
                        ejabberd_router:route_error(Packet, Err),
@@ -2589,7 +2589,7 @@ can_change_subject(Role, IsSubscriber, StateData) ->
                                                 {result, muc_admin()}.
 process_iq_admin(_From, #iq{lang = Lang, sub_els = [#muc_admin{items = []}]},
                 _StateData) ->
-    Txt = <<"No 'item' element found">>,
+    Txt = ?T("No 'item' element found"),
     {error, xmpp:err_bad_request(Txt, Lang)};
 process_iq_admin(From, #iq{type = set, lang = Lang,
                           sub_els = [#muc_admin{items = Items}]},
@@ -2602,7 +2602,7 @@ process_iq_admin(From, #iq{type = get, lang = Lang,
     FRole = get_role(From, StateData),
     case Item of
        #muc_item{role = undefined, affiliation = undefined} ->
-           Txt = <<"Neither 'role' nor 'affiliation' attribute found">>,
+           Txt = ?T("Neither 'role' nor 'affiliation' attribute found"),
            {error, xmpp:err_bad_request(Txt, Lang)};
        #muc_item{role = undefined, affiliation = Affiliation} ->
            if (FAffiliation == owner) or
@@ -2612,7 +2612,7 @@ process_iq_admin(From, #iq{type = get, lang = Lang,
                    Items = items_with_affiliation(Affiliation, StateData),
                    {result, #muc_admin{items = Items}};
               true ->
-                   ErrText = <<"Administrator privileges required">>,
+                   ErrText = ?T("Administrator privileges required"),
                    {error, xmpp:err_forbidden(ErrText, Lang)}
            end;
        #muc_item{role = Role} ->
@@ -2620,12 +2620,12 @@ process_iq_admin(From, #iq{type = get, lang = Lang,
                    Items = items_with_role(Role, StateData),
                    {result, #muc_admin{items = Items}};
               true ->
-                   ErrText = <<"Moderator privileges required">>,
+                   ErrText = ?T("Moderator privileges required"),
                    {error, xmpp:err_forbidden(ErrText, Lang)}
            end
     end;
 process_iq_admin(_From, #iq{type = get, lang = Lang}, _StateData) ->
-    ErrText = <<"Too many <item/> elements">>,
+    ErrText = ?T("Too many <item/> elements"),
     {error, xmpp:err_bad_request(ErrText, Lang)}.
 
 -spec items_with_role(role(), state()) -> [muc_item()].
@@ -2797,12 +2797,12 @@ find_changed_items(_UJID, _UAffiliation, _URole, [],
 find_changed_items(_UJID, _UAffiliation, _URole,
                   [#muc_item{jid = undefined, nick = <<"">>}|_],
                   Lang, _StateData, _Res) ->
-    Txt = <<"Neither 'jid' nor 'nick' attribute found">>,
+    Txt = ?T("Neither 'jid' nor 'nick' attribute found"),
     throw({error, xmpp:err_bad_request(Txt, Lang)});
 find_changed_items(_UJID, _UAffiliation, _URole,
                   [#muc_item{role = undefined, affiliation = undefined}|_],
                   Lang, _StateData, _Res) ->
-    Txt = <<"Neither 'role' nor 'affiliation' attribute found">>,
+    Txt = ?T("Neither 'role' nor 'affiliation' attribute found"),
     throw({error, xmpp:err_bad_request(Txt, Lang)});
 find_changed_items(UJID, UAffiliation, URole,
                   [#muc_item{jid = J, nick = Nick, reason = Reason,
@@ -2814,7 +2814,7 @@ find_changed_items(UJID, UAffiliation, URole,
           Nick /= <<"">> ->
                case find_jids_by_nick(Nick, StateData) of
                    [] ->
-                       ErrText = {<<"Nickname ~s does not exist in the room">>,
+                       ErrText = {?T("Nickname ~s does not exist in the room"),
                                   [Nick]},
                        throw({error, xmpp:err_not_acceptable(ErrText, Lang)});
                    JIDList ->
@@ -2870,7 +2870,7 @@ find_changed_items(UJID, UAffiliation, URole,
                               Items, Lang, StateData,
                               MoreRes ++ Res);
        false ->
-           Txt = <<"Changing role/affiliation is not allowed">>,
+           Txt = ?T("Changing role/affiliation is not allowed"),
            throw({error, xmpp:err_not_allowed(Txt, Lang)})
     end.
 
@@ -3163,7 +3163,7 @@ process_iq_owner(From, #iq{type = set, lang = Lang,
                 StateData) ->
     FAffiliation = get_affiliation(From, StateData),
     if FAffiliation /= owner ->
-           ErrText = <<"Owner privileges required">>,
+           ErrText = ?T("Owner privileges required"),
            {error, xmpp:err_forbidden(ErrText, Lang)};
        Destroy /= undefined, Config == undefined, Items == [] ->
            ?INFO_MSG("Destroyed MUC room ~s by the owner ~s",
@@ -3193,7 +3193,7 @@ process_iq_owner(From, #iq{type = set, lang = Lang,
                            {error, xmpp:err_bad_request(Txt, Lang)}
                    end;
                _ ->
-                   Txt = <<"Incorrect data form">>,
+                   Txt = ?T("Incorrect data form"),
                    {error, xmpp:err_bad_request(Txt, Lang)}
            end;
        Items /= [], Config == undefined, Destroy == undefined ->
@@ -3208,7 +3208,7 @@ process_iq_owner(From, #iq{type = get, lang = Lang,
                 StateData) ->
     FAffiliation = get_affiliation(From, StateData),
     if FAffiliation /= owner ->
-           ErrText = <<"Owner privileges required">>,
+           ErrText = ?T("Owner privileges required"),
            {error, xmpp:err_forbidden(ErrText, Lang)};
        Destroy == undefined, Config == undefined ->
            case Items of
@@ -3216,13 +3216,13 @@ process_iq_owner(From, #iq{type = get, lang = Lang,
                    {result,
                     #muc_owner{config = get_config(Lang, StateData, From)}};
                [#muc_item{affiliation = undefined}] ->
-                   Txt = <<"No 'affiliation' attribute found">>,
+                   Txt = ?T("No 'affiliation' attribute found"),
                    {error, xmpp:err_bad_request(Txt, Lang)};
                [#muc_item{affiliation = Affiliation}] ->
                    Items = items_with_affiliation(Affiliation, StateData),
                    {result, #muc_owner{items = Items}};
                [_|_] ->
-                   Txt = <<"Too many <item/> elements">>,
+                   Txt = ?T("Too many <item/> elements"),
                    {error, xmpp:err_bad_request(Txt, Lang)}
            end;
        true ->
@@ -3309,7 +3309,7 @@ get_config(Lang, StateData, From) ->
     Config = StateData#state.config,
     MaxUsersRoom = get_max_users(StateData),
     Title = str:format(
-             translate:translate(Lang, <<"Configuration of room ~s">>),
+             translate:translate(Lang, ?T("Configuration of room ~s")),
              [jid:encode(StateData#state.jid)]),
     Fs = [{roomname, Config#config.title},
          {roomdesc, Config#config.description},
@@ -3327,7 +3327,7 @@ get_config(Lang, StateData, From) ->
                      end},
         {maxusers, MaxUsersRoom,
          [if is_integer(ServiceMaxUsers) -> [];
-             true -> [{<<"No limit">>, <<"none">>}]
+             true -> [{?T("No limit"), <<"none">>}]
           end] ++ [{integer_to_binary(N), N}
                    || N <- lists:usort([ServiceMaxUsers,
                                         DefaultRoomMaxUsers,
@@ -3448,7 +3448,7 @@ set_config(Opts, Config, ServerHost, Lang) ->
                  {0, undefined} ->
                      ?ERROR_MSG("set_room_option hook failed for "
                                 "option '~s' with value ~p", [O, V]),
-                     Txt = {<<"Failed to process option '~s'">>, [O]},
+                     Txt = {?T("Failed to process option '~s'"), [O]},
                      {error, xmpp:err_internal_server_error(Txt, Lang)};
                  {Pos, Val} ->
                      setelement(Pos, C, Val)
@@ -3874,7 +3874,7 @@ make_disco_info(_From, StateData) ->
 -spec process_iq_disco_info(jid(), iq(), state()) ->
                                   {result, disco_info()} | {error, stanza_error()}.
 process_iq_disco_info(_From, #iq{type = set, lang = Lang}, _StateData) ->
-    Txt = <<"Value 'set' of 'type' attribute is not allowed">>,
+    Txt = ?T("Value 'set' of 'type' attribute is not allowed"),
     {error, xmpp:err_not_allowed(Txt, Lang)};
 process_iq_disco_info(From, #iq{type = get, lang = Lang,
                                sub_els = [#disco_info{node = <<>>}]},
@@ -3894,7 +3894,7 @@ process_iq_disco_info(From, #iq{type = get, lang = Lang,
        Node = <<(ejabberd_config:get_uri())/binary, $#, Hash/binary>>,
        {result, DiscoInfo1#disco_info{node = Node}}
     catch _:{badmatch, _} ->
-           Txt = <<"Invalid node name">>,
+           Txt = ?T("Invalid node name"),
            {error, xmpp:err_item_not_found(Txt, Lang)}
     end.
 
@@ -3934,7 +3934,7 @@ iq_disco_info_extras(Lang, StateData, Static) ->
 -spec process_iq_disco_items(jid(), iq(), state()) ->
                                    {error, stanza_error()} | {result, disco_items()}.
 process_iq_disco_items(_From, #iq{type = set, lang = Lang}, _StateData) ->
-    Txt = <<"Value 'set' of 'type' attribute is not allowed">>,
+    Txt = ?T("Value 'set' of 'type' attribute is not allowed"),
     {error, xmpp:err_not_allowed(Txt, Lang)};
 process_iq_disco_items(From, #iq{type = get}, StateData) ->
     case (StateData#state.config)#config.public_list of
@@ -3955,17 +3955,17 @@ process_iq_disco_items(From, #iq{type = get}, StateData) ->
 -spec process_iq_captcha(jid(), iq(), state()) -> {error, stanza_error()} |
                                                  {result, undefined}.
 process_iq_captcha(_From, #iq{type = get, lang = Lang}, _StateData) ->
-    Txt = <<"Value 'get' of 'type' attribute is not allowed">>,
+    Txt = ?T("Value 'get' of 'type' attribute is not allowed"),
     {error, xmpp:err_not_allowed(Txt, Lang)};
 process_iq_captcha(_From, #iq{type = set, lang = Lang, sub_els = [SubEl]},
                   _StateData) ->
     case ejabberd_captcha:process_reply(SubEl) of
       ok -> {result, undefined};
       {error, malformed} ->
-           Txt = <<"Incorrect CAPTCHA submit">>,
+           Txt = ?T("Incorrect CAPTCHA submit"),
            {error, xmpp:err_bad_request(Txt, Lang)};
       _ ->
-           Txt = <<"The CAPTCHA verification has failed">>,
+           Txt = ?T("The CAPTCHA verification has failed"),
            {error, xmpp:err_not_allowed(Txt, Lang)}
     end.
 
@@ -3992,7 +3992,7 @@ process_iq_vcard(From, #iq{type = set, lang = Lang, sub_els = [Pkt]},
            NewConfig = Config#config{vcard = VCardRaw, vcard_xupdate = Hash},
            change_config(NewConfig, StateData);
        _ ->
-           ErrText = <<"Owner privileges required">>,
+           ErrText = ?T("Owner privileges required"),
            {error, xmpp:err_forbidden(ErrText, Lang)}
     end.
 
@@ -4003,7 +4003,7 @@ process_iq_vcard(From, #iq{type = set, lang = Lang, sub_els = [Pkt]},
 process_iq_mucsub(_From, #iq{type = set, lang = Lang,
                             sub_els = [#muc_subscribe{}]},
                  #state{just_created = Just, config = #config{allow_subscription = false}}) when Just /= true ->
-    {error, xmpp:err_not_allowed(<<"Subscriptions are not allowed">>, Lang)};
+    {error, xmpp:err_not_allowed(?T("Subscriptions are not allowed"), Lang)};
 process_iq_mucsub(From,
                  #iq{type = set, lang = Lang,
                      sub_els = [#muc_subscribe{jid = #jid{} = SubJid} = Mucsub]},
@@ -4016,7 +4016,7 @@ process_iq_mucsub(From,
                                  sub_els = [Mucsub#muc_subscribe{jid = undefined}]},
                              StateData);
        true ->
-           Txt = <<"Moderator privileges required">>,
+           Txt = ?T("Moderator privileges required"),
            {error, xmpp:err_forbidden(Txt, Lang)}
     end;
 process_iq_mucsub(From,
@@ -4032,16 +4032,16 @@ process_iq_mucsub(From,
                                       StateData#state.host,
                                       From, Nick)} of
                {true, _} ->
-                   ErrText = <<"That nickname is already in use by another occupant">>,
+                   ErrText = ?T("That nickname is already in use by another occupant"),
                    {error, xmpp:err_conflict(ErrText, Lang)};
                {_, false} ->
                    Err = case Nick of
                              <<>> ->
-                                 xmpp:err_jid_malformed(<<"Nickname can't be empty">>,
+                                 xmpp:err_jid_malformed(?T("Nickname can't be empty"),
                                                         Lang);
                              _ ->
-                                 xmpp:err_conflict(<<"That nickname is registered"
-                                                     " by another person">>, Lang)
+                                 xmpp:err_conflict(?T("That nickname is registered"
+                                                      " by another person"), Lang)
                          end,
                    {error, Err};
                _ ->
@@ -4067,7 +4067,7 @@ process_iq_mucsub(From, #iq{type = set, lang = Lang,
                                  sub_els = [#muc_unsubscribe{jid = undefined}]},
                              StateData);
        true ->
-           Txt = <<"Moderator privileges required">>,
+           Txt = ?T("Moderator privileges required"),
            {error, xmpp:err_forbidden(Txt, Lang)}
     end;
 process_iq_mucsub(From, #iq{type = set, sub_els = [#muc_unsubscribe{}]},
@@ -4113,11 +4113,11 @@ process_iq_mucsub(From, #iq{type = get, lang = Lang,
                     end, [], StateData#state.subscribers),
            {result, #muc_subscriptions{list = Subs}, StateData};
        _ ->
-           Txt = <<"Moderator privileges required">>,
+           Txt = ?T("Moderator privileges required"),
            {error, xmpp:err_forbidden(Txt, Lang)}
     end;
 process_iq_mucsub(_From, #iq{type = get, lang = Lang}, _StateData) ->
-    Txt = <<"Value 'get' of 'type' attribute is not allowed">>,
+    Txt = ?T("Value 'get' of 'type' attribute is not allowed"),
     {error, xmpp:err_bad_request(Txt, Lang)}.
 
 remove_subscriptions(StateData) ->
@@ -4172,7 +4172,7 @@ get_roomdesc_reply(JID, StateData, Tail) ->
 get_roomdesc_tail(StateData, Lang) ->
     Desc = case (StateData#state.config)#config.public of
             true -> <<"">>;
-            _ -> translate:translate(Lang, <<"private, ">>)
+            _ -> translate:translate(Lang, ?T("private, "))
           end,
     Len = maps:size(StateData#state.nicks),
     <<" (", Desc/binary, (integer_to_binary(Len))/binary, ")">>.
@@ -4193,9 +4193,9 @@ get_mucroom_disco_items(StateData) ->
 
 -spec prepare_request_form(jid(), binary(), binary()) -> message().
 prepare_request_form(Requester, Nick, Lang) ->
-    Title = translate:translate(Lang, <<"Voice request">>),
+    Title = translate:translate(Lang, ?T("Voice request")),
     Instruction = translate:translate(
-                   Lang, <<"Either approve or decline the voice request.">>),
+                   Lang, ?T("Either approve or decline the voice request.")),
     Fs = muc_request:encode([{role, participant},
                             {jid, Requester},
                             {roomnick, Nick},
@@ -4237,11 +4237,11 @@ check_invitation(From, Invitations, Lang, StateData) ->
                true ->
                    ok;
                false ->
-                   Txt = <<"No 'to' attribute found in the invitation">>,
+                   Txt = ?T("No 'to' attribute found in the invitation"),
                    {error, xmpp:err_bad_request(Txt, Lang)}
            end;
        false ->
-           Txt = <<"Invitations are not allowed in this conference">>,
+           Txt = ?T("Invitations are not allowed in this conference"),
            {error, xmpp:err_not_allowed(Txt, Lang)}
     end.
 
@@ -4263,14 +4263,14 @@ route_invitation(From, Pkt, Invitation, Lang, StateData) ->
             [io_lib:format(
                translate:translate(
                  Lang,
-                 <<"~s invites you to the room ~s">>),
+                 ?T("~s invites you to the room ~s")),
                [jid:encode(From),
                 jid:encode({StateData#state.room, StateData#state.host, <<"">>})]),
              case (StateData#state.config)#config.password_protected of
                  true ->
                      <<", ",
                        (translate:translate(
-                          Lang, <<"the password is">>))/binary,
+                          Lang, ?T("the password is")))/binary,
                        " '",
                        ((StateData#state.config)#config.password)/binary,
                        "'">>;
@@ -4306,8 +4306,8 @@ handle_roommessage_from_nonparticipant(Packet, StateData, From) ->
            ejabberd_router:route(
              xmpp:set_from_to(NewPacket, StateData#state.jid, To));
        _ ->
-           ErrText = <<"Only occupants are allowed to send messages "
-                       "to the conference">>,
+           ErrText = ?T("Only occupants are allowed to send messages "
+                        "to the conference"),
            Err = xmpp:err_not_acceptable(ErrText, xmpp:get_lang(Packet)),
            ejabberd_router:route_error(Packet, Err)
     catch _:{xmpp_codec, Why} ->
index 9c527299615042b8c75d525bc6f14ec0edf7358e..70d1e20734ad0b56163ac05f486f0f4b5884dc6d 100644 (file)
@@ -322,27 +322,27 @@ route_untrusted(LServiceS, LServerS, Access, SLimits, Packet) ->
     catch
       adenied ->
          route_error(Packet, forbidden,
-                     <<"Access denied by service policy">>);
+                     ?T("Access denied by service policy"));
       eadsele ->
          route_error(Packet, bad_request,
-                     <<"No addresses element found">>);
+                     ?T("No addresses element found"));
       eadeles ->
          route_error(Packet, bad_request,
-                     <<"No address elements found">>);
+                     ?T("No address elements found"));
       ewxmlns ->
          route_error(Packet, bad_request,
-                     <<"Wrong xmlns">>);
+                     ?T("Wrong xmlns"));
       etoorec ->
          route_error(Packet, not_acceptable,
-                     <<"Too many receiver fields were specified">>);
+                     ?T("Too many receiver fields were specified"));
       edrelay ->
          route_error(Packet, forbidden,
-                     <<"Packet relay is denied by service policy">>);
+                     ?T("Packet relay is denied by service policy"));
       EType:EReason ->
          ?ERROR_MSG("Multicast unknown error: Type: ~p~nReason: ~p",
                     [EType, EReason]),
          route_error(Packet, internal_server_error,
-                     <<"Unknown problem">>)
+                     ?T("Internal server error"))
     end.
 
 -spec route_untrusted2(binary(), binary(), atom(), #service_limits{}, stanza()) -> 'ok'.
@@ -486,9 +486,9 @@ split_dests_jid(Dests) ->
 report_not_jid(From, Packet, Dests) ->
     Dests2 = [fxml:element_to_binary(xmpp:encode(Dest#dest.address))
              || Dest <- Dests],
-    [route_error(xmpp:set_from_to(Packet, From, From), jid_malformed,
-                <<"This service can not process the address: ",
-                  D/binary>>)
+    [route_error(
+       xmpp:set_from_to(Packet, From, From), jid_malformed,
+       str:format(?T("This service can not process the address: ~s"), [D]))
      || D <- Dests2].
 
 %%%-------------------------
index a3cb6d858b2b9d18b4eb4672f739864ebe9a9c29..8ec3183c8ddb6b0307835be4a75a588d924aea09 100644 (file)
@@ -77,6 +77,8 @@
 
 -include("mod_offline.hrl").
 
+-include("translate.hrl").
+
 -define(OFFLINE_TABLE_LOCK_THRESHOLD, 1000).
 
 %% default value for the maximum number of user messages
@@ -294,7 +296,7 @@ handle_offline_query(#iq{from = #jid{luser = U1, lserver = S1},
                         lang = Lang,
                         sub_els = [#offline{}]} = IQ)
   when {U1, S1} /= {U2, S2} ->
-    Txt = <<"Query to another users is forbidden">>,
+    Txt = ?T("Query to another users is forbidden"),
     xmpp:make_error(IQ, xmpp:err_forbidden(Txt, Lang));
 handle_offline_query(#iq{from = #jid{luser = U, lserver = S} = From,
                         to = #jid{luser = U, lserver = S} = _To,
@@ -315,7 +317,7 @@ handle_offline_query(#iq{from = #jid{luser = U, lserver = S} = From,
                {atomic, ok} ->
                    xmpp:make_iq_result(IQ);
                _Err ->
-                   Txt = <<"Database failure">>,
+                   Txt = ?T("Database failure"),
                    xmpp:make_error(IQ, xmpp:err_internal_server_error(Txt, Lang))
            end;
        {set, #offline{fetch = false, items = [_|_] = Items, purge = false}} ->
@@ -327,7 +329,7 @@ handle_offline_query(#iq{from = #jid{luser = U, lserver = S} = From,
            xmpp:make_error(IQ, xmpp:err_bad_request())
     end;
 handle_offline_query(#iq{lang = Lang} = IQ) ->
-    Txt = <<"No module is handling this query">>,
+    Txt = ?T("No module is handling this query"),
     xmpp:make_error(IQ, xmpp:err_service_unavailable(Txt, Lang)).
 
 -spec handle_offline_items_view(jid(), [offline_item()]) -> boolean().
@@ -664,11 +666,11 @@ discard_warn_sender(Packet, Reason) ->
            Lang = xmpp:get_lang(Packet),
            Err = case Reason of
                      full ->
-                         ErrText = <<"Your contact offline message queue is "
-                                     "full. The message has been discarded.">>,
+                         ErrText = ?T("Your contact offline message queue is "
+                                      "full. The message has been discarded."),
                          xmpp:err_resource_constraint(ErrText, Lang);
                      _ ->
-                         ErrText = <<"Database failure">>,
+                         ErrText = ?T("Database failure"),
                          xmpp:err_internal_server_error(ErrText, Lang)
                  end,
            ejabberd_router:route_error(Packet, Err);
@@ -915,18 +917,18 @@ user_queue(User, Server, Query, Lang) ->
     Hdrs = get_messages_subset(User, Server, HdrsAll),
     FMsgs = format_user_queue(Hdrs),
     [?XC(<<"h1">>,
-        (str:format(?T(<<"~s's Offline Messages Queue">>),
-                                      [us_to_list(US)])))]
-      ++ [?XREST(<<"Submitted">>)] ++
+        (str:format(translate:translate(Lang, ?T("~s's Offline Messages Queue")),
+                    [us_to_list(US)])))]
+      ++ [?XREST(?T("Submitted"))] ++
        [?XAE(<<"form">>,
              [{<<"action">>, <<"">>}, {<<"method">>, <<"post">>}],
              [?XE(<<"table">>,
                   [?XE(<<"thead">>,
                        [?XE(<<"tr">>,
-                            [?X(<<"td">>), ?XCT(<<"td">>, <<"Time">>),
-                             ?XCT(<<"td">>, <<"From">>),
-                             ?XCT(<<"td">>, <<"To">>),
-                             ?XCT(<<"td">>, <<"Packet">>)])]),
+                            [?X(<<"td">>), ?XCT(<<"td">>, ?T("Time")),
+                             ?XCT(<<"td">>, ?T("From")),
+                             ?XCT(<<"td">>, ?T("To")),
+                             ?XCT(<<"td">>, ?T("Packet"))])]),
                    ?XE(<<"tbody">>,
                        if FMsgs == [] ->
                               [?XE(<<"tr">>,
@@ -936,7 +938,7 @@ user_queue(User, Server, Query, Lang) ->
                        end)]),
               ?BR,
               ?INPUTT(<<"submit">>, <<"delete">>,
-                      <<"Delete Selected">>)])].
+                      ?T("Delete Selected"))])].
 
 user_queue_parse_query(LUser, LServer, Query) ->
     Mod = gen_mod:db_mod(LServer, ?MODULE),
@@ -994,11 +996,11 @@ webadmin_user(Acc, User, Server, Lang) ->
     FQueueLen = [?AC(<<"queue/">>,
                     (integer_to_binary(QueueLen)))],
     Acc ++
-      [?XCT(<<"h3">>, <<"Offline Messages:">>)] ++
+      [?XCT(<<"h3">>, ?T("Offline Messages:"))] ++
        FQueueLen ++
          [?C(<<" ">>),
           ?INPUTT(<<"submit">>, <<"removealloffline">>,
-                  <<"Remove All Offline Messages">>)].
+                  ?T("Remove All Offline Messages"))].
 
 -spec delete_all_msgs(binary(), binary()) -> {atomic, any()}.
 delete_all_msgs(User, Server) ->
index aeb3aedbd582b70ab357c195507237a490322077..a41bd8d1ef0da06ed53b7c60b73097fc6da3a859 100644 (file)
@@ -37,6 +37,8 @@
 
 -include("xmpp.hrl").
 
+-include("translate.hrl").
+
 %% API
 -export([start_ping/2, stop_ping/2]).
 
@@ -169,7 +171,7 @@ code_change(_OldVsn, State, _Extra) -> {ok, State}.
 iq_ping(#iq{type = get, sub_els = [#ping{}]} = IQ) ->
     xmpp:make_iq_result(IQ);
 iq_ping(#iq{lang = Lang} = IQ) ->
-    Txt = <<"Ping query is incorrect">>,
+    Txt = ?T("Ping query is incorrect"),
     xmpp:make_error(IQ, xmpp:err_bad_request(Txt, Lang)).
 
 -spec user_online(ejabberd_sm:sid(), jid(), ejabberd_sm:info()) -> ok.
index 7ac8f4a8e60301d97f67e5bbf1bf69a6b78d7394..3c394dc53adfa367251946725a613a464c036a9b 100644 (file)
@@ -43,6 +43,7 @@
 -include("logger.hrl").
 -include("xmpp.hrl").
 -include("mod_privacy.hrl").
+-include("translate.hrl").
 
 -define(PRIVACY_CACHE, privacy_cache).
 -define(PRIVACY_LIST_CACHE, privacy_list_cache).
@@ -130,7 +131,7 @@ process_iq(#iq{type = Type,
        set -> process_iq_set(IQ)
     end;
 process_iq(#iq{lang = Lang} = IQ) ->
-    Txt = <<"Query to another users is forbidden">>,
+    Txt = ?T("Query to another users is forbidden"),
     xmpp:make_error(IQ, xmpp:err_forbidden(Txt, Lang)).
 
 -spec process_iq_get(iq()) -> iq().
@@ -138,7 +139,7 @@ process_iq_get(#iq{lang = Lang,
                      sub_els = [#privacy_query{default = Default,
                                             active = Active}]} = IQ)
   when Default /= undefined; Active /= undefined ->
-    Txt = <<"Only <list/> element is allowed in this query">>,
+    Txt = ?T("Only <list/> element is allowed in this query"),
     xmpp:make_error(IQ, xmpp:err_bad_request(Txt, Lang));
 process_iq_get(#iq{lang = Lang,
                   sub_els = [#privacy_query{lists = Lists}]} = IQ) ->
@@ -148,11 +149,11 @@ process_iq_get(#iq{lang = Lang,
        [#privacy_list{name = ListName}] ->
            process_list_get(IQ, ListName);
        _ ->
-           Txt = <<"Too many <list/> elements">>,
+           Txt = ?T("Too many <list/> elements"),
            xmpp:make_error(IQ, xmpp:err_bad_request(Txt, Lang))
     end;
 process_iq_get(#iq{lang = Lang} = IQ) ->
-    Txt = <<"No module is handling this query">>,
+    Txt = ?T("No module is handling this query"),
     xmpp:make_error(IQ, xmpp:err_service_unavailable(Txt, Lang)).
 
 -spec process_lists_get(iq()) -> iq().
@@ -170,7 +171,7 @@ process_lists_get(#iq{from = #jid{luser = LUser, lserver = LServer},
            xmpp:make_iq_result(
              IQ, #privacy_query{active = none, default = none});
        {error, _} ->
-           Txt = <<"Database failure">>,
+           Txt = ?T("Database failure"),
            xmpp:make_error(IQ, xmpp:err_internal_server_error(Txt, Lang))
     end.
 
@@ -185,10 +186,10 @@ process_list_get(#iq{from = #jid{luser = LUser, lserver = LServer},
              #privacy_query{
                 lists = [#privacy_list{name = Name, items = Items}]});
        error ->
-           Txt = <<"No privacy list with this name found">>,
+           Txt = ?T("No privacy list with this name found"),
            xmpp:make_error(IQ, xmpp:err_item_not_found(Txt, Lang));
        {error, _} ->
-           Txt = <<"Database failure">>,
+           Txt = ?T("Database failure"),
            xmpp:make_error(IQ, xmpp:err_internal_server_error(Txt, Lang))
     end.
 
@@ -264,12 +265,12 @@ process_iq_set(#iq{lang = Lang,
        [] when Active == undefined, Default /= undefined ->
            process_default_set(IQ, Default);
        _ ->
-           Txt = <<"The stanza MUST contain only one <active/> element, "
-                   "one <default/> element, or one <list/> element">>,
+           Txt = ?T("The stanza MUST contain only one <active/> element, "
+                    "one <default/> element, or one <list/> element"),
            xmpp:make_error(IQ, xmpp:err_bad_request(Txt, Lang))
     end;
 process_iq_set(#iq{lang = Lang} = IQ) ->
-    Txt = <<"No module is handling this query">>,
+    Txt = ?T("No module is handling this query"),
     xmpp:make_error(IQ, xmpp:err_service_unavailable(Txt, Lang)).
 
 -spec process_default_set(iq(), none | binary()) -> iq().
@@ -279,10 +280,10 @@ process_default_set(#iq{from = #jid{luser = LUser, lserver = LServer},
        ok ->
            xmpp:make_iq_result(IQ);
        {error, notfound} ->
-           Txt = <<"No privacy list with this name found">>,
+           Txt = ?T("No privacy list with this name found"),
            xmpp:make_error(IQ, xmpp:err_item_not_found(Txt, Lang));
        {error, _} ->
-           Txt = <<"Database failure">>,
+           Txt = ?T("Database failure"),
            xmpp:make_error(IQ, xmpp:err_internal_server_error(Txt, Lang))
     end.
 
@@ -295,10 +296,10 @@ process_active_set(#iq{from = #jid{luser = LUser, lserver = LServer},
        {ok, _} ->
            xmpp:make_iq_result(xmpp:put_meta(IQ, privacy_active_list, Name));
        error ->
-           Txt = <<"No privacy list with this name found">>,
+           Txt = ?T("No privacy list with this name found"),
            xmpp:make_error(IQ, xmpp:err_item_not_found(Txt, Lang));
        {error, _} ->
-           Txt = <<"Database failure">>,
+           Txt = ?T("Database failure"),
            xmpp:make_error(IQ, xmpp:err_internal_server_error(Txt, Lang))
     end.
 
@@ -318,20 +319,20 @@ process_lists_set(#iq{from = #jid{luser = LUser, lserver = LServer},
                      lang = Lang} = IQ, Name, []) ->
     case xmpp:get_meta(IQ, privacy_active_list, none) of
        Name ->
-           Txt = <<"Cannot remove active list">>,
+           Txt = ?T("Cannot remove active list"),
            xmpp:make_error(IQ, xmpp:err_conflict(Txt, Lang));
        _ ->
            case remove_list(LUser, LServer, Name) of
                ok ->
                    xmpp:make_iq_result(IQ);
                {error, conflict} ->
-                   Txt = <<"Cannot remove default list">>,
+                   Txt = ?T("Cannot remove default list"),
                    xmpp:make_error(IQ, xmpp:err_conflict(Txt, Lang));
                {error, notfound} ->
-                   Txt = <<"No privacy list with this name found">>,
+                   Txt = ?T("No privacy list with this name found"),
                    xmpp:make_error(IQ, xmpp:err_item_not_found(Txt, Lang));
                {error, _} ->
-                   Txt = <<"Database failure">>,
+                   Txt = ?T("Database failure"),
                    Err = xmpp:err_internal_server_error(Txt, Lang),
                    xmpp:make_error(IQ, Err)
            end
@@ -348,7 +349,7 @@ process_lists_set(#iq{from = #jid{luser = LUser, lserver = LServer} = From,
                    push_list_update(From, Name),
                    xmpp:make_iq_result(IQ);
                {error, _} ->
-                   Txt = <<"Database failure">>,
+                   Txt = ?T("Database failure"),
                    xmpp:make_error(IQ, xmpp:err_internal_server_error(Txt, Lang))
            end
     end.
index 9c6ba0ed085818dd7f99acce5b934554c48b4177..19f5476421ff9b3bb38497428d21f8e1e76724ed 100644 (file)
@@ -43,6 +43,7 @@
 -include("xmpp.hrl").
 -include("mod_private.hrl").
 -include("ejabberd_commands.hrl").
+-include("translate.hrl").
 
 -define(PRIVATE_CACHE, private_cache).
 
@@ -136,7 +137,7 @@ process_sm_iq(#iq{type = Type, lang = Lang,
                  sub_els = [#private{sub_els = Els0}]} = IQ) ->
     case filter_xmlels(Els0) of
        [] ->
-           Txt = <<"No private data found in this query">>,
+           Txt = ?T("No private data found in this query"),
            xmpp:make_error(IQ, xmpp:err_bad_request(Txt, Lang));
        Data when Type == set ->
            case set_data(From, Data) of
@@ -145,14 +146,14 @@ process_sm_iq(#iq{type = Type, lang = Lang,
                {error, #stanza_error{} = Err} ->
                    xmpp:make_error(IQ, Err);
                {error, _} ->
-                   Txt = <<"Database failure">>,
+                   Txt = ?T("Database failure"),
                    Err = xmpp:err_internal_server_error(Txt, Lang),
                    xmpp:make_error(IQ, Err)
            end;
        Data when Type == get ->
            case get_data(LUser, LServer, Data) of
                {error, _} ->
-                   Txt = <<"Database failure">>,
+                   Txt = ?T("Database failure"),
                    Err = xmpp:err_internal_server_error(Txt, Lang),
                    xmpp:make_error(IQ, Err);
                Els ->
@@ -160,7 +161,7 @@ process_sm_iq(#iq{type = Type, lang = Lang,
            end
     end;
 process_sm_iq(#iq{lang = Lang} = IQ) ->
-    Txt = <<"Query to another users is forbidden">>,
+    Txt = ?T("Query to another users is forbidden"),
     xmpp:make_error(IQ, xmpp:err_forbidden(Txt, Lang)).
 
 -spec filter_xmlels([xmlel()]) -> [{binary(), xmlel()}].
index ae1d4ab258928fd6f6d666c4137c9b3ee44d7cfa..f511aad7fbeefceb86baeb6805a1dd3c248c5f09 100644 (file)
@@ -41,6 +41,7 @@
 
 -include("logger.hrl").
 -include("xmpp.hrl").
+-include("translate.hrl").
 
 -record(state, {server_host = <<"">> :: binary(),
                permissions = dict:new() :: dict:dict()}).
@@ -104,7 +105,7 @@ process_message(#message{from = #jid{luser = <<"">>, lresource = <<"">>} = From,
                outgoing ->
                    forward_message(Msg);
                _ ->
-                   Txt = <<"Insufficient privilege">>,
+                   Txt = ?T("Insufficient privilege"),
                    Err = xmpp:err_forbidden(Txt, Lang),
                    ejabberd_router:route_error(Msg, Err)
            end,
@@ -291,12 +292,12 @@ forward_message(#message{to = To} = Msg) ->
                            ejabberd_router:route(NewMsg);
                        _ ->
                            Lang = xmpp:get_lang(Msg),
-                           Txt = <<"Invalid 'from' attribute in forwarded message">>,
+                           Txt = ?T("Invalid 'from' attribute in forwarded message"),
                            Err = xmpp:err_forbidden(Txt, Lang),
                            ejabberd_router:route_error(Msg, Err)
                    end;
                _ ->
-                   Txt = <<"Message not found in forwarded payload">>,
+                   Txt = ?T("Message not found in forwarded payload"),
                    Err = xmpp:err_bad_request(Txt, Lang),
                    ejabberd_router:route_error(Msg, Err)
            catch _:{xmpp_codec, Why} ->
@@ -305,7 +306,7 @@ forward_message(#message{to = To} = Msg) ->
                    ejabberd_router:route_error(Msg, Err)
            end;
        _ ->
-           Txt = <<"No <forwarded/> element found">>,
+           Txt = ?T("No <forwarded/> element found"),
            Err = xmpp:err_bad_request(Txt, Lang),
            ejabberd_router:route_error(Msg, Err)
     catch _:{xmpp_codec, Why} ->
index 35205fe38e53446df1b4ffbef417e558d09675dc..7274bbdf9a80ea8e5da61f849752ada0d34c8fb5 100644 (file)
@@ -128,7 +128,7 @@ delete_listener(Host) ->
 %%%------------------------
 -spec process_disco_info(iq()) -> iq().
 process_disco_info(#iq{type = set, lang = Lang} = IQ) ->
-    Txt = <<"Value 'set' of 'type' attribute is not allowed">>,
+    Txt = ?T("Value 'set' of 'type' attribute is not allowed"),
     xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang));
 process_disco_info(#iq{type = get, to = To, lang = Lang} = IQ) ->
     Host = ejabberd_router:host_of_route(To#jid.lserver),
@@ -145,14 +145,14 @@ process_disco_info(#iq{type = get, to = To, lang = Lang} = IQ) ->
 
 -spec process_disco_items(iq()) -> iq().
 process_disco_items(#iq{type = set, lang = Lang} = IQ) ->
-    Txt = <<"Value 'set' of 'type' attribute is not allowed">>,
+    Txt = ?T("Value 'set' of 'type' attribute is not allowed"),
     xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang));
 process_disco_items(#iq{type = get} = IQ) ->
     xmpp:make_iq_result(IQ, #disco_items{}).
 
 -spec process_vcard(iq()) -> iq().
 process_vcard(#iq{type = set, lang = Lang} = IQ) ->
-    Txt = <<"Value 'set' of 'type' attribute is not allowed">>,
+    Txt = ?T("Value 'set' of 'type' attribute is not allowed"),
     xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang));
 process_vcard(#iq{type = get, lang = Lang} = IQ) ->
     xmpp:make_iq_result(
@@ -170,7 +170,7 @@ process_bytestreams(#iq{type = get, from = JID, to = To, lang = Lang} = IQ) ->
            StreamHost = get_streamhost(Host, ServerHost),
            xmpp:make_iq_result(IQ, #bytestreams{hosts = [StreamHost]});
        deny ->
-           xmpp:make_error(IQ, xmpp:err_forbidden(<<"Access denied by service policy">>, Lang))
+           xmpp:make_error(IQ, xmpp:err_forbidden(?T("Access denied by service policy"), Lang))
     end;
 process_bytestreams(#iq{type = set, lang = Lang,
                        sub_els = [#bytestreams{sid = SID}]} = IQ)
@@ -202,24 +202,24 @@ process_bytestreams(#iq{type = set, lang = Lang, from = InitiatorJID, to = To,
                      {InitiatorPid, InitiatorJID}, {TargetPid, TargetJID}),
                    xmpp:make_iq_result(IQ);
                {error, notfound} ->
-                   Txt = <<"Failed to activate bytestream">>,
+                   Txt = ?T("Failed to activate bytestream"),
                    xmpp:make_error(IQ, xmpp:err_item_not_found(Txt, Lang));
                {error, {limit, InitiatorPid, TargetPid}} ->
                    mod_proxy65_stream:stop(InitiatorPid),
                    mod_proxy65_stream:stop(TargetPid),
-                   Txt = <<"Too many active bytestreams">>,
+                   Txt = ?T("Too many active bytestreams"),
                    xmpp:make_error(IQ, xmpp:err_resource_constraint(Txt, Lang));
                {error, conflict} ->
-                   Txt = <<"Bytestream already activated">>,
+                   Txt = ?T("Bytestream already activated"),
                    xmpp:make_error(IQ, xmpp:err_conflict(Txt, Lang));
                {error, Err} ->
                    ?ERROR_MSG("failed to activate bytestream from ~s to ~s: ~p",
                               [Initiator, Target, Err]),
-                   Txt = <<"Database failure">>,
+                   Txt = ?T("Database failure"),
                    xmpp:make_error(IQ, xmpp:err_internal_server_error(Txt, Lang))
            end;
        deny ->
-           Txt = <<"Access denied by service policy">>,
+           Txt = ?T("Access denied by service policy"),
            xmpp:make_error(IQ, xmpp:err_forbidden(Txt, Lang))
     end.
 
index a3c7bf3560b0fbab486a83fb7f5f839199bcef71..d45f5961f9b082cae24665163d460433f2f146cc 100644 (file)
@@ -814,7 +814,7 @@ code_change(_OldVsn, State, _Extra) -> {ok, State}.
 %%--------------------------------------------------------------------
 -spec process_disco_info(iq()) -> iq().
 process_disco_info(#iq{type = set, lang = Lang} = IQ) ->
-    Txt = <<"Value 'set' of 'type' attribute is not allowed">>,
+    Txt = ?T("Value 'set' of 'type' attribute is not allowed"),
     xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang));
 process_disco_info(#iq{from = From, to = To, lang = Lang, type = get,
                       sub_els = [#disco_info{node = Node}]} = IQ) ->
@@ -833,7 +833,7 @@ process_disco_info(#iq{from = From, to = To, lang = Lang, type = get,
 
 -spec process_disco_items(iq()) -> iq().
 process_disco_items(#iq{type = set, lang = Lang} = IQ) ->
-    Txt = <<"Value 'set' of 'type' attribute is not allowed">>,
+    Txt = ?T("Value 'set' of 'type' attribute is not allowed"),
     xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang));
 process_disco_items(#iq{type = get, from = From, to = To,
                         sub_els = [#disco_items{node = Node} = SubEl]} = IQ) ->
@@ -871,7 +871,7 @@ process_pubsub_owner(#iq{to = To} = IQ) ->
 process_vcard(#iq{type = get, lang = Lang} = IQ) ->
     xmpp:make_iq_result(IQ, iq_get_vcard(Lang));
 process_vcard(#iq{type = set, lang = Lang} = IQ) ->
-    Txt = <<"Value 'set' of 'type' attribute is not allowed">>,
+    Txt = ?T("Value 'set' of 'type' attribute is not allowed"),
     xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang)).
 
 -spec process_commands(iq()) -> iq().
@@ -889,7 +889,7 @@ process_commands(#iq{type = set, to = To, from = From,
              IQ, xmpp_util:make_adhoc_response(Request, Response))
     end;
 process_commands(#iq{type = get, lang = Lang} = IQ) ->
-    Txt = <<"Value 'get' of 'type' attribute is not allowed">>,
+    Txt = ?T("Value 'get' of 'type' attribute is not allowed"),
     xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang)).
 
 -spec do_route(binary(), stanza()) -> ok.
@@ -1015,7 +1015,7 @@ iq_disco_items(Host, ?NS_COMMANDS, _From, _RSM) ->
     {result,
      #disco_items{items = [#disco_item{jid = jid:make(Host),
                                       node = ?NS_PUBSUB_GET_PENDING,
-                                      name = <<"Get Pending">>}]}};
+                                      name = ?T("Get Pending")}]}};
 iq_disco_items(_Host, ?NS_PUBSUB_GET_PENDING, _From, _RSM) ->
     {result, #disco_items{}};
 iq_disco_items(Host, Item, From, RSM) ->
@@ -1139,10 +1139,10 @@ iq_pubsub(Host, Access, #iq{from = From, type = IQType, lang = Lang,
                         #ps_options{xdata = XData, jid = undefined, node = <<>>} ->
                             decode_subscribe_options(XData, Lang);
                         #ps_options{xdata = _XData, jid = #jid{}} ->
-                            Txt = <<"Attribute 'jid' is not allowed here">>,
+                            Txt = ?T("Attribute 'jid' is not allowed here"),
                             {error, xmpp:err_bad_request(Txt, Lang)};
                         #ps_options{xdata = _XData} ->
-                            Txt = <<"Attribute 'node' is not allowed here">>,
+                            Txt = ?T("Attribute 'node' is not allowed here"),
                             {error, xmpp:err_bad_request(Txt, Lang)};
                         _ ->
                             []
@@ -1202,7 +1202,7 @@ iq_pubsub_owner(Host, #iq{type = IQType, from = From,
        {set, #pubsub_owner{configure = {Node, XData}, _ = undefined}} ->
            case XData of
                undefined ->
-                   {error, xmpp:err_bad_request(<<"No data form found">>, Lang)};
+                   {error, xmpp:err_bad_request(?T("No data form found"), Lang)};
                #xdata{type = cancel} ->
                    {result, #pubsub_owner{}};
                #xdata{type = submit} ->
@@ -1213,7 +1213,7 @@ iq_pubsub_owner(Host, #iq{type = IQType, from = From,
                            set_configure(Host, Node, From, Config, Lang)
                    end;
                #xdata{} ->
-                   {error, xmpp:err_bad_request(<<"Incorrect data form">>, Lang)}
+                   {error, xmpp:err_bad_request(?T("Incorrect data form"), Lang)}
            end;
        {get, #pubsub_owner{default = {Node, undefined}, _ = undefined}} ->
            get_default(Host, Node, From, Lang);
@@ -1321,7 +1321,7 @@ send_pending_auth_events(Host, Node, Owner, Lang) ->
                                node_call(Host, Type, get_node_subscriptions, [Nidx]);
                            _ ->
                                {error, xmpp:err_forbidden(
-                                         <<"Owner privileges required">>, Lang)}
+                                         ?T("Owner privileges required"), Lang)}
                        end;
                    false ->
                        {error, extended_error(xmpp:err_feature_not_implemented(),
@@ -1353,11 +1353,11 @@ send_authorization_request(#pubsub_node{nodeid = {Host, Node},
           Lang),
     X = #xdata{type = form,
               title = translate:translate(
-                        Lang, <<"PubSub subscriber request">>),
+                        Lang, ?T("PubSub subscriber request")),
               instructions = [translate:translate(
                                 Lang,
-                                <<"Choose whether to approve this entity's "
-                                  "subscription.">>)],
+                                ?T("Choose whether to approve this entity's "
+                                   "subscription."))],
               fields = Fs},
     Stanza = #message{from = service_jid(Host), sub_els = [X]},
     lists:foreach(
@@ -1412,7 +1412,7 @@ handle_authorization_response(Host, #message{from = From} = Packet, Response) ->
                        {result, Subs} = node_call(Host, Type, get_subscriptions, [Nidx, Subscriber]),
                        update_auth(Host, Node, Type, Nidx, Subscriber, Allow, Subs);
                    false ->
-                       {error, xmpp:err_forbidden(<<"Owner privileges required">>, Lang)}
+                       {error, xmpp:err_forbidden(?T("Owner privileges required"), Lang)}
                end
        end,
     case transaction(Host, Node, Action, sync_dirty) of
@@ -1444,7 +1444,7 @@ update_auth(Host, Node, Type, Nidx, Subscriber, Allow, Subs) ->
            send_authorization_approval(Host, Subscriber, Node, NewSub),
            {result, ok};
        _ ->
-           Txt = <<"No pending subscriptions found">>,
+           Txt = ?T("No pending subscriptions found"),
            {error, xmpp:err_unexpected_request(Txt, ejabberd_option:language())}
     end.
 
@@ -1524,7 +1524,7 @@ create_node(Host, ServerHost, Node, Owner, GivenType, Access, Configuration) ->
                                Error
                        end;
                    _ ->
-                       Txt = <<"You're not allowed to create nodes">>,
+                       Txt = ?T("You're not allowed to create nodes"),
                        {error, xmpp:err_forbidden(Txt, ejabberd_option:language())}
                end
        end,
@@ -1561,7 +1561,7 @@ create_node(Host, ServerHost, Node, Owner, GivenType, Access, Configuration) ->
 %%</ul>
 -spec delete_node(host(), binary(), jid()) -> {result, pubsub_owner()} | {error, stanza_error()}.
 delete_node(_Host, <<>>, _Owner) ->
-    {error, xmpp:err_not_allowed(<<"No node specified">>, ejabberd_option:language())};
+    {error, xmpp:err_not_allowed(?T("No node specified"), ejabberd_option:language())};
 delete_node(Host, Node, Owner) ->
     Action = fun (#pubsub_node{type = Type, id = Nidx}) ->
            case node_call(Host, Type, get_affiliation, [Nidx, Owner]) of
@@ -1573,7 +1573,7 @@ delete_node(Host, Node, Owner) ->
                        Error -> Error
                    end;
                _ ->
-                   {error, xmpp:err_forbidden(<<"Owner privileges required">>, ejabberd_option:language())}
+                   {error, xmpp:err_forbidden(?T("Owner privileges required"), ejabberd_option:language())}
            end
     end,
     Reply = undefined,
@@ -1865,7 +1865,7 @@ publish_item(Host, ServerHost, Node, Publisher, ItemId, Payload, PubOpts, Access
                            {error, xmpp:err_item_not_found()}
                    end;
                false ->
-                   Txt = <<"Automatic node creation is not enabled">>,
+                   Txt = ?T("Automatic node creation is not enabled"),
                    {error, xmpp:err_item_not_found(Txt, ejabberd_option:language())}
            end;
        Error ->
@@ -2147,7 +2147,7 @@ get_affiliations(Host, Node, JID) ->
                        {error, extended_error(xmpp:err_feature_not_implemented(),
                                               err_unsupported('modify-affiliations'))};
                   Affiliation /= owner ->
-                       {error, xmpp:err_forbidden(<<"Owner privileges required">>, ejabberd_option:language())};
+                       {error, xmpp:err_forbidden(?T("Owner privileges required"), ejabberd_option:language())};
                   true ->
                        node_call(Host, Type, get_node_affiliations, [Nidx])
                end
@@ -2213,7 +2213,7 @@ set_affiliations(Host, Node, From, Affs) ->
                        {result, undefined};
                    _ ->
                        {error, xmpp:err_forbidden(
-                                 <<"Owner privileges required">>, ejabberd_option:language())}
+                                 ?T("Owner privileges required"), ejabberd_option:language())}
                end
        end,
     case transaction(Host, Node, Action, sync_dirty) of
@@ -2410,7 +2410,7 @@ get_subscriptions(Host, Node, JID) ->
                    {error, extended_error(xmpp:err_feature_not_implemented(),
                                           err_unsupported('manage-subscriptions'))};
                Affiliation /= owner ->
-                   {error, xmpp:err_forbidden(<<"Owner privileges required">>, ejabberd_option:language())};
+                   {error, xmpp:err_forbidden(?T("Owner privileges required"), ejabberd_option:language())};
                true ->
                    node_call(Host, Type, get_node_subscriptions, [Nidx])
            end
@@ -2491,7 +2491,7 @@ set_subscriptions(Host, Node, From, Entities) ->
                        end;
                    _ ->
                        {error, xmpp:err_forbidden(
-                                 <<"Owner privileges required">>, ejabberd_option:language())}
+                                 ?T("Owner privileges required"), ejabberd_option:language())}
 
                end
        end,
@@ -3116,7 +3116,7 @@ get_configure(Host, ServerHost, Node, From, Lang) ->
                                configure =
                                    {Node, #xdata{type = form, fields = Fs}}}};
                _ ->
-                   {error, xmpp:err_forbidden(<<"Owner privileges required">>, Lang)}
+                   {error, xmpp:err_forbidden(?T("Owner privileges required"), Lang)}
            end
     end,
     case transaction(Host, Node, Action, sync_dirty) of
@@ -3275,7 +3275,7 @@ set_configure(Host, Node, From, Config, Lang) ->
                        end;
                    _ ->
                        {error, xmpp:err_forbidden(
-                                 <<"Owner privileges required">>, Lang)}
+                                 ?T("Owner privileges required"), Lang)}
                end
        end,
     case transaction(Host, Node, Action, transaction) of
@@ -3575,7 +3575,7 @@ tree_action(Host, Function, Args) ->
                    Result;
                {aborted, Reason} ->
                    ?ERROR_MSG("transaction return internal error: ~p~n", [{aborted, Reason}]),
-                   ErrTxt = <<"Database failure">>,
+                   ErrTxt = ?T("Database failure"),
                    {error, xmpp:err_internal_server_error(ErrTxt, ejabberd_option:language())}
            end;
        _ ->
@@ -3654,10 +3654,10 @@ do_transaction(ServerHost, Fun, Trans, DBType) ->
            {error, Error};
        {aborted, Reason} ->
            ?ERROR_MSG("transaction return internal error: ~p~n", [{aborted, Reason}]),
-           {error, xmpp:err_internal_server_error(<<"Database failure">>, ejabberd_option:language())};
+           {error, xmpp:err_internal_server_error(?T("Database failure"), ejabberd_option:language())};
        Other ->
            ?ERROR_MSG("transaction return internal error: ~p~n", [Other]),
-           {error, xmpp:err_internal_server_error(<<"Database failure">>, ejabberd_option:language())}
+           {error, xmpp:err_internal_server_error(?T("Database failure"), ejabberd_option:language())}
     end.
 
 %%%% helpers
index 8ba3d7e72a8cafcd4f457a03b96e4f6e10ff2ec5..db56a24b20d8579ec381e2d16c6046562d8b067f 100644 (file)
@@ -52,6 +52,7 @@
 -include("ejabberd_commands.hrl").
 -include("logger.hrl").
 -include("xmpp.hrl").
+-include("translate.hrl").
 
 -define(PUSH_CACHE, push_cache).
 
@@ -261,10 +262,10 @@ unregister_iq_handlers(Host) ->
 
 -spec process_iq(iq()) -> iq().
 process_iq(#iq{type = get, lang = Lang} = IQ) ->
-    Txt = <<"Value 'get' of 'type' attribute is not allowed">>,
+    Txt = ?T("Value 'get' of 'type' attribute is not allowed"),
     xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang));
 process_iq(#iq{lang = Lang, sub_els = [#push_enable{node = <<>>}]} = IQ) ->
-    Txt = <<"Enabling push without 'node' attribute is not supported">>,
+    Txt = ?T("Enabling push without 'node' attribute is not supported"),
     xmpp:make_error(IQ, xmpp:err_feature_not_implemented(Txt, Lang));
 process_iq(#iq{from = #jid{lserver = LServer} = JID,
               to = #jid{lserver = LServer},
@@ -276,10 +277,10 @@ process_iq(#iq{from = #jid{lserver = LServer} = JID,
        ok ->
            xmpp:make_iq_result(IQ);
        {error, db_failure} ->
-           Txt = <<"Database failure">>,
+           Txt = ?T("Database failure"),
            xmpp:make_error(IQ, xmpp:err_internal_server_error(Txt, Lang));
        {error, notfound} ->
-           Txt = <<"User session not found">>,
+           Txt = ?T("User session not found"),
            xmpp:make_error(IQ, xmpp:err_item_not_found(Txt, Lang))
     end;
 process_iq(#iq{from = #jid{lserver = LServer} = JID,
@@ -291,10 +292,10 @@ process_iq(#iq{from = #jid{lserver = LServer} = JID,
        ok ->
            xmpp:make_iq_result(IQ);
        {error, db_failure} ->
-           Txt = <<"Database failure">>,
+           Txt = ?T("Database failure"),
            xmpp:make_error(IQ, xmpp:err_internal_server_error(Txt, Lang));
        {error, notfound} ->
-           Txt = <<"Push record not found">>,
+           Txt = ?T("Push record not found"),
            xmpp:make_error(IQ, xmpp:err_item_not_found(Txt, Lang))
     end;
 process_iq(IQ) ->
index 9bbb02006c12a7b258e3c8aa9c94f73d19caa423..d5d8d35cb7d7534ba6b600f44ae3741fbd062050 100644 (file)
@@ -120,7 +120,7 @@ process_iq(#iq{from = From, to = To} = IQ, Source) ->
 process_iq(#iq{type = set, lang = Lang,
               sub_els = [#register{remove = true}]} = IQ,
           _Source, _IsCaptchaEnabled, _AllowRemove = false) ->
-    Txt = <<"Access denied by service policy">>,
+    Txt = ?T("Access denied by service policy"),
     xmpp:make_error(IQ, xmpp:err_forbidden(Txt, Lang));
 process_iq(#iq{type = set, lang = Lang, to = To, from = From,
               sub_els = [#register{remove = true,
@@ -138,7 +138,7 @@ process_iq(#iq{type = set, lang = Lang, to = To, from = From,
                            ejabberd_auth:remove_user(User, Server, Password),
                            xmpp:make_iq_result(IQ);
                       true ->
-                           Txt = <<"No 'password' found in this query">>,
+                           Txt = ?T("No 'password' found in this query"),
                            xmpp:make_error(IQ, xmpp:err_bad_request(Txt, Lang))
                    end
            end;
@@ -150,7 +150,7 @@ process_iq(#iq{type = set, lang = Lang, to = To, from = From,
                    ejabberd_auth:remove_user(LUser, Server),
                    ignore;
                _ ->
-                   Txt = <<"The query is only allowed from local users">>,
+                   Txt = ?T("The query is only allowed from local users"),
                    xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang))
            end
     end;
@@ -173,14 +173,14 @@ process_iq(#iq{type = set, to = To,
                    try_register_or_set_password(
                      User, Server, Password, IQ, Source, true);
                _ ->
-                   Txt = <<"Incorrect data form">>,
+                   Txt = ?T("Incorrect data form"),
                    xmpp:make_error(IQ, xmpp:err_bad_request(Txt, Lang))
            end;
        {error, malformed} ->
-           Txt = <<"Incorrect CAPTCHA submit">>,
+           Txt = ?T("Incorrect CAPTCHA submit"),
            xmpp:make_error(IQ, xmpp:err_bad_request(Txt, Lang));
        _ ->
-           ErrText = <<"The CAPTCHA verification has failed">>,
+           ErrText = ?T("The CAPTCHA verification has failed"),
            xmpp:make_error(IQ, xmpp:err_not_allowed(ErrText, Lang))
     end;
 process_iq(#iq{type = set} = IQ, _Source, _IsCaptchaEnabled, _AllowRemove) ->
@@ -201,25 +201,25 @@ process_iq(#iq{type = get, from = From, to = To, id = ID, lang = Lang} = IQ,
                {false, <<"">>}
        end,
     Instr = translate:translate(
-             Lang, <<"Choose a username and password to register "
-                     "with this server">>),
+             Lang, ?T("Choose a username and password to register "
+                      "with this server")),
     URL = mod_register_opt:redirect_url(Server),
     if (URL /= undefined) and not IsRegistered ->
-           Txt = translate:translate(Lang, <<"To register, visit ~s">>),
+           Txt = translate:translate(Lang, ?T("To register, visit ~s")),
            Desc = str:format(Txt, [URL]),
            xmpp:make_iq_result(
              IQ, #register{instructions = Desc,
                            sub_els = [#oob_x{url = URL}]});
        IsCaptchaEnabled and not IsRegistered ->
            TopInstr = translate:translate(
-                        Lang, <<"You need a client that supports x:data "
-                                "and CAPTCHA to register">>),
+                        Lang, ?T("You need a client that supports x:data "
+                                 "and CAPTCHA to register")),
            UField = #xdata_field{type = 'text-single',
-                                 label = translate:translate(Lang, <<"User">>),
+                                 label = translate:translate(Lang, ?T("User")),
                                  var = <<"username">>,
                                  required = true},
            PField = #xdata_field{type = 'text-private',
-                                 label = translate:translate(Lang, <<"Password">>),
+                                 label = translate:translate(Lang, ?T("Password")),
                                  var = <<"password">>,
                                  required = true},
            X = #xdata{type = form, instructions = [Instr],
@@ -230,11 +230,11 @@ process_iq(#iq{type = get, from = From, to = To, id = ID, lang = Lang} = IQ,
                      IQ, #register{instructions = TopInstr,
                                    sub_els = CaptchaEls});
                {error, limit} ->
-                   ErrText = <<"Too many CAPTCHA requests">>,
+                   ErrText = ?T("Too many CAPTCHA requests"),
                    xmpp:make_error(
                      IQ, xmpp:err_resource_constraint(ErrText, Lang));
                _Err ->
-                   ErrText = <<"Unable to generate a CAPTCHA">>,
+                   ErrText = ?T("Unable to generate a CAPTCHA"),
                    xmpp:make_error(
                      IQ, xmpp:err_internal_server_error(ErrText, Lang))
            end;
@@ -263,7 +263,7 @@ try_register_or_set_password(User, Server, Password,
                            xmpp:make_error(IQ, Error)
                    end;
                deny ->
-                   Txt = <<"Access denied by service policy">>,
+                   Txt = ?T("Access denied by service policy"),
                    xmpp:make_error(IQ, xmpp:err_forbidden(Txt, Lang))
            end;
        _ ->
index 689d1383d0e08f796ea0876c6b92c6120d31a6a5..88132ee9c1598e511b1cef59b1cb39972aa7cc1d 100644 (file)
@@ -65,6 +65,8 @@
 
 -include("ejabberd_web_admin.hrl").
 
+-include("translate.hrl").
+
 %%%----------------------------------------------------------------------
 %%% gen_mod callbacks
 %%%----------------------------------------------------------------------
@@ -107,13 +109,12 @@ process([<<"new">>],
       {success, ok, {Username, Host, _Password}} ->
          Jid = jid:make(Username, Host),
           mod_register:send_registration_notifications(?MODULE, Jid, Ip),
-         Text = (?T(<<"Your Jabber account was successfully "
-                      "created.">>)),
+         Text = translate:translate(Lang, ?T("Your Jabber account was successfully created.")),
          {200, [], Text};
       Error ->
          ErrorText =
-                list_to_binary([?T(<<"There was an error creating the account: ">>),
-                                ?T(get_error_text(Error))]),
+                list_to_binary([translate:translate(Lang, ?T("There was an error creating the account: ")),
+                                translate:translate(Lang, get_error_text(Error))]),
          {404, [], ErrorText}
     end;
 process([<<"delete">>],
@@ -121,13 +122,12 @@ process([<<"delete">>],
                 host = _HTTPHost}) ->
     case form_del_post(Q) of
       {atomic, ok} ->
-         Text = (?T(<<"Your Jabber account was successfully "
-                      "deleted.">>)),
+         Text = translate:translate(Lang, ?T("Your Jabber account was successfully deleted.")),
          {200, [], Text};
       Error ->
          ErrorText =
-                list_to_binary([?T(<<"There was an error deleting the account: ">>),
-                                ?T(get_error_text(Error))]),
+                list_to_binary([translate:translate(Lang, ?T("There was an error deleting the account: ")),
+                                translate:translate(Lang, get_error_text(Error))]),
          {404, [], ErrorText}
     end;
 %% TODO: Currently only the first vhost is usable. The web request record
@@ -137,13 +137,12 @@ process([<<"change_password">>],
                 host = _HTTPHost}) ->
     case form_changepass_post(Q) of
       {atomic, ok} ->
-         Text = (?T(<<"The password of your Jabber account "
-                      "was successfully changed.">>)),
+         Text = translate:translate(Lang, ?T("The password of your Jabber account was successfully changed.")),
          {200, [], Text};
       Error ->
          ErrorText =
-                list_to_binary([?T(<<"There was an error changing the password: ">>),
-                                ?T(get_error_text(Error))]),
+                list_to_binary([translate:translate(Lang, ?T("There was an error changing the password: ")),
+                                translate:translate(Lang, get_error_text(Error))]),
          {404, [], ErrorText}
     end;
 
@@ -195,7 +194,7 @@ meta() ->
 index_page(Lang) ->
     HeadEls = [meta(),
               ?XCT(<<"title">>,
-                   <<"Jabber Account Registration">>),
+                   ?T("Jabber Account Registration")),
               ?XA(<<"link">>,
                   [{<<"href">>, <<"/register/register.css">>},
                    {<<"type">>, <<"text/css">>},
@@ -203,15 +202,15 @@ index_page(Lang) ->
     Els = [?XACT(<<"h1">>,
                 [{<<"class">>, <<"title">>},
                  {<<"style">>, <<"text-align:center;">>}],
-                <<"Jabber Account Registration">>),
+                ?T("Jabber Account Registration")),
           ?XE(<<"ul">>,
               [?XE(<<"li">>,
-                   [?ACT(<<"new">>, <<"Register a Jabber account">>)]),
+                   [?ACT(<<"new">>, ?T("Register a Jabber account"))]),
                ?XE(<<"li">>,
-                   [?ACT(<<"change_password">>, <<"Change Password">>)]),
+                   [?ACT(<<"change_password">>, ?T("Change Password"))]),
                ?XE(<<"li">>,
                    [?ACT(<<"delete">>,
-                         <<"Unregister a Jabber account">>)])])],
+                         ?T("Unregister a Jabber account"))])])],
     {200,
      [{<<"Server">>, <<"ejabberd">>},
       {<<"Content-Type">>, <<"text/html">>}],
@@ -234,7 +233,7 @@ form_new_get(Host, Lang, IP) ->
 form_new_get2(Host, Lang, CaptchaEls) ->
     HeadEls = [meta(),
               ?XCT(<<"title">>,
-                   <<"Register a Jabber account">>),
+                   ?T("Register a Jabber account")),
               ?XA(<<"link">>,
                   [{<<"href">>, <<"/register/register.css">>},
                    {<<"type">>, <<"text/css">>},
@@ -242,64 +241,64 @@ form_new_get2(Host, Lang, CaptchaEls) ->
     Els = [?XACT(<<"h1">>,
                 [{<<"class">>, <<"title">>},
                  {<<"style">>, <<"text-align:center;">>}],
-                <<"Register a Jabber account">>),
+                ?T("Register a Jabber account")),
           ?XCT(<<"p">>,
-               <<"This page allows to create a Jabber "
-                 "account in this Jabber server. Your "
-                 "JID (Jabber IDentifier) will be of the "
-                 "form: username@server. Please read carefully "
-                 "the instructions to fill correctly the "
-                 "fields.">>),
+               ?T("This page allows to create a Jabber "
+                  "account in this Jabber server. Your "
+                  "JID (Jabber IDentifier) will be of the "
+                  "form: username@server. Please read carefully "
+                  "the instructions to fill correctly the "
+                  "fields.")),
           ?XAE(<<"form">>,
                [{<<"action">>, <<"">>}, {<<"method">>, <<"post">>}],
                [?XE(<<"ol">>,
                     ([?XE(<<"li">>,
-                          [?CT(<<"Username:">>), ?C(<<" ">>),
+                          [?CT(?T("Username:")), ?C(<<" ">>),
                            ?INPUTS(<<"text">>, <<"username">>, <<"">>,
                                    <<"20">>),
                            ?BR,
                            ?XE(<<"ul">>,
                                [?XCT(<<"li">>,
-                                     <<"This is case insensitive: macbeth is "
-                                       "the same that MacBeth and Macbeth.">>),
+                                     ?T("This is case insensitive: macbeth is "
+                                        "the same that MacBeth and Macbeth.")),
                                 ?XC(<<"li">>,
-                                    <<(?T(<<"Characters not allowed:">>))/binary,
+                                    <<(translate:translate(Lang, ?T("Characters not allowed:")))/binary,
                                       " \" & ' / : < > @ ">>)])]),
                       ?XE(<<"li">>,
-                          [?CT(<<"Server:">>), ?C(<<" ">>),
+                          [?CT(?T("Server:")), ?C(<<" ">>),
                            ?INPUTS(<<"text">>, <<"host">>, Host, <<"20">>)]),
                       ?XE(<<"li">>,
-                          [?CT(<<"Password:">>), ?C(<<" ">>),
+                          [?CT(?T("Password:")), ?C(<<" ">>),
                            ?INPUTS(<<"password">>, <<"password">>, <<"">>,
                                    <<"20">>),
                            ?BR,
                            ?XE(<<"ul">>,
                                [?XCT(<<"li">>,
-                                     <<"Don't tell your password to anybody, "
-                                       "not even the administrators of the Jabber "
-                                       "server.">>),
+                                     ?T("Don't tell your password to anybody, "
+                                        "not even the administrators of the Jabber "
+                                        "server.")),
                                 ?XCT(<<"li">>,
-                                     <<"You can later change your password using "
-                                       "a Jabber client.">>),
+                                     ?T("You can later change your password using "
+                                        "a Jabber client.")),
                                 ?XCT(<<"li">>,
-                                     <<"Some Jabber clients can store your password "
-                                       "in the computer, but you should do this only "
-                                       "in your personal computer for safety reasons.">>),
+                                     ?T("Some Jabber clients can store your password "
+                                        "in the computer, but you should do this only "
+                                        "in your personal computer for safety reasons.")),
                                 ?XCT(<<"li">>,
-                                     <<"Memorize your password, or write it "
-                                       "in a paper placed in a safe place. In "
-                                       "Jabber there isn't an automated way "
-                                       "to recover your password if you forget "
-                                       "it.">>)])]),
+                                     ?T("Memorize your password, or write it "
+                                        "in a paper placed in a safe place. In "
+                                        "Jabber there isn't an automated way "
+                                        "to recover your password if you forget "
+                                        "it."))])]),
                       ?XE(<<"li">>,
-                          [?CT(<<"Password Verification:">>), ?C(<<" ">>),
+                          [?CT(?T("Password Verification:")), ?C(<<" ">>),
                            ?INPUTS(<<"password">>, <<"password2">>, <<"">>,
                                    <<"20">>)])]
                        ++
                        CaptchaEls ++
                          [?XE(<<"li">>,
                               [?INPUTT(<<"submit">>, <<"register">>,
-                                       <<"Register">>)])]))])],
+                                       ?T("Register"))])]))])],
     {200,
      [{<<"Server">>, <<"ejabberd">>},
       {<<"Content-Type">>, <<"text/html">>}],
@@ -381,7 +380,7 @@ build_captcha_li_list2(Lang, IP) ->
 
 form_changepass_get(Host, Lang) ->
     HeadEls = [meta(),
-              ?XCT(<<"title">>, <<"Change Password">>),
+              ?XCT(<<"title">>, ?T("Change Password")),
               ?XA(<<"link">>,
                   [{<<"href">>, <<"/register/register.css">>},
                    {<<"type">>, <<"text/css">>},
@@ -389,32 +388,32 @@ form_changepass_get(Host, Lang) ->
     Els = [?XACT(<<"h1">>,
                 [{<<"class">>, <<"title">>},
                  {<<"style">>, <<"text-align:center;">>}],
-                <<"Change Password">>),
+                ?T("Change Password")),
           ?XAE(<<"form">>,
                [{<<"action">>, <<"">>}, {<<"method">>, <<"post">>}],
                [?XE(<<"ol">>,
                     [?XE(<<"li">>,
-                         [?CT(<<"Username:">>), ?C(<<" ">>),
+                         [?CT(?T("Username:")), ?C(<<" ">>),
                           ?INPUTS(<<"text">>, <<"username">>, <<"">>,
                                   <<"20">>)]),
                      ?XE(<<"li">>,
-                         [?CT(<<"Server:">>), ?C(<<" ">>),
+                         [?CT(?T("Server:")), ?C(<<" ">>),
                           ?INPUTS(<<"text">>, <<"host">>, Host, <<"20">>)]),
                      ?XE(<<"li">>,
-                         [?CT(<<"Old Password:">>), ?C(<<" ">>),
+                         [?CT(?T("Old Password:")), ?C(<<" ">>),
                           ?INPUTS(<<"password">>, <<"passwordold">>, <<"">>,
                                   <<"20">>)]),
                      ?XE(<<"li">>,
-                         [?CT(<<"New Password:">>), ?C(<<" ">>),
+                         [?CT(?T("New Password:")), ?C(<<" ">>),
                           ?INPUTS(<<"password">>, <<"password">>, <<"">>,
                                   <<"20">>)]),
                      ?XE(<<"li">>,
-                         [?CT(<<"Password Verification:">>), ?C(<<" ">>),
+                         [?CT(?T("Password Verification:")), ?C(<<" ">>),
                           ?INPUTS(<<"password">>, <<"password2">>, <<"">>,
                                   <<"20">>)]),
                      ?XE(<<"li">>,
                          [?INPUTT(<<"submit">>, <<"changepass">>,
-                                  <<"Change Password">>)])])])],
+                                  ?T("Change Password"))])])])],
     {200,
      [{<<"Server">>, <<"ejabberd">>},
       {<<"Content-Type">>, <<"text/html">>}],
@@ -489,7 +488,7 @@ check_password(Username, Host, Password) ->
 form_del_get(Host, Lang) ->
     HeadEls = [meta(),
               ?XCT(<<"title">>,
-                   <<"Unregister a Jabber account">>),
+                   ?T("Unregister a Jabber account")),
               ?XA(<<"link">>,
                   [{<<"href">>, <<"/register/register.css">>},
                    {<<"type">>, <<"text/css">>},
@@ -497,27 +496,27 @@ form_del_get(Host, Lang) ->
     Els = [?XACT(<<"h1">>,
                 [{<<"class">>, <<"title">>},
                  {<<"style">>, <<"text-align:center;">>}],
-                <<"Unregister a Jabber account">>),
+                ?T("Unregister a Jabber account")),
           ?XCT(<<"p">>,
-               <<"This page allows to unregister a Jabber "
-                 "account in this Jabber server.">>),
+               ?T("This page allows to unregister a Jabber "
+                  "account in this Jabber server.")),
           ?XAE(<<"form">>,
                [{<<"action">>, <<"">>}, {<<"method">>, <<"post">>}],
                [?XE(<<"ol">>,
                     [?XE(<<"li">>,
-                         [?CT(<<"Username:">>), ?C(<<" ">>),
+                         [?CT(?T("Username:")), ?C(<<" ">>),
                           ?INPUTS(<<"text">>, <<"username">>, <<"">>,
                                   <<"20">>)]),
                      ?XE(<<"li">>,
-                         [?CT(<<"Server:">>), ?C(<<" ">>),
+                         [?CT(?T("Server:")), ?C(<<" ">>),
                           ?INPUTS(<<"text">>, <<"host">>, Host, <<"20">>)]),
                      ?XE(<<"li">>,
-                         [?CT(<<"Password:">>), ?C(<<" ">>),
+                         [?CT(?T("Password:")), ?C(<<" ">>),
                           ?INPUTS(<<"password">>, <<"password">>, <<"">>,
                                   <<"20">>)]),
                      ?XE(<<"li">>,
                          [?INPUTT(<<"submit">>, <<"unregister">>,
-                                  <<"Unregister">>)])])])],
+                                  ?T("Unregister"))])])])],
     {200,
      [{<<"Server">>, <<"ejabberd">>},
       {<<"Content-Type">>, <<"text/html">>}],
@@ -591,25 +590,25 @@ unregister_account(Username, Host, Password) ->
 %%%----------------------------------------------------------------------
 
 get_error_text({error, captcha_non_valid}) ->
-    <<"The captcha you entered is wrong">>;
+    ?T("The captcha you entered is wrong");
 get_error_text({error, exists}) ->
-    <<"The account already exists">>;
+    ?T("The account already exists");
 get_error_text({error, password_incorrect}) ->
-    <<"Incorrect password">>;
+    ?T("Incorrect password");
 get_error_text({error, invalid_jid}) ->
-    <<"The username is not valid">>;
+    ?T("The username is not valid");
 get_error_text({error, not_allowed}) ->
-    <<"Not allowed">>;
+    ?T("Not allowed");
 get_error_text({error, account_doesnt_exist}) ->
-    <<"Account doesn't exist">>;
+    ?T("Account doesn't exist");
 get_error_text({error, account_exists}) ->
-    <<"The account was not deleted">>;
+    ?T("The account was not deleted");
 get_error_text({error, password_not_changed}) ->
-    <<"The password was not changed">>;
+    ?T("The password was not changed");
 get_error_text({error, passwords_not_identical}) ->
-    <<"The passwords are different">>;
+    ?T("The passwords are different");
 get_error_text({error, wrong_parameters}) ->
-    <<"Wrong parameters in the web formulary">>.
+    ?T("Wrong parameters in the web formulary").
 
 mod_options(_) ->
     [].
index eed03a0e6d7151b50125d972eee6b047841453b8..dd721db6ceffb90705c002a6d292d0604e20def8 100644 (file)
@@ -59,6 +59,7 @@
 -include("ejabberd_http.hrl").
 -include("ejabberd_web_admin.hrl").
 -include("ejabberd_stacktrace.hrl").
+-include("translate.hrl").
 
 -define(ROSTER_CACHE, roster_cache).
 -define(ROSTER_ITEM_CACHE, roster_item_cache).
@@ -151,7 +152,7 @@ process_iq(#iq{lang = Lang, to = To} = IQ) ->
     case ejabberd_hooks:run_fold(roster_remote_access,
                                 To#jid.lserver, false, [IQ]) of
        false ->
-           Txt = <<"Query to another users is forbidden">>,
+           Txt = ?T("Query to another users is forbidden"),
            xmpp:make_error(IQ, xmpp:err_forbidden(Txt, Lang));
        true ->
            process_local_iq(IQ)
@@ -161,21 +162,21 @@ process_local_iq(#iq{type = set,lang = Lang,
                     sub_els = [#roster_query{
                                   items = [#roster_item{ask = Ask}]}]} = IQ)
   when Ask /= undefined ->
-    Txt = <<"Possessing 'ask' attribute is not allowed by RFC6121">>,
+    Txt = ?T("Possessing 'ask' attribute is not allowed by RFC6121"),
     xmpp:make_error(IQ, xmpp:err_bad_request(Txt, Lang));
 process_local_iq(#iq{type = set, from = From, lang = Lang,
                     sub_els = [#roster_query{
                                   items = [#roster_item{} = Item]}]} = IQ) ->
     case has_duplicated_groups(Item#roster_item.groups) of
        true ->
-           Txt = <<"Duplicated groups are not allowed by RFC6121">>,
+           Txt = ?T("Duplicated groups are not allowed by RFC6121"),
            xmpp:make_error(IQ, xmpp:err_bad_request(Txt, Lang));
        false ->
            #jid{lserver = LServer} = From,
            Access = mod_roster_opt:access(LServer),
            case acl:match_rule(LServer, Access, From) of
                deny ->
-                   Txt = <<"Access denied by service policy">>,
+                   Txt = ?T("Access denied by service policy"),
                    xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang));
                allow ->
                    process_iq_set(IQ)
@@ -183,7 +184,7 @@ process_local_iq(#iq{type = set, from = From, lang = Lang,
     end;
 process_local_iq(#iq{type = set, lang = Lang,
                     sub_els = [#roster_query{items = [_|_]}]} = IQ) ->
-    Txt = <<"Multiple <item/> elements are not allowed by RFC6121">>,
+    Txt = ?T("Multiple <item/> elements are not allowed by RFC6121"),
     xmpp:make_error(IQ, xmpp:err_bad_request(Txt, Lang));
 process_local_iq(#iq{type = get, lang = Lang,
                     sub_els = [#roster_query{items = Items}]} = IQ) ->
@@ -191,11 +192,11 @@ process_local_iq(#iq{type = get, lang = Lang,
        [] ->
            process_iq_get(IQ);
        [_|_] ->
-           Txt = <<"The query must not contain <item/> elements">>,
+           Txt = ?T("The query must not contain <item/> elements"),
            xmpp:make_error(IQ, xmpp:err_bad_request(Txt, Lang))
     end;
 process_local_iq(#iq{lang = Lang} = IQ) ->
-    Txt = <<"No module is handling this query">>,
+    Txt = ?T("No module is handling this query"),
     xmpp:make_error(IQ, xmpp:err_service_unavailable(Txt, Lang)).
 
 roster_hash(Items) ->
@@ -322,7 +323,7 @@ process_iq_get(#iq{to = To, lang = Lang,
     catch ?EX_RULE(E, R, St) ->
            ?ERROR_MSG("failed to process roster get for ~s: ~p",
                       [jid:encode(To), {E, {R, ?EX_STACK(St)}}]),
-           Txt = <<"Roster module has failed">>,
+           Txt = ?T("Roster module has failed"),
            xmpp:make_error(IQ, xmpp:err_internal_server_error(Txt, Lang))
     end.
 
@@ -926,16 +927,16 @@ user_roster(User, Server, Query, Lang) ->
     Items = get_roster(LUser, LServer),
     SItems = lists:sort(Items),
     FItems = case SItems of
-              [] -> [?CT(<<"None">>)];
+              [] -> [?CT(?T("None"))];
               _ ->
                   [?XE(<<"table">>,
                        [?XE(<<"thead">>,
                             [?XE(<<"tr">>,
-                                 [?XCT(<<"td">>, <<"Jabber ID">>),
-                                  ?XCT(<<"td">>, <<"Nickname">>),
-                                  ?XCT(<<"td">>, <<"Subscription">>),
-                                  ?XCT(<<"td">>, <<"Pending">>),
-                                  ?XCT(<<"td">>, <<"Groups">>)])]),
+                                 [?XCT(<<"td">>, ?T("Jabber ID")),
+                                  ?XCT(<<"td">>, ?T("Nickname")),
+                                  ?XCT(<<"td">>, ?T("Subscription")),
+                                  ?XCT(<<"td">>, ?T("Pending")),
+                                  ?XCT(<<"td">>, ?T("Groups"))])]),
                         ?XE(<<"tbody">>,
                             (lists:map(fun (R) ->
                                                Groups = lists:flatmap(fun
@@ -973,7 +974,7 @@ user_roster(User, Server, Query, Lang) ->
                                                                 [?INPUTT(<<"submit">>,
                                                                          <<"validate",
                                                                            (ejabberd_web_admin:term_to_id(R#roster.jid))/binary>>,
-                                                                         <<"Validate">>)]);
+                                                                         ?T("Validate"))]);
                                                        true -> ?X(<<"td">>)
                                                     end,
                                                     ?XAE(<<"td">>,
@@ -982,16 +983,16 @@ user_roster(User, Server, Query, Lang) ->
                                                          [?INPUTT(<<"submit">>,
                                                                   <<"remove",
                                                                     (ejabberd_web_admin:term_to_id(R#roster.jid))/binary>>,
-                                                                  <<"Remove">>)])])
+                                                                  ?T("Remove"))])])
                                        end,
                                        SItems)))])]
             end,
     [?XC(<<"h1">>,
-        (<<(?T(<<"Roster of ">>))/binary, (us_to_list(US))/binary>>))]
+        (<<(translate:translate(Lang, ?T("Roster of ")))/binary, (us_to_list(US))/binary>>))]
       ++
       case Res of
-       ok -> [?XREST(<<"Submitted">>)];
-       error -> [?XREST(<<"Bad format">>)];
+       ok -> [?XREST(?T("Submitted"))];
+       error -> [?XREST(?T("Bad format"))];
        nothing -> []
       end
        ++
@@ -1001,7 +1002,7 @@ user_roster(User, Server, Query, Lang) ->
                 [?P, ?INPUT(<<"text">>, <<"newjid">>, <<"">>),
                  ?C(<<" ">>),
                  ?INPUTT(<<"submit">>, <<"addjid">>,
-                         <<"Add Jabber ID">>)]))].
+                         ?T("Add Jabber ID"))]))].
 
 build_contact_jid_td(RosterJID) ->
     ContactJID = jid:make(RosterJID),
@@ -1101,7 +1102,7 @@ us_to_list({User, Server}) ->
 
 webadmin_user(Acc, _User, _Server, Lang) ->
     Acc ++
-      [?XE(<<"h3">>, [?ACT(<<"roster/">>, <<"Roster">>)])].
+      [?XE(<<"h3">>, [?ACT(<<"roster/">>, ?T("Roster"))])].
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 has_duplicated_groups(Groups) ->
index e64a0a93588241f15a9f2cff9c7b37e7210db23e..1111d0e8d1d885106673ebd9e81b6dafcbd8ae73 100644 (file)
@@ -36,6 +36,7 @@
 
 -include("xmpp.hrl").
 -include("logger.hrl").
+-include("translate.hrl").
 
 %%%===================================================================
 %%% API
@@ -323,9 +324,9 @@ check_from_to(From, To) ->
 
 -spec mk_error(term(), binary()) -> stanza_error().
 mk_error(forbidden, Lang) ->
-    xmpp:err_forbidden(<<"Access denied by service policy">>, Lang);
+    xmpp:err_forbidden(?T("Access denied by service policy"), Lang);
 mk_error(host_unknown, Lang) ->
-    xmpp:err_not_allowed(<<"Host unknown">>, Lang);
+    xmpp:err_not_allowed(?T("Host unknown"), Lang);
 mk_error({codec_error, Why}, Lang) ->
     xmpp:err_bad_request(xmpp:io_format_error(Why), Lang);
 mk_error({_Class, _Reason} = Why, Lang) ->
index c3de2903b50dc1d32c0b8418c52e165c939d6caa..58d4eedc1dbba45c910864656e4c7f4ca96dae3f 100644 (file)
@@ -53,6 +53,8 @@
 
 -include("mod_shared_roster.hrl").
 
+-include("translate.hrl").
+
 -type group_options() :: [{atom(), any()}].
 -callback init(binary(), gen_mod:opts()) -> any().
 -callback import(binary(), binary(), [binary()]) -> ok.
@@ -727,7 +729,7 @@ unset_presence(LUser, LServer, Resource, Status) ->
 %%---------------------
 
 webadmin_menu(Acc, _Host, Lang) ->
-    [{<<"shared-roster">>, ?T(<<"Shared Roster Groups">>)}
+    [{<<"shared-roster">>, translate:translate(Lang, ?T("Shared Roster Groups"))}
      | Acc].
 
 webadmin_page(_, Host,
@@ -768,13 +770,13 @@ list_shared_roster_groups(Host, Query, Lang) ->
                                              <<"">>)]),
                                  ?XE(<<"td">>,
                                      [?INPUTT(<<"submit">>, <<"addnew">>,
-                                              <<"Add New">>)])])]))])),
-    (?H1GL((?T(<<"Shared Roster Groups">>)),
+                                              ?T("Add New"))])])]))])),
+    (?H1GL((translate:translate(Lang, ?T("Shared Roster Groups"))),
           <<"mod_shared_roster">>, <<"mod_shared_roster">>))
       ++
       case Res of
-       ok -> [?XREST(<<"Submitted">>)];
-       error -> [?XREST(<<"Bad format">>)];
+       ok -> [?XREST(?T("Submitted"))];
+       error -> [?XREST(?T("Bad format"))];
        nothing -> []
       end
        ++
@@ -782,7 +784,7 @@ list_shared_roster_groups(Host, Query, Lang) ->
              [{<<"action">>, <<"">>}, {<<"method">>, <<"post">>}],
              [FGroups, ?BR,
               ?INPUTT(<<"submit">>, <<"delete">>,
-                      <<"Delete Selected">>)])].
+                      ?T("Delete Selected"))])].
 
 list_sr_groups_parse_query(Host, Query) ->
     case lists:keysearch(<<"addnew">>, 1, Query) of
@@ -839,44 +841,44 @@ shared_roster_group(Host, Group, Query, Lang) ->
                   [{<<"class">>, <<"withtextareas">>}],
                   [?XE(<<"tbody">>,
                        [?XE(<<"tr">>,
-                            [?XCT(<<"td">>, <<"Name:">>),
+                            [?XCT(<<"td">>, ?T("Name:")),
                              ?XE(<<"td">>,
                                  [?INPUT(<<"text">>, <<"name">>, Name)])]),
                         ?XE(<<"tr">>,
-                            [?XCT(<<"td">>, <<"Description:">>),
+                            [?XCT(<<"td">>, ?T("Description:")),
                              ?XE(<<"td">>,
                                  [?TEXTAREA(<<"description">>,
                                             integer_to_binary(lists:max([3,
                                                                                DescNL])),
                                             <<"20">>, Description)])]),
                         ?XE(<<"tr">>,
-                            [?XCT(<<"td">>, <<"Members:">>),
+                            [?XCT(<<"td">>, ?T("Members:")),
                              ?XE(<<"td">>,
                                  [?TEXTAREA(<<"members">>,
                                             integer_to_binary(lists:max([3,
                                                                                length(Members)+3])),
                                             <<"20">>, FMembers)])]),
                         ?XE(<<"tr">>,
-                            [?XCT(<<"td">>, <<"Displayed Groups:">>),
+                            [?XCT(<<"td">>, ?T("Displayed Groups:")),
                              ?XE(<<"td">>,
                                  [?TEXTAREA(<<"dispgroups">>,
                                             integer_to_binary(lists:max([3,                                                                                            length(FDisplayedGroups)])),
                                             <<"20">>,
                                             list_to_binary(FDisplayedGroups))])])])])),
-    (?H1GL((?T(<<"Shared Roster Groups">>)),
+    (?H1GL((translate:translate(Lang, ?T("Shared Roster Groups"))),
           <<"mod_shared_roster">>, <<"mod_shared_roster">>))
       ++
-      [?XC(<<"h2">>, <<(?T(<<"Group ">>))/binary, Group/binary>>)] ++
+      [?XC(<<"h2">>, <<(translate:translate(Lang, ?T("Group ")))/binary, Group/binary>>)] ++
        case Res of
-         ok -> [?XREST(<<"Submitted">>)];
-         error -> [?XREST(<<"Bad format">>)];
+         ok -> [?XREST(?T("Submitted"))];
+         error -> [?XREST(?T("Bad format"))];
          nothing -> []
        end
          ++
          [?XAE(<<"form">>,
                [{<<"action">>, <<"">>}, {<<"method">>, <<"post">>}],
                [FGroup, ?BR,
-                ?INPUTT(<<"submit">>, <<"submit">>, <<"Submit">>)])].
+                ?INPUTT(<<"submit">>, <<"submit">>, ?T("Submit"))])].
 
 shared_roster_group_parse_query(Host, Group, Query) ->
     case lists:keysearch(<<"submit">>, 1, Query) of
index 3ca8e6da9be431a1bebc6870700afb886ed9d3d8..f8105f2cd5b9f00bbe847ae9d0e0a36d1031c48a 100644 (file)
 
 -include("logger.hrl").
 -include("xmpp.hrl").
+-include("translate.hrl").
 
 start(Host, _Opts) ->
     gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_SIC_0,
                                  ?MODULE, process_local_iq),
     gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_SIC_0,
-                                 ?MODULE, process_sm_iq),    
+                                 ?MODULE, process_sm_iq),
     gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_SIC_1,
                                  ?MODULE, process_local_iq),
     gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_SIC_1,
@@ -64,7 +65,7 @@ process_local_iq(#iq{from = #jid{user = User, server = Server,
                     type = get} = IQ) ->
     get_ip({User, Server, Resource}, IQ);
 process_local_iq(#iq{type = set, lang = Lang} = IQ) ->
-    Txt = <<"Value 'set' of 'type' attribute is not allowed">>,
+    Txt = ?T("Value 'set' of 'type' attribute is not allowed"),
     xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang)).
 
 process_sm_iq(#iq{from = #jid{user = User, server = Server,
@@ -73,10 +74,10 @@ process_sm_iq(#iq{from = #jid{user = User, server = Server,
                  type = get} = IQ) ->
     get_ip({User, Server, Resource}, IQ);
 process_sm_iq(#iq{type = get, lang = Lang} = IQ) ->
-    Txt = <<"Query to another users is forbidden">>,
+    Txt = ?T("Query to another users is forbidden"),
     xmpp:make_error(IQ, xmpp:err_forbidden(Txt, Lang));
 process_sm_iq(#iq{type = set, lang = Lang} = IQ) ->
-    Txt = <<"Value 'set' of 'type' attribute is not allowed">>,
+    Txt = ?T("Value 'set' of 'type' attribute is not allowed"),
     xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang)).
 
 get_ip({User, Server, Resource},
@@ -89,7 +90,7 @@ get_ip({User, Server, Resource},
                     end,
            xmpp:make_iq_result(IQ, Result);
        _ ->
-           Txt = <<"User session not found">>,
+           Txt = ?T("User session not found"),
            xmpp:make_error(IQ, xmpp:err_item_not_found(Txt, Lang))
     end.
 
index d3a70556400bf8ea5612a147c02863bc38f676c9..34d1d4c10fda325fa98ac74fd7319b4a6dccc6b0 100644 (file)
@@ -36,6 +36,7 @@
 
 -include("logger.hrl").
 -include("xmpp.hrl").
+-include("translate.hrl").
 
 start(Host, _Opts) ->
     gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_STATS,
@@ -51,7 +52,7 @@ depends(_Host, _Opts) ->
     [].
 
 process_iq(#iq{type = set, lang = Lang} = IQ) ->
-    Txt = <<"Value 'set' of 'type' attribute is not allowed">>,
+    Txt = ?T("Value 'set' of 'type' attribute is not allowed"),
     xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang));
 process_iq(#iq{type = get, to = To, lang = Lang,
               sub_els = [#stats{} = Stats]} = IQ) ->
@@ -89,7 +90,7 @@ get_local_stats(_Server, [<<"running nodes">>, ENode],
                Names, Lang) ->
     case search_running_node(ENode) of
       false ->
-           Txt = <<"No running node found">>,
+           Txt = ?T("No running node found"),
            {error, xmpp:err_item_not_found(Txt, Lang)};
       Node ->
          {result,
@@ -97,7 +98,7 @@ get_local_stats(_Server, [<<"running nodes">>, ENode],
                     Names)}
     end;
 get_local_stats(_Server, _, _, Lang) ->
-    Txt = <<"No statistics found for this item">>,
+    Txt = ?T("No statistics found for this item"),
     {error, xmpp:err_feature_not_implemented(Txt, Lang)}.
 
 -define(STATVAL(Val, Unit), #stat{name = Name, units = Unit, value = Val}).
index 15a735c85ffd1539868c141d05dbf29894b03580..fd18b9fa04106adc4c509186ef7bc4d1ae99f8b3 100644 (file)
@@ -39,6 +39,7 @@
 -include("xmpp.hrl").
 -include("logger.hrl").
 -include("p1_queue.hrl").
+-include("translate.hrl").
 
 -define(STREAM_MGMT_CACHE, stream_mgmt_cache).
 
@@ -131,7 +132,7 @@ c2s_unauthenticated_packet(#{lang := Lang} = State, Pkt) when ?is_sm_packet(Pkt)
     %% says: "Stream management errors SHOULD be considered recoverable", so we
     %% won't bail out.
     Err = #sm_failed{reason = 'not-authorized',
-                    text = xmpp:mk_text(<<"Unauthorized">>, Lang),
+                    text = xmpp:mk_text(?T("Unauthorized"), Lang),
                     xmlns = ?NS_STREAM_MGMT_3},
     {stop, send(State, Err)};
 c2s_unauthenticated_packet(State, _Pkt) ->
@@ -195,7 +196,7 @@ c2s_handle_send(#{mgmt_state := MgmtState, mod := Mod,
                        #{mgmt_max_queue := exceeded} = State2 ->
                            State3 = State2#{mgmt_resend => false},
                            Err = xmpp:serr_policy_violation(
-                                   <<"Too many unacked stanzas">>, Lang),
+                                   ?T("Too many unacked stanzas"), Lang),
                            send(State3, Err);
                        State2 when SendResult == ok ->
                            send_rack(State2);
@@ -224,7 +225,7 @@ c2s_handle_call(#{sid := {Time, _}, mod := Mod, mgmt_queue := Queue} = State,
     Mod:reply(From, {resume, State1}),
     {stop, State#{mgmt_state => resumed}};
 c2s_handle_call(#{mod := Mod} = State, {resume_session, _}, From) ->
-    Mod:reply(From, {error, <<"Previous session not found">>}),
+    Mod:reply(From, {error, ?T("Previous session not found")}),
     {stop, State};
 c2s_handle_call(State, _Call, _From) ->
     State.
@@ -240,7 +241,7 @@ c2s_handle_info(#{mgmt_state := pending, lang := Lang,
                {timeout, TRef, pending_timeout}) ->
     ?DEBUG("Timed out waiting for resumption of stream for ~s",
           [jid:encode(JID)]),
-    Txt = <<"Timed out waiting for stream resumption">>,
+    Txt = ?T("Timed out waiting for stream resumption"),
     Err = xmpp:serr_connection_timeout(Txt, Lang),
     Mod:stop(State#{mgmt_state => timeout,
                    stop_reason => {stream, {out, Err}}});
@@ -320,7 +321,7 @@ negotiate_stream_mgmt(Pkt, #{lang := Lang} = State) ->
        _ when is_record(Pkt, sm_a);
               is_record(Pkt, sm_r);
               is_record(Pkt, sm_resume) ->
-           Txt = <<"Stream management is not enabled">>,
+           Txt = ?T("Stream management is not enabled"),
            Err = #sm_failed{reason = 'unexpected-request',
                             text = xmpp:mk_text(Txt, Lang),
                             xmlns = Xmlns},
@@ -338,13 +339,13 @@ perform_stream_mgmt(Pkt, #{mgmt_xmlns := Xmlns, lang := Lang} = State) ->
                    handle_a(State, Pkt);
                _ when is_record(Pkt, sm_enable);
                       is_record(Pkt, sm_resume) ->
-                   Txt = <<"Stream management is already enabled">>,
+                   Txt = ?T("Stream management is already enabled"),
                    send(State, #sm_failed{reason = 'unexpected-request',
                                           text = xmpp:mk_text(Txt, Lang),
                                           xmlns = Xmlns})
            end;
        _ ->
-           Txt = <<"Unsupported version">>,
+           Txt = ?T("Unsupported version"),
            send(State, #sm_failed{reason = 'unexpected-request',
                                   text = xmpp:mk_text(Txt, Lang),
                                   xmlns = Xmlns})
@@ -448,7 +449,7 @@ check_h_attribute(#{mgmt_stanzas_out := NumStanzasOut, jid := JID,
                 [jid:encode(JID), H, NumStanzasOut]),
     State1 = State#{mgmt_resend => false},
     Err = xmpp:serr_undefined_condition(
-           <<"Client acknowledged more stanzas than sent by server">>, Lang),
+           ?T("Client acknowledged more stanzas than sent by server"), Lang),
     send(State1, Err);
 check_h_attribute(#{mgmt_stanzas_out := NumStanzasOut, jid := JID} = State, H) ->
     ?DEBUG("~s acknowledged ~B of ~B stanzas",
@@ -573,7 +574,7 @@ route_unacked_stanzas(#{mgmt_state := MgmtState,
       fun({_, _Time, #presence{from = From}}) ->
              ?DEBUG("Dropping presence stanza from ~s", [jid:encode(From)]);
         ({_, _Time, #iq{} = El}) ->
-             Txt = <<"User session terminated">>,
+             Txt = ?T("User session terminated"),
              ejabberd_router:route_error(
                El, xmpp:err_service_unavailable(Txt, Lang));
         ({_, _Time, #message{from = From, meta = #{carbon_copy := true}}}) ->
@@ -595,7 +596,7 @@ route_unacked_stanzas(#{mgmt_state := MgmtState,
                      NewEl = add_resent_delay_info(State, Msg, Time),
                      ejabberd_router:route(NewEl);
                  false ->
-                     Txt = <<"User session terminated">>,
+                     Txt = ?T("User session terminated"),
                      ejabberd_router:route_error(
                        Msg, xmpp:err_service_unavailable(Txt, Lang))
              end;
@@ -618,9 +619,9 @@ inherit_session_state(#{user := U, server := S,
                none ->
                    case pop_stanzas_in({U, S, R}, Time) of
                        error ->
-                           {error, <<"Previous session PID not found">>};
+                           {error, ?T("Previous session PID not found")};
                        {ok, H} ->
-                           {error, <<"Previous session timed out">>, H}
+                           {error, ?T("Previous session timed out"), H}
                    end;
                OldPID ->
                    OldSID = {Time, OldPID},
@@ -648,19 +649,19 @@ inherit_session_state(#{user := U, server := S,
                        {error, Msg} ->
                            {error, Msg}
                    catch exit:{noproc, _} ->
-                           {error, <<"Previous session PID is dead">>};
+                           {error, ?T("Previous session PID is dead")};
                          exit:{normal, _} ->
-                           {error, <<"Previous session PID has exited">>};
+                           {error, ?T("Previous session PID has exited")};
                          exit:{killed, _} ->
-                           {error, <<"Previous session PID has been killed">>};
+                           {error, ?T("Previous session PID has been killed")};
                          exit:{timeout, _} ->
                            ejabberd_sm:close_session(OldSID, U, S, R),
                            ejabberd_c2s:stop(OldPID),
-                           {error, <<"Session state copying timed out">>}
+                           {error, ?T("Session state copying timed out")}
                    end
            end;
        _ ->
-           {error, <<"Invalid 'previd' value">>}
+           {error, ?T("Invalid 'previd' value")}
     end.
 
 -spec resume_session({erlang:timestamp(), pid()}, state()) -> {resume, state()} |
index 1db3abe13c84f0eef2974206134a30fc47c763d9..1355ba46c074ba0d4f7a9368786987244e98277e 100644 (file)
@@ -1,7 +1,7 @@
 %%%----------------------------------------------------------------------
 %%% File    : mod_time.erl
 %%% Author  : Alexey Shchepin <alexey@process-one.net>
-%%% Purpose : 
+%%% Purpose :
 %%% Purpose :
 %%% Created : 18 Jan 2003 by Alexey Shchepin <alexey@process-one.net>
 %%%
@@ -36,8 +36,8 @@
         mod_options/1, depends/2]).
 
 -include("logger.hrl").
-
 -include("xmpp.hrl").
+-include("translate.hrl").
 
 start(Host, _Opts) ->
     gen_iq_handler:add_iq_handler(ejabberd_local, Host,
@@ -51,7 +51,7 @@ reload(_Host, _NewOpts, _OldOpts) ->
     ok.
 
 process_local_iq(#iq{type = set, lang = Lang} = IQ) ->
-    Txt = <<"Value 'set' of 'type' attribute is not allowed">>,
+    Txt = ?T("Value 'set' of 'type' attribute is not allowed"),
     xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang));
 process_local_iq(#iq{type = get} = IQ) ->
     Now = erlang:timestamp(),
index a050a372ed076fb7f1effdaa5fed67faac01f6b9..8c337528faf2512382e7bb58eb625f67ecfb48fc 100644 (file)
@@ -193,7 +193,7 @@ get_sm_features(Acc, _From, _To, Node, _Lang) ->
 
 -spec process_local_iq(iq()) -> iq().
 process_local_iq(#iq{type = set, lang = Lang} = IQ) ->
-    Txt = <<"Value 'set' of 'type' attribute is not allowed">>,
+    Txt = ?T("Value 'set' of 'type' attribute is not allowed"),
     xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang));
 process_local_iq(#iq{type = get, lang = Lang} = IQ) ->
     xmpp:make_iq_result(
@@ -213,14 +213,14 @@ process_sm_iq(#iq{type = set, lang = Lang, from = From} = IQ) ->
                _ -> xmpp:make_iq_result(IQ)
            end;
        false ->
-           Txt = <<"The query is only allowed from local users">>,
+           Txt = ?T("The query is only allowed from local users"),
            xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang))
     end;
 process_sm_iq(#iq{type = get, from = From, to = To, lang = Lang} = IQ) ->
     #jid{luser = LUser, lserver = LServer} = To,
     case get_vcard(LUser, LServer) of
        error ->
-           Txt = <<"Database failure">>,
+           Txt = ?T("Database failure"),
            xmpp:make_error(IQ, xmpp:err_internal_server_error(Txt, Lang));
        [] ->
            xmpp:make_iq_result(IQ, #vcard_temp{});
@@ -230,7 +230,7 @@ process_sm_iq(#iq{type = get, from = From, to = To, lang = Lang} = IQ) ->
 
 -spec process_vcard(iq()) -> iq().
 process_vcard(#iq{type = set, lang = Lang} = IQ) ->
-    Txt = <<"Value 'set' of 'type' attribute is not allowed">>,
+    Txt = ?T("Value 'set' of 'type' attribute is not allowed"),
     xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang));
 process_vcard(#iq{type = get, lang = Lang} = IQ) ->
     xmpp:make_iq_result(
@@ -249,7 +249,7 @@ process_search(#iq{type = set, to = To, lang = Lang,
     ResultXData = search_result(Lang, To, ServerHost, Fs),
     xmpp:make_iq_result(IQ, #search{xdata = ResultXData});
 process_search(#iq{type = set, lang = Lang} = IQ) ->
-    Txt = <<"Incorrect data form">>,
+    Txt = ?T("Incorrect data form"),
     xmpp:make_error(IQ, xmpp:err_bad_request(Txt, Lang)).
 
 -spec disco_items({error, stanza_error()} | {result, [disco_item()]} | empty,
@@ -258,7 +258,7 @@ process_search(#iq{type = set, lang = Lang} = IQ) ->
 disco_items(empty, _From, _To, <<"">>, _Lang) ->
     {result, []};
 disco_items(empty, _From, _To, _Node, Lang) ->
-    {error, xmpp:err_item_not_found(<<"No services available">>, Lang)};
+    {error, xmpp:err_item_not_found(?T("No services available"), Lang)};
 disco_items(Acc, _From, _To, _Node, _Lang) ->
     Acc.
 
@@ -275,7 +275,7 @@ disco_features(Acc, _From, _To, <<"">>, _Lang) ->
     {result, [?NS_DISCO_INFO, ?NS_DISCO_ITEMS,
              ?NS_VCARD, ?NS_SEARCH | Features]};
 disco_features(empty, _From, _To, _Node, Lang) ->
-    Txt = <<"No features available">>,
+    Txt = ?T("No features available"),
     {error, xmpp:err_item_not_found(Txt, Lang)};
 disco_features(Acc, _From, _To, _Node, _Lang) ->
     Acc.
@@ -380,7 +380,7 @@ vcard_iq_set(#iq{from = From, lang = Lang, sub_els = [VCard]} = IQ) ->
     case set_vcard(User, LServer, VCard) of
        {error, badarg} ->
            %% Should not be here?
-           Txt = <<"Nodeprep has failed">>,
+           Txt = ?T("Nodeprep has failed"),
            {stop, xmpp:err_internal_server_error(Txt, Lang)};
        ok ->
            IQ
@@ -422,7 +422,7 @@ mk_field(Var, Val) ->
 
 -spec mk_search_form(jid(), binary(), binary()) -> search().
 mk_search_form(JID, ServerHost, Lang) ->
-    Title = <<(translate:translate(Lang, <<"Search users in ">>))/binary,
+    Title = <<(translate:translate(Lang, ?T("Search users in ")))/binary,
              (jid:encode(JID))/binary>>,
     Mod = gen_mod:db_mod(ServerHost, ?MODULE),
     SearchFields = Mod:search_fields(ServerHost),
@@ -433,17 +433,17 @@ mk_search_form(JID, ServerHost, Lang) ->
               fields = Fs},
     #search{instructions =
                translate:translate(
-                 Lang, <<"You need an x:data capable client to search">>),
+                 Lang, ?T("You need an x:data capable client to search")),
            xdata = X}.
 
 make_instructions(Mod, Lang) ->
     Fill = translate:translate(
             Lang,
-            <<"Fill in the form to search for any matching "
-              "Jabber User">>),
+            ?T("Fill in the form to search for any matching "
+               "Jabber User")),
     Add = translate:translate(
            Lang,
-           <<" (Add * to the end of field to match substring)">>),
+           ?T(" (Add * to the end of field to match substring)")),
     case Mod of
        mod_vcard_mnesia -> Fill;
        _ -> str:concat(Fill, Add)
@@ -456,7 +456,7 @@ search_result(Lang, JID, ServerHost, XFields) ->
                   {Label, Var} <- Mod:search_reported(ServerHost)],
     #xdata{type = result,
           title = <<(translate:translate(Lang,
-                                         <<"Search Results for ">>))/binary,
+                                         ?T("Search Results for ")))/binary,
                     (jid:encode(JID))/binary>>,
           reported = Reported,
           items = lists:map(fun (Item) -> item_to_field(Item) end,
index 41e97e4963605950ef5303c32ca4d1cf1aab18e5..6def24951d56968a9dd279dea385bdd793dcac68 100644 (file)
@@ -35,8 +35,8 @@
         mod_opt_type/1, mod_options/1, depends/2]).
 
 -include("logger.hrl").
-
 -include("xmpp.hrl").
+-include("translate.hrl").
 
 start(Host, _Opts) ->
     gen_iq_handler:add_iq_handler(ejabberd_local, Host,
@@ -50,7 +50,7 @@ reload(_Host, _NewOpts, _OldOpts) ->
     ok.
 
 process_local_iq(#iq{type = set, lang = Lang} = IQ) ->
-    Txt = <<"Value 'set' of 'type' attribute is not allowed">>,
+    Txt = ?T("Value 'set' of 'type' attribute is not allowed"),
     xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang));
 process_local_iq(#iq{type = get, to = To} = IQ) ->
     Host = To#jid.lserver,
index 5f494a9c056aa244573493ffe3198fde077d0e9b..cc94b8b0a1b90073037325566d6a125491278b57 100644 (file)
@@ -37,6 +37,7 @@
 -include("pubsub.hrl").
 -include("xmpp.hrl").
 -include("ejabberd_sql_pt.hrl").
+-include("translate.hrl").
 
 -export([init/3, terminate/2, options/0, features/0,
     create_node_permission/6, create_node/2, delete_node/1,
@@ -766,7 +767,7 @@ get_item(Nidx, ItemId) ->
        {selected, []} ->
            {error, xmpp:err_item_not_found()};
        {'EXIT', _} ->
-           {error, xmpp:err_internal_server_error(<<"Database failure">>, ejabberd_option:language())}
+           {error, xmpp:err_internal_server_error(?T("Database failure"), ejabberd_option:language())}
     end.
 
 get_item(Nidx, ItemId, JID, AccessModel, PresenceSubscription, RosterGroup, _SubId) ->
index 3398f0900c4531451d187cf9e132066a0e650615..2be16fd7ea6f9650ee79795858f2c83be4e04157 100644 (file)
@@ -41,6 +41,7 @@
 
 -include("pubsub.hrl").
 -include("xmpp.hrl").
+-include("translate.hrl").
 
 -export([init/3, terminate/2, options/0, set_node/1,
     get_node/3, get_node/2, get_node/1, get_nodes/2,
@@ -71,13 +72,13 @@ get_node(Host, Node, _From) ->
 get_node(Host, Node) ->
     case mnesia:read({pubsub_node, {Host, Node}}) of
        [Record] when is_record(Record, pubsub_node) -> Record;
-       _ -> {error, xmpp:err_item_not_found(<<"Node not found">>, ejabberd_option:language())}
+       _ -> {error, xmpp:err_item_not_found(?T("Node not found"), ejabberd_option:language())}
     end.
 
 get_node(Nidx) ->
     case mnesia:index_read(pubsub_node, Nidx, #pubsub_node.id) of
        [Record] when is_record(Record, pubsub_node) -> Record;
-       _ -> {error, xmpp:err_item_not_found(<<"Node not found">>, ejabberd_option:language())}
+       _ -> {error, xmpp:err_item_not_found(?T("Node not found"), ejabberd_option:language())}
     end.
 
 get_nodes(Host, _From) ->
@@ -189,7 +190,7 @@ create_node(Host, Node, Type, Owner, Options, Parents) ->
                    {error, xmpp:err_forbidden()}
            end;
        _ ->
-           {error, xmpp:err_conflict(<<"Node already exists">>, ejabberd_option:language())}
+           {error, xmpp:err_conflict(?T("Node already exists"), ejabberd_option:language())}
     end.
 
 delete_node(Host, Node) ->
index 0a06645c3accdd2ad1b042193eecbf5a77925290..786f8b2625b24e49aec62ec3542b9746a0ca362a 100644 (file)
@@ -41,6 +41,7 @@
 -include("pubsub.hrl").
 -include("xmpp.hrl").
 -include("ejabberd_sql_pt.hrl").
+-include("translate.hrl").
 
 -export([init/3, terminate/2, options/0, set_node/1,
     get_node/3, get_node/2, get_node/1, get_nodes/2,
@@ -92,7 +93,7 @@ set_node(Record) when is_record(Record, pubsub_node) ->
     end,
     case Nidx of
        none ->
-           Txt = <<"Node index not found">>,
+           Txt = ?T("Node index not found"),
            {error, xmpp:err_internal_server_error(Txt, ejabberd_option:language())};
        _ ->
            lists:foreach(fun ({Key, Value}) ->
@@ -120,9 +121,9 @@ get_node(Host, Node) ->
        {selected, [RItem]} ->
            raw_to_node(Host, RItem);
        {'EXIT', _Reason} ->
-           {error, xmpp:err_internal_server_error(<<"Database failure">>, ejabberd_option:language())};
+           {error, xmpp:err_internal_server_error(?T("Database failure"), ejabberd_option:language())};
        _ ->
-           {error, xmpp:err_item_not_found(<<"Node not found">>, ejabberd_option:language())}
+           {error, xmpp:err_item_not_found(?T("Node not found"), ejabberd_option:language())}
     end.
 
 get_node(Nidx) ->
@@ -134,9 +135,9 @@ get_node(Nidx) ->
        {selected, [{Host, Node, Parent, Type}]} ->
            raw_to_node(Host, {Node, Parent, Type, Nidx});
        {'EXIT', _Reason} ->
-           {error, xmpp:err_internal_server_error(<<"Database failure">>, ejabberd_option:language())};
+           {error, xmpp:err_internal_server_error(?T("Database failure"), ejabberd_option:language())};
        _ ->
-           {error, xmpp:err_item_not_found(<<"Node not found">>, ejabberd_option:language())}
+           {error, xmpp:err_item_not_found(?T("Node not found"), ejabberd_option:language())}
     end.
 
 get_nodes(Host, _From) ->
@@ -258,9 +259,9 @@ create_node(Host, Node, Type, Owner, Options, Parents) ->
                    {error, xmpp:err_forbidden()}
            end;
        {result, _} ->
-           {error, xmpp:err_conflict(<<"Node already exists">>, ejabberd_option:language())};
+           {error, xmpp:err_conflict(?T("Node already exists"), ejabberd_option:language())};
        {error, db_fail} ->
-           {error, xmpp:err_internal_server_error(<<"Database failure">>, ejabberd_option:language())}
+           {error, xmpp:err_internal_server_error(?T("Database failure"), ejabberd_option:language())}
     end.
 
 delete_node(Host, Node) ->
index 66664a8aea8fb5c9c97204011880bffa0be7e9e0..32a79aef5a597c42eff301b53566dc3f7dedf084 100644 (file)
@@ -38,8 +38,8 @@
     read_subscription/3, write_subscription/4]).
 
 -include("pubsub.hrl").
-
 -include("xmpp.hrl").
+-include("translate.hrl").
 
 -define(PUBSUB_DELIVER, <<"pubsub#deliver">>).
 -define(PUBSUB_DIGEST, <<"pubsub#digest">>).
@@ -206,13 +206,13 @@ val_xfield(digest_frequency = Opt, [Val]) ->
     case catch binary_to_integer(Val) of
        N when is_integer(N) -> N;
        _ ->
-           Txt = {<<"Value of '~s' should be integer">>, [Opt]},
+           Txt = {?T("Value of '~s' should be integer"), [Opt]},
            {error, xmpp:err_not_acceptable(Txt, ejabberd_option:language())}
     end;
 val_xfield(expire = Opt, [Val]) ->
     try xmpp_util:decode_timestamp(Val)
     catch _:{bad_timestamp, _} ->
-           Txt = {<<"Value of '~s' should be datetime string">>, [Opt]},
+           Txt = {?T("Value of '~s' should be datetime string"), [Opt]},
            {error, xmpp:err_not_acceptable(Txt, ejabberd_option:language())}
     end;
 val_xfield(include_body = Opt, [Val]) -> xopt_to_bool(Opt, Val);
@@ -224,7 +224,7 @@ val_xfield(subscription_depth = Opt, [Depth]) ->
     case catch binary_to_integer(Depth) of
        N when is_integer(N) -> N;
        _ ->
-           Txt = {<<"Value of '~s' should be integer">>, [Opt]},
+           Txt = {?T("Value of '~s' should be integer"), [Opt]},
            {error, xmpp:err_not_acceptable(Txt, ejabberd_option:language())}
     end.
 
@@ -234,7 +234,7 @@ xopt_to_bool(_, <<"1">>) -> true;
 xopt_to_bool(_, <<"false">>) -> false;
 xopt_to_bool(_, <<"true">>) -> true;
 xopt_to_bool(Option, _) ->
-    Txt = {<<"Value of '~s' should be boolean">>, [Option]},
+    Txt = {?T("Value of '~s' should be boolean"), [Option]},
     {error, xmpp:err_not_acceptable(Txt, ejabberd_option:language())}.
 
 %% Return a field for an XForm for Key, with data filled in, if
index f960d0382c5a3f6d96c975f2b459b78f64d94800..af31008be7ab1c83a6db1a86f45a233ea2efbe28 100644 (file)
@@ -34,8 +34,8 @@
     get_options_xform/2, parse_options_xform/1]).
 
 -include("pubsub.hrl").
-
 -include("xmpp.hrl").
+-include("translate.hrl").
 
 -define(PUBSUB_DELIVER, <<"pubsub#deliver">>).
 -define(PUBSUB_DIGEST, <<"pubsub#digest">>).
@@ -171,13 +171,13 @@ val_xfield(digest_frequency = Opt, [Val]) ->
     case catch binary_to_integer(Val) of
        N when is_integer(N) -> N;
        _ ->
-           Txt = {<<"Value of '~s' should be integer">>, [Opt]},
+           Txt = {?T("Value of '~s' should be integer"), [Opt]},
            {error, xmpp:err_not_acceptable(Txt, ejabberd_option:language())}
     end;
 val_xfield(expire = Opt, [Val]) ->
     try xmpp_util:decode_timestamp(Val)
     catch _:{bad_timestamp, _} ->
-           Txt = {<<"Value of '~s' should be datetime string">>, [Opt]},
+           Txt = {?T("Value of '~s' should be datetime string"), [Opt]},
            {error, xmpp:err_not_acceptable(Txt, ejabberd_option:language())}
     end;
 val_xfield(include_body = Opt, [Val]) -> xopt_to_bool(Opt, Val);
@@ -189,7 +189,7 @@ val_xfield(subscription_depth = Opt, [Depth]) ->
     case catch binary_to_integer(Depth) of
        N when is_integer(N) -> N;
        _ ->
-           Txt = {<<"Value of '~s' should be integer">>, [Opt]},
+           Txt = {?T("Value of '~s' should be integer"), [Opt]},
            {error, xmpp:err_not_acceptable(Txt, ejabberd_option:language())}
     end.
 
@@ -199,7 +199,7 @@ xopt_to_bool(_, <<"1">>) -> true;
 xopt_to_bool(_, <<"false">>) -> false;
 xopt_to_bool(_, <<"true">>) -> true;
 xopt_to_bool(Option, _) ->
-    Txt = {<<"Value of '~s' should be boolean">>, [Option]},
+    Txt = {?T("Value of '~s' should be boolean"), [Option]},
     {error, xmpp:err_not_acceptable(Txt, ejabberd_option:language())}.
 
 %% Return a field for an XForm for Key, with data filled in, if
index ef0ae60b426cf2227c1a0712f611c2e7645098c5..30bfa71dfb09d80bad34e1ac80549337b5a63b72 100755 (executable)
 #!/usr/bin/env escript
 %% -*- erlang -*-
-%%! -pa ebin
 
-main(Dirs) ->
-    Txts =
-       lists:foldl(
-         fun(Dir, Acc) ->
-                 EbinDir = filename:join(Dir, "ebin"),
-                 SrcDir = filename:join(Dir, "src"),
-                 filelib:fold_files(
-                   EbinDir, ".+\.beam\$", false,
-                   fun(BeamFile, Res) ->
-                           Mod = mod(BeamFile),
-                           ErlFile = filename:join(SrcDir, Mod ++ ".erl"),
-                           case get_forms(BeamFile, ErlFile) of
-                               {ok, BeamForms, ErlForms} ->
-                                   process_forms(BeamForms, Mod, application) ++
-                                       process_forms(ErlForms, Mod, macro) ++ Res;
-                               _Err ->
-                                   Res
-                           end
-                   end, Acc)
-         end, [], Dirs),
-    Dict = lists:foldl(
-            fun({B, Meta}, Acc) ->
-                    dict:update(
-                      binary_to_list(B),
-                      fun(OldMeta) ->
-                              lists:usort([Meta|OldMeta])
-                      end,
-                      [Meta], Acc)
-            end, dict:new(), Txts),
+main(Paths) ->
+    Dict = fold_erls(
+            fun(File, Tokens, Acc) ->
+                    File1 = filename:rootname(filename:basename(File)),
+                    extract_tr(File1, Tokens, Acc)
+            end, dict:new(), Paths),
     generate_pot(Dict).
 
-process_forms(Forms, Mod, Type) ->
-    Tree = erl_syntax:form_list(Forms),
-    erl_syntax_lib:fold_subtrees(
-      fun(Form, Acc) ->
-             case erl_syntax:type(Form) of
-                 function ->
-                     case map(Form, Mod, Type) of
-                         [] ->
-                             Acc;
-                         Vars ->
-                             Vars ++ Acc
-                     end;
-                 _ ->
-                     Acc
-             end
-      end, [], Tree).
-
-map(Tree, Mod, Type) ->
-    Vars = erl_syntax_lib:fold(
-            fun(Form, Acc) ->
-                    case erl_syntax:type(Form) of
-                        Type when Type == application ->
-                            analyze_app(Form, Mod) ++ Acc;
-                        Type when Type == macro ->
-                            analyze_macro(Form, Mod) ++ Acc;
-                        _ ->
-                            Acc
-                    end
-            end, [], Tree),
-    Bins = lists:flatmap(
-            fun({Var, Pos}) when is_atom(Var) ->
-                    Res = erl_syntax_lib:fold(
-                            fun(Form, Acc) ->
-                                    case process_match_expr(
-                                           Form, Var, Mod) of
-                                        {ok, Binary, NewPos} ->
-                                            [{Binary, NewPos}|Acc];
-                                        error ->
-                                            Acc
-                                    end
-                            end, [], Tree),
-                    case Res of
-                        [] ->
-                            log("~s:~p: unresolved variable: ~s~n",
-                                [Mod, Pos, Var]);
-                        _ ->
-                            ok
-                    end,
-                    Res;
-               ({Var, Pos}) when is_binary(Var) ->
-                    [{Var, Pos}]
-            end, lists:usort(Vars)),
-    [{B, {Mod, Pos}} || {B, Pos} <- Bins, B /= <<"">>].
-
-process_match_expr(Form, Var, Mod) ->
-    case erl_syntax:type(Form) of
-       match_expr ->
-           Pattern = erl_syntax:match_expr_pattern(Form),
-           Body = erl_syntax:match_expr_body(Form),
-           {V, Expr} =
-               case {erl_syntax:type(Pattern), erl_syntax:type(Body)} of
-                   {variable, _} ->
-                       {erl_syntax:variable_name(Pattern), Body};
-                   {_, variable} ->
-                       {erl_syntax:variable_name(Body), Pattern};
-                   _ ->
-                       {'', none}
-               end,
-           Text = maybe_extract_tuple(Expr),
-           if V == Var ->
-                   Pos = erl_syntax:get_pos(Text),
-                   try {ok, erl_syntax:concrete(Text), Pos}
-                   catch _:_ ->
-                           case catch erl_syntax_lib:analyze_application(Text) of
-                               {_M, {Fn, 1}} when Fn == format_error;
-                                                  Fn == io_format_error ->
-                                   error;
-                               _ ->
-                                   log("~s:~p: not a binary: ~s~n",
-                                       [Mod, Pos, erl_prettypr:format(Text)]),
-                                   {ok, <<>>, Pos}
-                           end
-                   end;
-              true ->
+extract_tr(File, [{'?', _}, {var, _, 'T'}, {'(', Line}|Tokens], Acc) ->
+    {String, Tokens1} = extract_string(Tokens, []),
+    extract_tr(File, Tokens1, dict:append(String, {File, Line}, Acc));
+extract_tr(File, [_|Tokens], Acc) ->
+    extract_tr(File, Tokens, Acc);
+extract_tr(_, [], Acc) ->
+    Acc.
+
+extract_string([{string, _, S}|Tokens], Acc) ->
+    extract_string(Tokens, [S|Acc]);
+extract_string(Tokens, Acc) ->
+    {lists:flatten(lists:reverse(Acc)), Tokens}.
+
+fold_erls(Fun, State, Paths) ->
+    Paths1 = fold_paths(Paths),
+    Total = length(Paths1),
+    {_, State1} =
+        lists:foldl(
+          fun(File, {I, Acc}) ->
+                  io:format(standard_error,
+                           "Progress: ~B% (~B/~B)\r",
+                            [round(I*100/Total), I, Total]),
+                 case tokens(File) of
+                     {ok, Tokens} ->
+                         {I+1, Fun(File, Tokens, Acc)};
+                     error ->
+                         {I+1, Acc}
+                 end
+          end, {0, State}, Paths1),
+    State1.
+
+fold_paths(Paths) ->
+    lists:flatmap(
+      fun(Path) ->
+              case filelib:is_dir(Path) of
+                  true ->
+                      lists:reverse(
+                       filelib:fold_files(
+                         Path, ".+\.erl\$", false,
+                         fun(File, Acc) ->
+                                 [File|Acc]
+                         end, []));
+                  false ->
+                      [Path]
+              end
+      end, Paths).
+
+tokens(File) ->
+    case file:read_file(File) of
+       {ok, Data} ->
+           case erl_scan:string(binary_to_list(Data)) of
+               {ok, Tokens, _} ->
+                   {ok, Tokens};
+               {error, {_, Module, Desc}, Line} ->
+                   err("~s:~n: Warning: scan error: ~s",
+                       [filename:basename(File), Line, Module:format_error(Desc)]),
                    error
            end;
-       _ ->
+       {error, Why} ->
+           err("Warning: failed to read file ~s: ~s",
+               [File, file:format_error(Why)]),
            error
     end.
 
-maybe_extract_tuple(none) ->
-    none;
-maybe_extract_tuple(Form) ->
-    try
-       tuple = erl_syntax:type(Form),
-       [Text, _] = erl_syntax:tuple_elements(Form),
-       Text
-    catch _:{badmatch, _} ->
-           Form
-    end.
-
-analyze_app(Form, Mod) ->
-    try
-       {M, {F, A}} = erl_syntax_lib:analyze_application(Form),
-       Args = erl_syntax:application_arguments(Form),
-       Txt = case {M, atom_to_list(F), A, Args} of
-                 {xmpp, "err_" ++ _, 2, [T|_]} -> T;
-                 {xmpp, "serr_" ++ _, 2, [T|_]} -> T;
-                 {xmpp, "mk_text", 2, [T|_]} -> T;
-                 {xmpp_tr, "tr", 2, [_,T|_]} -> T;
-                 {translate, "translate", 2, [_,T|_]} -> T
-             end,
-       Pos = erl_syntax:get_pos(Txt),
-       case erl_syntax:type(Txt) of
-           binary ->
-               try [{erl_syntax:concrete(Txt), Pos}]
-               catch _:_ ->
-                       Pos = erl_syntax:get_pos(Txt),
-                       log("~s:~p: not a binary: ~s~n",
-                           [Mod, Pos, erl_prettypr:format(Txt)]),
-                       []
-               end;
-           variable ->
-               [{erl_syntax:variable_name(Txt), Pos}];
-           application ->
-               Vars = sets:to_list(erl_syntax_lib:variables(Txt)),
-               case Vars of
-                   [Var] ->
-                       [{Var, Pos}];
-                   [_|_] ->
-                       log("Too many variables: ~p~n", [Vars]),
-                       [];
-                   [] ->
-                       []
-               end;
-           _ ->
-               []
-       end
-    catch _:{badmatch, _} ->
-           [];
-         _:{case_clause, _} ->
-           []
-    end.
-
-analyze_macro(Form, Mod) ->
-    try
-       Name = erl_syntax:macro_name(Form),
-       variable = erl_syntax:type(Name),
-       'T' = erl_syntax:variable_name(Name),
-       [Txt] = erl_syntax:macro_arguments(Form),
-       string = erl_syntax:type(Txt),
-       Pos = erl_syntax:get_pos(Txt),
-       try [{list_to_binary(erl_syntax:string_value(Txt)), Pos}]
-       catch _:_ ->
-               log("~s:~p: not a binary: ~s~n",
-                   [Mod, Pos, erl_prettypr:format(Txt)]),
-               []
-       end
-    catch _:{badmatch, _} ->
-           []
-    end.
-
 generate_pot(Dict) ->
     io:format("~s~n~n", [pot_header()]),
     lists:foreach(
@@ -242,65 +120,5 @@ pot_header() ->
        "\"Content-Transfer-Encoding: 8bit\\n\""],
       io_lib:nl()).
 
-mod(Path) ->
-    filename:rootname(filename:basename(Path)).
-
-log(Format, Args) ->
-    io:format(standard_error, Format, Args).
-
-get_forms(BeamFile, ErlFile) ->
-    try
-       {ok, BeamForms} = get_beam_forms(BeamFile),
-       {ok, ErlForms} = get_erl_forms(ErlFile),
-       {ok, BeamForms, ErlForms}
-    catch _:{badmatch, error} ->
-           error
-    end.
-
-get_beam_forms(File) ->
-    case beam_lib:chunks(File, [abstract_code]) of
-        {ok, {_, List}} ->
-            case lists:keyfind(abstract_code, 1, List) of
-                {abstract_code, {raw_abstract_v1, Abstr}} ->
-                    {ok, Abstr};
-                _Err ->
-                   log("failed to get abstract code from ~s~n", [File]),
-                    error
-            end;
-        Err ->
-           log("failed to read chunks from ~s: ~p~n", [File, Err]),
-            error
-    end.
-
-get_erl_forms(Path) ->
-    case file:open(Path, [read]) of
-        {ok, Fd} ->
-            parse(Path, Fd, 1, []);
-        {error, Why} ->
-           log("failed to read ~s: ~s~n", [Path, file:format_error(Why)]),
-            error
-    end.
-
-parse(Path, Fd, Line, Acc) ->
-    {ok, Pos} = file:position(Fd, cur),
-    case epp_dodger:parse_form(Fd, Line) of
-        {ok, Form, NewLine} ->
-           {ok, NewPos} = file:position(Fd, cur),
-           {ok, RawForm} = file:pread(Fd, Pos, NewPos - Pos),
-           file:position(Fd, {bof, NewPos}),
-           AnnForm = erl_syntax:set_ann(Form, RawForm),
-           parse(Path, Fd, NewLine, [AnnForm|Acc]);
-        {eof, _} ->
-           {ok, NewPos} = file:position(Fd, cur),
-           if NewPos > Pos ->
-                   {ok, RawForm} = file:pread(Fd, Pos, NewPos - Pos),
-                   Form = erl_syntax:text(""),
-                   AnnForm = erl_syntax:set_ann(Form, RawForm),
-                   {ok, lists:reverse([AnnForm|Acc])};
-              true ->
-                   {ok, lists:reverse(Acc)}
-           end;
-        Err ->
-           log("failed to parse ~s: ~p~n", [Path, Err]),
-           error
-    end.
+err(Format, Args) ->
+    io:format(standard_error, Format ++ io_lib:nl(), Args).