These are chat archives for synrc/n2o

26th
Jan 2016
Yuriy Al. Shirokov
@yashrk
Jan 26 2016 08:23 UTC

Дело, похоже, не в версии mad. Просто erlydtl:compile/3 возвращает то {ok, ИМЯ_МОДУЛЯ}, то просто ok. То есть последняя строчка mad_dtl:compile_erlydtl_files/1 должна выглядеть так:

 lists:any(fun({error,_}) -> true; ({ok, _Module}) -> false; (ok) -> false end,[Compile(F) || F <- Files]).

Пиздец, конечно. Главное, совершенно непонятно, от чего зависит тип возвращаемого значения.

Yuriy Al. Shirokov
@yashrk
Jan 26 2016 08:29 UTC
Блядь, или нет. Теперь и без ok работает. Я совсем перестал понимать, что происходит.
Такой вариант, конечно, будет работать с обеими версиями ErlyDTL, и с 0.8.0, и с 0.11.1
Yuriy Al. Shirokov
@yashrk
Jan 26 2016 09:09 UTC

Короче, я по шагам расписал, как воспроизвести НЁХ, это явно именно НЁХ, а чтобы понять, что происходит, мне пока не хватает знания потрохов N2O.
Зато стало чуть понятнее, что не так с определением собственных тегов. Если добавить к опциям ErlyDTL опцию report, то при компиляции шаблонов получаю:

apps/myapp/priv/templates/base.html: Warning: Failed to load library 'mytags' (mytags): nofile
apps/myapp/priv/templates/base.html: Warning: Unknown tag 'mytag'

Хотя десятью строчками выше сообщение

Compiling /apps/myapp/src/mytags.erl
Yuriy Al. Shirokov
@yashrk
Jan 26 2016 11:05 UTC

Всё, работают у меня собственные теги, разобрался. К mad получается такой патч:

--------------------------- src/compile/mad_dtl.erl ---------------------------
index 8bee911..b28febd 100644
@@ -39,6 +39,8 @@ compile_erlydtl_files(Opts) ->
     {{_, ModuleExt}, Opts3} = get_kv(module_ext, Opts2, ""),
     {{_, OutDir},        _} = get_kv(out_dir,    Opts3, ""),

+    true = code:add_pathz(OutDir),
+
     Files = filelib:fold_files(DocRoot, SourceExt, true,
                                fun(F, Acc) -> [F|Acc] end, []),

@@ -55,4 +57,4 @@ compile_erlydtl_files(Opts) ->
              true -> ok end
     end,

-    lists:any(fun({error,_}) -> true; (ok) -> false end,[Compile(F) || F <- Files]).
+    lists:any(fun({error,_}) -> true; ({ok, _Module}) -> false end,[Compile(F) || F <- Files]).

Если хочется, чтобы со старой версией ErlyDTL тоже работало, в лямбду внутри lists:any/2надо добавить перехват атома ok, без кортежа. Ещё можно подумать, всегда ли OutDir совпадает с путём, где лежат скомпилированные модули самого приложения.
Почему такие изменения? «Суть токова»ⓒ: во-первых, изменился формат возвращаемых значений у erlydtl:compile/3 (ну, это-то сразу понятно было); во-вторых, apps/myapp/ebin отсутствует в code path. Что логично, до попыток определять собственные теги модули самого проекта шаблонизатору были нахер не нужны.
Поведение mad при компиляции шаблонов по-прежнему остаётся для меня загадкой, но у меня всё работает, поэтому дальше разбираться не буду.

PR делай
Yuriy Al. Shirokov
@yashrk
Jan 26 2016 11:11 UTC
Ага, думаю вечером сделаю, надо просто убедиться в совместимости с ErlyDTL 0.8.0, а сейчас некогда.
Ram Kumar
@ramka001
Jan 26 2016 17:00 UTC

Hi, is there any way to validate an input text

#input {id=userName, type="text", class=["form-control"], name="username", placeholder="Username", autofocus=true }

using the wf:wire to check if the userName is already used ?

