Coder Social home page Coder Social logo

nitrogen / nitrogen_core Goto Github PK

View Code? Open in Web Editor NEW
71.0 12.0 68.0 6.59 MB

The core Nitrogen library.

Home Page: http://nitrogenproject.com

License: MIT License

Shell 0.11% Erlang 43.54% Emacs Lisp 0.06% JavaScript 54.95% CSS 0.86% Makefile 0.12% NASL 0.01% Perl 0.26% HTML 0.09%
erlang javascript webframework websocket

nitrogen_core's Introduction

nitrogen_core's People

Contributors

afrantisak avatar aliceblittercopper avatar allanstreib avatar bunnylushington avatar choptastic avatar codebykat avatar dmsnell avatar etxemag75 avatar fbrau avatar fooflare avatar hji avatar homeway avatar jadahl avatar jamespharaoh avatar joaohf avatar mattiash avatar mbbx6spp avatar miby00 avatar msvoboda-ra-rockwell-com avatar osbre avatar oskardrums avatar rkozmer avatar rustyio avatar sfinnie avatar stpanning avatar stuart-thackray avatar superbobry avatar tex avatar witeman avatar x0id avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

nitrogen_core's Issues

http_basic_auth_security_handler can't work together with nitrogen_rest

I use http basic auth for my project, and there are some rest handlers also.
Perhaps there is a bug in http_basic_auth_security_handler.
I solved it.

The old code in http_basic_auth_security_handler.erl is:

prompt_for_authentication(CallbackMod) ->
    wf:state(callback_mod, CallbackMod),
    wf_context:page_module(?MODULE).

And I add a line to modify entry_point:

prompt_for_authentication(CallbackMod) ->
    wf:state(callback_mod, CallbackMod),
    wf_context:entry_point(fun() -> main() end),
    wf_context:page_module(?MODULE).

Or:

prompt_for_authentication(CallbackMod) ->
    wf:state(callback_mod, CallbackMod),
    wf_context:entry_point(main),
    wf_context:page_module(?MODULE).

Because the handler for common page use main/0, http_basic_auth_security_handler use main/0 too.
And the type is atom to context, so it worked well for common page.
The code in wf_core.erl is:

run_entry_point(_Module, Fun) when is_function(Fun, 0) ->
    Fun();
run_entry_point(Module, Fun) when is_atom(Fun) ->
    Module:Fun().

Unfortunately, the entry point in rest handler returns a function, not the main atom, so the http_basic_auth_security_handler can't work together with nitrogen_rest. And it's the reason for the bug.

element_restful_form

Hi,

could we please emit the class tag in the element_restful form, as below.

