KEMBAR78
Modular Web Applications With Netzke | KEY
Modular web
applications with
     Netzke
  Ruby Open Air 2012, Minsk
Denis Gorin
  @nomadcoder
Denis Gorin
  @nomadcoder



 the Netherlands
Denis Gorin
         @nomadcoder



        the Netherlands
+ 30 other countries and counting
Denis Gorin
         @nomadcoder



        the Netherlands
+ 30 other countries and counting
   couchsurfing.org/travelista
Web apps
Web apps


not any web-apps
Web apps


    not any web-apps
Rich Internet Applications
RIA
RIA

RIA?..
RIA

RIA?..
AJAX!
RIA

  RIA?..
  AJAX!
single-page
RIA
RIA
        DB-admins
ECM
      Backends        DMS

E-commerce      CMS
RIA
        DB-admins
ECM
      Backends           DMS

E-commerce      CMS



                            logistics
                SCM
                            ERP              CRM
                    accounting          HR
RIA
                         DB-admins
                ECM
                      Backends            DMS

                 E-commerce      CMS


issue/time-trackers
                                             logistics
       Data logging
    management
                                 SCM
                                             ERP              CRM
                                     accounting          HR
         reporting
RIA

Moving from desktop to Web
Sencha Ext JS
Sencha Ext JS

 Huge set of widgets
 Powerful architecture
 Good documentation
    Active forums
Ext JS + Rails = ?
Ext JS + Rails = ?


  How should we do this?
Showcase: Floralogic
Showcase: 4cast
Showcase:Yanit
     yanit.heroku.com
Showcase: Desktop
 netzke-desktop-demo.heroku.com
Ext JS + Rails = ?


  How should we do this?
MVC?
MVC?


Aren’t controllers for data?
Rails API gem
Rails API gem


Complete JavaScript on initial load?
Showcase: Floralogic
Showcase: Floralogic
TrucksController




  OrdersController
Authorization
Authorization


Client: “I need sellers to be able to login, too”
Authorization


Client: “I need sellers to be able to login, too”
 “...Oh, and don’t let them change or delete
                   anything”
Authorization


Client: “I need sellers to be able to login, too”
 “...Oh, and don’t let them change or delete
                   anything”


            Pro tip: treat your boss as your client
Floralogic: Sellers GUI
Floralogic: Sellers GUI
o_O
o_O
Separate JS per role?
o_O
Separate JS per role?
Dynamically built JS?
o_O
Separate JS per role?
Dynamically built JS?
  Configurable JS?
o_O
     Separate JS per role?
     Dynamically built JS?
       Configurable JS?
What about server-side checks?
o_O
     Separate JS per role?
     Dynamically built JS?
       Configurable JS?
What about server-side checks?
        HEADACHES
Extra headaches


 Dynamic loading of stuff
Let’s think components
 Ext JS is a component (widget) framework




                                   familienservice.de
Let’s think components
   Ext JS is a component (widget) framework


reusability




                                     familienservice.de
Let’s think components
     Ext JS is a component (widget) framework


 reusability
extensibility




                                       familienservice.de
Let’s think components
      Ext JS is a component (widget) framework


   reusability
 extensibility
composability


                                        familienservice.de
Let’s think components
      Ext JS is a component (widget) framework


   reusability
 extensibility
composability
       events
                                        familienservice.de
What’s missing?
What’s missing?


Seamless server-side bindings
What’s missing?


Seamless server-side bindings
Server-driven configuration
Start from server
Start from server

     Authorization
Start from server

     Authorization
         Data
Start from server

     Authorization
         Data
     Business logic
Start from server

     Authorization
         Data
     Business logic
         Ruby!
Client + server = <3
Client + server = <3
Single point of
 configuration
Client + server = <3
Single point of
 configuration
    Testability
Client + server = <3
Single point of
 configuration
    Testability
   Reusability
Client + server = <3
Single point of
 configuration
    Testability
   Reusability
       Code
encapsulation
Netzke component
... is a Ruby class
class SimpleComponent < Netzke::Base
end
Netzke component
   ... is a Ruby class
   class SimpleComponent < Netzke::Base
   end



... along with the corresponding JS class
>> puts SimpleComponent.js_code
Ext.define('Netzke.classes.SimpleComponent', {
  // ...
});
Instantiating in Ext JS
var c = Ext.create('Ext.panel.Panel', {
    title: 'Hello',
    width: 200,
    height: 150,
    html: '... world!',
    bbar: [{text: 'Button'}]
});
Instantiating in Ext JS
var c = Ext.create('Ext.panel.Panel', {
    title: 'Hello',
    width: 200,
    height: 150,
    html: '... world!',
    bbar: [{text: 'Button'}]
});



c.setTitle("Brave new");
Instantiating in Netzke
c = SimpleComponent.new(title: "Hello", html: "...world!")

>> pp c.js_config
{
  :title=>"Hello",
  :html=> "...world!"
}
Showcase:Yanit
Showcase:Yanit
Netzke::Basepack::GridPanel
Showcase:Yanit
             Netzke::Basepack::GridPanel




Column
config:
text
editable
sortable
filterable
editor
hidden
GridPanel
grid = Netzke::Basepack::GridPanel.new (
  model: "Issue",
  columns: [:name, :description, :priority]
)
GridPanel
        grid = Netzke::Basepack::GridPanel.new (
          model: "Issue",
          columns: [:name, :description, :priority]
        )



>> pp grid.js_config[:columns]
GridPanel
               grid = Netzke::Basepack::GridPanel.new (
                 model: "Issue",
                 columns: [:name, :description, :priority]
               )



>> pp grid.js_config[:columns]
[
    {:name=>"id", :text=>"Id", :hidden=>true, :sortable=>true, :filterable=>true},
    {:name=>"name", :editable=>true, :editor=>{:xtype=>:textfield}, ...},
    {:name=>"description", :editor=>{:xtype=>:textarea}, ...},
    {:name=>"priority", :editor=>{:xtype=>:numberfield}, ...}
]
Inheritance
class ExtendedComponent < SimpleComponent
end




>> puts ExtendedComponent.js_code
Ext.define('Netzke.classes.ExtendedComponent', {
  extend: 'Netzke.classes.SimpleComponent',
  // ...
});
Showcase: 4cast
Charts
WeekChart     DayChart
Charts
# It knows we deal with multiple
# forecasts that have to be displayed     class DayChart < ActivityChart
# with colored lines, but it's flexible     def data
# about what to display along the axes        # query data for given day
# (which is configurable)                   end
class ActivityChart < Netzke::Base        end
  js_base_class "Ext.chart.Chart"
                                          class WeekChart < ActivityChart
  # lots of code ...
                                            def data
                                              # query data for given week
  # This data goes to the client
                                            end
  # via the constructor
  def data                                end
    []
  end
end
Other cool things
Other cool things

     Composability
Other cool things

       Composability
  Seamless server bindings
Other cool things

         Composability
    Seamless server bindings
 Dynamic loading of client-code
Conclusion

      Structured DRY code
             OOP
      JS code incapsulation
Desktop-like development for web
Check it out!


   netzke.org
  @nomadcoder

Modular Web Applications With Netzke

Editor's Notes