Namdak Tonpa
@5HT
Jan 26 2016 17:05 UTC
n2o has validators, but not yet documented
Ram Kumar
@ramka001
Jan 26 2016 17:08 UTC
ok cool.. i'm trying to use a sample by nitrogen
something like wf:wire(signupButton, userName, #validate { attach_to=userName, validators=[#is_required { text="Required." }]}),
Namdak Tonpa
@5HT
Jan 26 2016 17:09 UTC
we have compeltly different approach that nitrogen
Ram Kumar
@ramka001
Jan 26 2016 17:09 UTC
ok..
any example
we don't manually code forms
we use autogenerated forms with spawnproc/forms
Ram Kumar
@ramka001
Jan 26 2016 17:12 UTC
these two need to be added into the rebar.config
and this is list of types of fields used in forms engine
we have 500 forms in our business apps, so handcoding is a trap
nitrogen in validation area is total bullshit
Ram Kumar
@ramka001
Jan 26 2016 17:13 UTC
:)
Namdak Tonpa
@5HT
Jan 26 2016 17:14 UTC
actually not only in validation area :-)
in any aspect )
that's how n2o emerged )
Ram Kumar
@ramka001
Jan 26 2016 17:14 UTC
good work
Namdak Tonpa
@5HT
Jan 26 2016 17:17 UTC
we allow to write validators in JavaScript
Ram Kumar
@ramka001
Jan 26 2016 17:20 UTC
is there any specific OTP version that the spawnproc is dependent on?
or >18 is ok?
Namdak Tonpa
@5HT
Jan 26 2016 17:20 UTC
17+
Ram Kumar
@ramka001
Jan 26 2016 17:20 UTC
cool
Namdak Tonpa
@5HT
Jan 26 2016 17:20 UTC
synrc, spawnproc, voxoz
we have three organizations and 10+ repos
Ram Kumar
@ramka001
Jan 26 2016 17:21 UTC
k
Namdak Tonpa
@5HT
Jan 26 2016 17:21 UTC
    "money": function(e, min, max, msg) {
        var money = e.detail.replace(/ /g,"");
        if( !/^(0\.\d{1,2}|[1-9]{1}\d{0,}(\.\d{1,2}){0,1})$/.test(money) ) {
            showErrorMSG(e.target, msg);
            return false; }
        if(!this.min(e, min)) return false;
        if(max!='none' && parseFloat(money) > max){
            showErrorMSG(e.target, i18n("MaxAmount")+max+" "+i18n(currency));
            return false; }
        var parent = e.target.parentNode;
        if(parent.lastChild.tagName == "DIV" && parent.lastChild.className == "errorMSG") parent.removeChild(parent.lastChild);
        return true;
    },
here is example of JavaScript client validator for "money" field
i.e. unlike in Nitrogen we can validate without server handshake
Ram Kumar
@ramka001
Jan 26 2016 17:22 UTC
on - the - fly
Namdak Tonpa
@5HT
Jan 26 2016 17:22 UTC
    "date": function(e) {
        var min, max, val = /^{(\d{4}),(\d{2}),(\d{2})}$/.exec(e.detail);
        if(val == null) { showErrorMSG(e.target, i18n("WrongDate")); return false; }

        min = /^(\d{4})-(\d{2})-(\d{2})$/.exec(e.target.getAttribute("min"));
        max = /^(\d{4})-(\d{2})-(\d{2})$/.exec(e.target.getAttribute("max"));
        if(min==null || max==null) { showErrorMSG(e.target, i18n("RefreshPage")); return false; }

        val = parseInt(val[1]+val[2]+val[3]);
        min = parseInt(min[1]+min[2]+min[3]);
        max = parseInt(max[1]+max[2]+max[3]);
        if(val < min) { showErrorMSG(e.target, i18n("DateMin")); return false; }
        if(val > max) { showErrorMSG(e.target, i18n("DateMax")); return false; }
        if((e.target.parentNode).lastChild.tagName == "DIV" && (e.target.parentNode).lastChild.className == "errorMSG") (e.target.parentNode).removeChild((e.target.parentNode).lastChild);
        return true;
    },