wf_tags:emit_tag(form, WithName#restful_form.body, [
    wf_tags:html_name(WithName#restful_form.id,
                      WithName#restful_form.html_name),
    {class, WithName#restful_form.class},
    {action, WithName#restful_form.action},
    {method, WithName#restful_form.method},
    {enctype, WithName#restful_form.enctype}
]).

Additionally for the #password{} / element_password.erl could we add the field placeholder (like #input/element_input) , and emit is as below.

Placeholder = wf:html_encode(Record#password.placeholder, true),
Value = wf:html_encode(Record#password.text, Record#password.html_encode),
wf_tags:emit_tag(input, [
{id, Record#password.html_id},
{type, password},
{class, [password, Record#password.class]},
{style, Record#password.style},
{name, Record#password.html_name},
{placeholder, Placeholder},
{value, Value}
]).

Thanks.

Bug: Dynamically making elements using #update, with elements containing their own actions

This is merely a report for myself (or someone else who might feel up to fixing this one), but when dynamically creating elements using an attached #update action with the specified elements themselves containing wired actions. The wired actions will not work.

Example:

#button{id=button, text="Click me first", click=[
   #update{type=insert_after, target=button, elements=[
      #button{text="Click me next", click=#alert{text="You clicked the new button"}}
   ]}
]}.

In this, after clicking "Click me first", the "Click me next" button will be created, but clicking it will do nothing.

The problem is caused by the fact that in order to add the new elements, they need to be rendered by nitrogen, and in doing so, the attached actions get wired immediately. To fix this, the attached actions need to only be wired when the first button is clicked, with everything being enclosed in a closure.

element_checkbox

I can't really tell if this is an issue or not to be honest, but if I use checkbox in its current state the lines show up on different rows. (This could be my setup or CSS), but the for doesn't seem to be applying.

It currently emits as

      <input.....>
      <label...>

It works for me if it emits as

   <label ....>
       <input...>
   </label>

So if possible can we change the emit to the following?

   [
     wf_tags:emit_tag(label,
        % Checkbox...
        [wf_tags:emit_tag(input, [
            {name, Record#checkbox.html_name},
            {id,   Anchor},
            {type, checkbox},
            {class, [checkbox, Record#checkbox.class]},
            {style, Record#checkbox.style},
            {value, Record#checkbox.value},
            {CheckedOrNot, true},
            {data_fields, Record#checkbox.data_fields}
        ]),

        % Label for Checkbox...
         Text], [
            {for, Anchor}
        ])
    ].

Add Middleware handler

This would allow for doing some custom things with the state after the handlers have run, but before a page's main() function is executed.

Unicode encoding causing trouble with binary downloads.

The automatic unicode encoding applied after elements have been processed is proving to be troublesome for modules whose main function is expected to return straight-up binary data.

Perhaps the simple fix is to provide a flag in the context to "not encode" - something like:

wf_context:encoding() and wf_context:encoding(Encoding) where Encoding can be 'unicode' or 'none'.

Or perhaps reading the 'content-type' and determining if utf encoding should be applied dynamically.

Something to chew on for the next beta release.

New Feature: stream attribute

Add an attribute called "stream", which can be an alternative to body, and which then performs an insert_bottom for each time it's run.

For example:

#panel{stream_fun=fun my_stream/0}.

Where my_stream then is basically run in a comet loop and keeps executing an insert_bottom with the return value of my_stream, or if eof is returned, then end.

Seems like an interesting way of deferring loading some data which might take a while to retrieve from microservices.

google charts

Hi,

Sorry would make this a pull request but I am struggling to see why I can't.

Google charts doesn't work on https:// if you site is HTTPS. It gave me error on both firefox and chrome, I have tested the change pages are displaying but website does give warning that you are loading insecure content, but the page works.

So please can we change line 19 from
Path = "//chart.apis.google.com/chart?",
To
Path = "http://chart.apis.google.com/chart?",

Regards,
Stuart

Add a rest api behaviour

Add a restful API behaviour.

Basically, it should allow a page to simply specify

-behaviour(nitrogen_restful_api).

Which would then provide simple callbacks for get, post, delete, head, list, etc, each taking a single argument (the PathInfo). Post variables can still be retrieved as needed with wf:q and its siblings, but the PathInfo will, I think, be used so frequently that it makes sense not to require the user to request it each time.

Cant make a "delayed" render for a custom element

Hi. I have seen several web frameworks (css/js), -and I'm using one- that require
to declare some content out of the "structural" html. For example (real):

A dropdown:
`

... `

We dont want to mess with the nav structure neither is necessary to render them together
so for this very dropdown I have to declare the dropdown contents after the nav:

`

...
...
`

I'm not very proficient with nitrogen yet and I'm struggling to make this work.
At first I thought to initialize a comet handler when the page 'main' and
in the element's 'render_element()' to send the delayed content. That didn't
work because messages sent from 'render_element()' went to a non existent
apparently, for example, wf:send(delayed_contents, {push,Dropdown}), event thought a did a comet initialization in the page's main(). My idea was then to do a wf:send(draw_delayed_contents)
somewhere after page load, but that seems tricky, that content should be there before
the page 'onLoad' not after.

Now I'm thinking of storing that 'delayed' content in page state when preparing the render in
'render_element()'...

What could be a elegant way to make this happen -not that the pool concept is not- ?

Support for data_fields in #button{}

Good day to everyone,

Frameworks such as Twitter Bootstrap rely on the usage of data-* fields. #link{} supports them via the data_fields field. #button{}, however, does not, and it would be of great use for anyone who wants to integrate Twitter Bootstrap with Nitrogen.

Thank you very much in advance and congratulations for the excellent job you've done with Nitrogen.

Docs for datepicker_textbox missing

Can't believe I never noticed this, but there are no docs for datepicker_textbox. There is a demo on the main page, but no docs. Must be rectified.

Trouble wiring validators (or all events?) when TriggerID is a string

This is related to wf_render_actions:normalize_path, where if the id is a string, it won't prepend ."wfid_" to it for generating a class.

It should be smarter about prepending that, or further down the way, consider going the N2O route and go with simple HTML IDs for the element id. Due to the backwards incompatibility, this would need to be for Nitrogen 3 in order to be consistent with semver.

If going down that route, what would be the ramifications to the #bind{} element?

Also need to determine what will happen with respect to wf:q() and those string IDs. I suspect it won't be a problem and intstead it's just a problem with the wiring, but it needs to be considered.

emit style on #restful_form

Hi a small one.

The style field is not emitted on element_restful_form
Add to line: 39 please:

    {style, WithName#restful_form.style},

#inplace element could use some work

There is a bit of a disconnect in the nature of the #inplace element, especially if a #dropdown box is used. The inplace_event function must return the new value of to be used in the #dropdown, but it's also used as the text of the element. Similarly, the starting text gets used by the #inplace element.

More research must be done to make this easier to use.

custom validation

Hi,

I have been having a problem with the custom validators; it may not be something allowed or catered. I am bit lost where to look or what might be causing.

I have module lets say index.erl; that has a button and that button calls other module(s) to get the elements to output, which are added to the page via a wf:replace

The validators are then set via a comet otherwise I get "livevalidation.min.js:1 Uncaught Error: LiveValidation::initialize - No element reference or element id has been provided!"

there is a 1 second delay on the comet then the validators are wired and flush called.

The built in validators such as #is_required{} work as expected however the custom validators never seem to fire.

I have a sample of the files (index.erl & dynamic_elements_render.erl) in https://drive.google.com/file/d/0B0_ahQMa6SwjT0JYbnRudFhyUzQ/view

Actual #grid elements need to be documented and demoed

The #grid elements have no documentation or demos on the home page.

Susan Potter conveniently started a demo page for it in a now-closed pull request a while back at nitrogen/NitrogenProject.com#1 but it needs to be better fleshed out. Further, we need to add an actual documentation page for it.

It doesn't need to be elaborate, and it can probably do well enough heavily referencing this: http://net.tutsplus.com/tutorials/html-css-techniques/mastering-the-960-grid-system/

Which makes me think it's probably worth adding some more elements for different grid-like systems:

These are all things that can, and should be done with plugins, rather than baking them directly into the system.

Add Demo for new #textbox "type" attribute

Need a demo for the #textbox type attribute for HTML5 stuff.

Also, it might be worthwhile to convert datepicker_textbox to actually just be a #textbox with type date, and then rely on javascript for backwards compatibility.

Something to consider.

Crash handler error

Hi Jesse,

I don't know why, but sometimes I get this error, but not always:

=INFO REPORT==== 29-Oct-2014::19:01:01 ===
{error_in_crash_handler,error,
{badrecord,context},
[{wf_context,handlers,0,[{file,"src/lib/wf_context.erl"},{line,403}]},
{wf_handler,get_handler,1,[{file,"src/lib/wf_handler.erl"},{line,73}]},
{wf_handler,call_readonly,3,[{file,"src/lib/wf_handler.erl"},{line,46}]},
{wf_core,run_websocket_crash,3,[{file,"src/wf_core.erl"},{line,64}]},
{nitrogen,ws_message,3,[{file,"src/nitrogen.erl"},{line,63}]},
{simple_bridge_websocket,process_frames,6,
[{file,"src/simple_bridge_websocket.erl"},{line,311}]},
{simple_bridge_websocket,websocket_loop,8,
[{file,"src/simple_bridge_websocket.erl"},{line,158}]},
{simple_bridge_websocket,attempt_hijacking,2,
[{file,"src/simple_bridge_websocket.erl"},{line,64}]}]}

It happens when I restart Nitrogen after stopping the VM with > q(). and I get this other error:

=ERROR REPORT==== 29-Oct-2014::19:00:52 ===
Unhandled message to websocket process: {'EXIT',<0.101.0>,shutdown}

This is what I got in the inets.log file before the unhandled message:

[29/Oct/2014:19:00:48 +0100], module traverse failed: inets_simple_bridge_anchor:do =>
Error Type: exit
Error: normal
Stack trace: [{inets_simple_bridge_anchor,do,1,
[{file,
"src/inets_bridge_modules/inets_simple_bridge_anchor.erl"},
{line,16}]},
{httpd_response,traverse_modules,2,
[{file,"httpd_response.erl"},{line,72}]},
{httpd_response,generate_and_send_response,1,
[{file,"httpd_response.erl"},{line,40}]},
{httpd_request_handler,handle_response,1,
[{file,"httpd_request_handler.erl"},{line,527}]},
{gen_server,handle_msg,5,
[{file,"gen_server.erl"},{line,599}]},
{proc_lib,init_p_do_apply,3,
[{file,"proc_lib.erl"},{line,237}]}]

And finally, when I click in a link (or reload), before leaving the page, it appears the red message panel in the top of the browser, but without any message, it looks just like a red line. I suppose the websocket connection is broken, but I am not sure.

Thanks.

#datepicker_textbox

Hi,

Please could we add html_name to #datepicker_textbox

I believe just adding it to the record if I understand correctly would add the functionality due to the the fact that #textbox{} already has this field.

-record(datepicker_textbox, {?ELEMENT_BASE(element_datepicker_textbox),
text="" :: text(),
next :: id(),


html_name :: html_name(),


    html_encode=true        :: html_encode(),
    validators=[]           :: validators(),
    placeholder=""          :: text(),
    readonly=false          :: boolean(),
    disabled=false          :: boolean(),
    options = [{dateFormat, "yy-mm-dd"}]    :: proplist()
}).

Cant make comets work

Maybe its just me but

I'm doing the chat example in the tutorial... all fine, but then
I want to use a local pool instead of a global one... just testing

And at this point I dont' know whats wrong, I just replace
"comet_global" -> "comet"
and "send_global" -> "send"

I dont' know whats wrong because the messages dont get updated
in the page

Add trap_tabs attribute to textarea

A useful option, which could be added as a relatively simple javascript to Nitrogen.js is the addition of a trap_tabs attribute to textareas to allow users to type tabs into textareas without the tab key triggering a focus change.

(note to self)

wf:q(UnicodeString) and wf:to_binary(UnicodeString) can't work

I find the wf:to_binary/1 can't accept unicode string, for example:

([email protected])7> wf:to_binary("abc").                          
<<"abc">>
([email protected])8> wf:to_binary("你好").
** exception error: bad argument
     in function  list_to_binary/1
        called as list_to_binary([20320,22909])
     in call from wf_convert:to_binary/1 (src/lib/wf_convert.erl, line 83)
([email protected])9> wf:to_binary(unicode:characters_to_binary("abc")).
<<"abc">>
([email protected])10> wf:to_binary(unicode:characters_to_binary("你好")).
<<228,189,160,229,165,189>>

Perhaps I can use it like <<"你好"/utf8>>, but I also use unicode in form, and use wf:q/1 to call wf:to_binary/1.

And I found the code in wf_convert.erl:

-spec to_binary(term()) -> binary().
...
to_binary(L) when is_list(L) -> list_to_binary(L).

If the code change like this, it must be a good message for us :)

to_binary(L) when is_list(L) -> unicode:characters_to_binary(L).

wf:decode_html (Convenience Functions)

According to the API Documentation it is supported, however there seems to be no implementation of this functionally.
http://nitrogenproject.com/doc/api.html#sec-12

It would be a nice feature to have.

With code similar to the below, not sure if it requires any additional functionality.
html_decode([]) -> [];
html_decode([$&,$a,$m,$p,$;|T]) -> [$&|html_decode(T)];
html_decode([$&,$#,$3,$9,$;|T]) -> [$'|html_decode(T)];
html_decode([$&,$q,$u,$o,$t,$;|T]) -> [$"|html_decode(T)];
html_decode([$&,$g,$t,$;|T]) -> [$>|html_decode(T)];
html_decode([$&,$l,$t,$;|T]) -> [$<|html_decode(T)];
html_decode([H|T]) -> [H|html_decode(T)].

#button{}, #restful_form{}

I would like to add the body tag to button record.

-record(button, {?ELEMENT_BASE(element_button), text="", html_encode=true, click, body, postback, delegate}).

Inside element button emit the body.

Body = Record#button.body, 
wf_tags:emit_tag(input, Body, [
    {id, Record#button.html_id},
    {type, button},
    {class, [button, Record#button.class]},
    {style, Record#button.style},
    {value, Value}
]).

For restful form add either the target field or to keep it consistent with #link{}, call the field new. Below is the illustration of target.

--record(restful_form, {?ELEMENT_BASE(element_restful_form), method="POST", action, html_name, enctype, body=[]}).
+-record(restful_form, {?ELEMENT_BASE(element_restful_form), method="POST", action, html_name,target, enctype, body=[]}).

     {class, WithName#restful_form.class},
   {target, WithName#restful_form.target},

Add an error_handler instead of silently failing or simply printing "Internal Server Error"

An error handler of some sort should be added to wf_core.erl in the catch portion of the run/0 function.

This can allow users to specify how to handle errors:

  1. handle how an error is logged (lager, emailing, syslog, whatever)
  2. display a friendlier error message to the user (similar to how 404s are handled), and providing an alternative for postback/comet requests.

The default error handler will act exactly like the current functionality (die silently)

Right now minimal behavior should export first_request/3 and postback_request/3 both of which take (Type, Error, Stacktrace)

Add smart extensions to the dynamic_route_handler

Short: Allow page modules to support standard (And customizable) extensions. For example: if http://mysite/my/page/module was a valid address, then this would allow intelligently retrieving the pertinent data formatted for json by requesting http://mysite/my/page/module.json

Long: A smart_extensions option should be added to the dynamic_route_handler, which will read a smart_extensions value from the config. Smart exceptions in the config should look like this:

{smart_extensions, [
    {"json", fun dynamic_route_handler:json/0},
    {"atom", fun dynamic_route_handler:atom/0},
    {"something_else", fun some_module:some_function/0}
]}.

If the extension of a request matches a smart extension:

  1. Strip off the extension and see if there is a module that matches the request without an extension. If there is, move on to the next step. If not, this is a static file request and handle it accordingly
  2. Re-record the path info sans extension into the context's page_info: wf_context:page_info(PathinfoSansExt)
  3. Call the function

The function should do something useful with the request, relevant to the extension. In the default provided ones like (dynamic_route_handler:json/0), it would look like this:

dynamic_route_handler:json() ->
   Mod = wf_context:page_module(),
   case erlang:function_exported(Mod, json_body, 0) of
      false ->
         <<"This page does not have a json handler">>;
      true ->
        wf:content_type("application/json"),
        Json = Mod:json_body(),
        _EncodedJson = nitro_mochijson2:encode({struct,Json})
   end.

Basically, it would check for the existence of PageModule:json_body function, and if it exists, call it, assuming it returns a proplist-type structure that can be interpreted by json (that way, the programmer doesn't need to deal with json encoding, just returning encodable erlang data), and finally encoding that structure to send it to the client.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.