this is for date
it is very custom
so your validator supposed to be little bit smaller
Ram Kumar
@ramka001
Jan 26 2016 17:23 UTC
does it get converted into ajax?
Namdak Tonpa
@5HT
Jan 26 2016 17:23 UTC
we don't use AJAX
we use WebSocket
Ram Kumar
@ramka001
Jan 26 2016 17:23 UTC
ok
then faster
Namdak Tonpa
@5HT
Jan 26 2016 17:24 UTC
NO AJAX, NO JSON NO XML, NO JQUERY, NO MULTIPART, NO MIME, NO XHR
Pure JavaScript Erlang and WebSocket native Erlang BERT protocol
Ram Kumar
@ramka001
Jan 26 2016 17:25 UTC
the file transfer video ... I watched it..
Namdak Tonpa
@5HT
Jan 26 2016 17:25 UTC
No Bullshit )
Ram Kumar
@ramka001
Jan 26 2016 17:25 UTC
high speed
super fast
Namdak Tonpa
@5HT
Jan 26 2016 17:25 UTC
amazing such wow
Ram Kumar
@ramka001
Jan 26 2016 17:26 UTC
you ever work with RTP
Namdak Tonpa
@5HT
Jan 26 2016 17:27 UTC
once I wrote VoIP client for BeOS
Ram Kumar
@ramka001
Jan 26 2016 17:28 UTC
BeOS.. very old
Blue Eyed
I'm starting to learn RTP
RTC also
Namdak Tonpa
@5HT
Jan 26 2016 17:31 UTC
WebRTC?
Ram Kumar
@ramka001
Jan 26 2016 17:31 UTC
yup
WebRTC
Namdak Tonpa
@5HT
Jan 26 2016 17:31 UTC
we have a idea to make WebRTC stream with built-in commercials for peer-to peer networks
Ram Kumar
@ramka001
Jan 26 2016 17:32 UTC
i'm planning to do something like that...
Namdak Tonpa
@5HT
Jan 26 2016 17:32 UTC
you may talk with @m-2k, @fycth
fxmy wang
@fxmy
Jan 26 2016 17:32 UTC
Just one concern, what if some user fucks up the js and bypass the validation in browser?
Namdak Tonpa
@5HT
Jan 26 2016 17:32 UTC
they are also interested in such n2o apps
Ram Kumar
@ramka001
Jan 26 2016 17:33 UTC
cool..
Namdak Tonpa
@5HT
Jan 26 2016 17:33 UTC
@fxmy thats why you need always two side validations
JavaScript for fast check without server handshake
and Server validation is mandatory
fxmy wang
@fxmy
Jan 26 2016 17:34 UTC
that makes sense :+1:
Namdak Tonpa
@5HT
Jan 26 2016 17:34 UTC
validation({date, MinDate, MaxDate, _Lang}) ->
  Min =  integer_to_binary(MinDate),
  Max =  integer_to_binary(MaxDate),
  #validation {
    name = date, msg = <<"Введено неверное значение!"/utf8>>,
    options = [ {regexp,"^{([0-9]{4}),([0-9]{1,2}),([0-9]{1,2})}$",<<"Введена некорректная дата!"/utf8>>},
                {checkDate, "", <<"Введена некорректная дата!"/utf8>>},
                {minMax,{MinDate,MaxDate},<<"Дата должна находиться в пределах "/utf8, Min/binary, " - ", Max/binary,"!">>} ] };
that is how server validators look like
fxmy wang
@fxmy
Jan 26 2016 17:36 UTC
coooooooooool
Ram Kumar
@ramka001
Jan 26 2016 17:39 UTC
For i18n is there much difference in the steps in n2o and java like using properties file or can this be handled using the sys.config file
Namdak Tonpa
@5HT
Jan 26 2016 17:40 UTC
this is bullshit
all you need is two files: en.erl and yourlang.erl
with something like that
-module(en).
-compile(export_all).
translate({Module1,Code1}) -> <<"message"/utf8>>;
translate({Module2,Code1}) -> <<"message"/utf8>>;
...
Ram Kumar
@ramka001
Jan 26 2016 17:42 UTC
dang... i'm starting to hate java
:smile:
Namdak Tonpa
@5HT
Jan 26 2016 17:42 UTC
and use it like Lang:translate({?MODULE,"CODE"})
no propfiles, no gettext, no anything
you could even use parse_transform or erlang code parser to build language editors
like .po files in gettext
Ram Kumar
@ramka001
Jan 26 2016 17:45 UTC
nice
tr(Text,#st{user=#user3{lang=?UNDEF}}) -> Text;
tr(Text,#st{user=#user3{lang=Lang}}) -> ?MODULE:Lang(Text);
tr(Text,_) -> Text.
tr(Text) -> tr(Text,erlang:get(state)).

list() -> [
    {<<"English"/utf8>>, ?UNDEF},
    {<<"Русский"/utf8>>, ru},
    {<<"Украинский"/utf8>>, ua}
].

ru(<<"Personal info">>) -> <<"Основное"/utf8>>;
Namdak Tonpa
@5HT
Jan 26 2016 18:02 UTC
do it yourself approach
что
Namdak Tonpa
@5HT
Jan 26 2016 18:03 UTC
у нас подход типа сделай сам себе систему переводов
правил нет
кому как удобно так пусть и делают
можете хоть gettex юхать если упоротые )
Andrii Sergiienko
@fycth
Jan 26 2016 21:08 UTC
@5HT какой путь адаптирования AVZ к новому KVS? ID можно как-то считать - а как юзеров выбирать теперь по email?
Namdak Tonpa
@5HT
Jan 26 2016 21:09 UTC
отдельную таблицу
Andrii Sergiienko
@fycth
Jan 26 2016 21:09 UTC
ок