Building Web Interface On Rails
Upcoming SlideShare
Loading in...5
×
 

Like this? Share it with your network

Share

Building Web Interface On Rails

on

  • 7,668 views

 

Statistics

Views

Total Views
7,668
Views on SlideShare
7,178
Embed Views
490

Actions

Likes
16
Downloads
206
Comments
0

6 Embeds 490

http://ihower.idv.tw 238
http://ihower.tw 225
http://www.slideshare.net 24
http://blog.ihower.idv.tw 1
http://webcache.googleusercontent.com 1
https://www.linkedin.com 1

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Building Web Interface On Rails Presentation Transcript

  • 1. BUILDING WEB INTERFACES ON RAILS ihower@handlino.com Ruby Tuesday 2009/5/19
  • 2. ABOUT ME • a.k.a ihower • http://ihower.idv.tw/blog/ • http://twitter.com/ihower • Rails developer • http://handlino.com • http://registrano.com
  • 3. AGENDA • 1. some useful helper technique • 2. handicraft_helper plugin • 3. handicraft_ujs plugin • 4. some UI design patterns implementation
  • 4. EXAMPLE CODE all demo code is here: http://github.com/ihower/handicraft-interfaces 1. download 2. rake dev:build 3. script/server
  • 5. 1. USEFUL HELPER TECHNIQUES
  • 6. CONTENT_FOR # /layouts/application.html.erb # foobar.html.erb <p>fooooooooooooooooooo</p> A <html> <head> <% content_for :page_javascript do %> <script type=quot;text/javascriptquot;> B <%= yield :page_javascript %> ... B </script> </head> <% end %> <body> <p>barrrrrrrrrrrrrrrrrr</p> A A <%= yield %> <div id=”sidebar”> <%= yield :sidebar %> <div> </body> </html>
  • 7. PASSING BLOCK PARAMETER Original version, we need a helper <% link_to_remote some_helper(contact), :url => contact_path(contact), :method => :get %> My Want <% link_to_remote :url => contact_path(contact), :method => :get do %> <span class=quot;picturequot;> <%= image_tag contact.buddy_icon %> </span> <span class=quot;real-namequot;> <%= contact.full_name %></span> <% if contact.friendly? %> <span class=quot;is-friendquot;>is your friend.</span> <% else %> <span class=quot;no-friendquot;>is not your friend.</span> <% end -%> <span class=quot;nicknamequot;><%= contact.nickname %></span> <% end -%>
  • 8. PASSING BLOCK PARAMETER Use block_given?, concat and capture(&block) # provide block suppoet def link_to_remote(*args, &block) if block_given? options = args.first || {} html_options = args.second concat( link_to_function(capture(&block), remote_function(options), html_options || options.delete(:html)) ) else name = args.first options = args.second || {} html_options = args.third link_to_function(name, remote_function(options), html_options || options.delete(:html)) end end
  • 9. CONTENT_TAG Ruby Style, less line of code <% if some_condition %> <h1>foobar</h1> <%= content_tag(quot;h1quot;, quot;foobarquot;) if some_condition %> <% end %> HTML attributes as helper options def some_helper( title, options = {} ) content_tag(quot;pquot;, content_tag(quot;spanquot;, title, options), :class => 'p_classquot;) end <p class=quot;p_classquot;><span class=quot;foobarquot;>test</span></p>
  • 10. KNOW RAILS HELPERS • READ Rails helpers source code • /actionpack-x.y.z/lib/action_view/helpers/*
  • 11. 2. HANDICRAFT HELPER PLUGIN handlino’s favorite rails helpers
  • 12. PROBLEM AND SOLUTION • Weneed complex/logistic HTML in helper, but write a lot HTML string + operators are painful. • Myearly solution: use markaby plugin, but it’s slow and yet another dependency. • currentsolution idea from Composite&Builder pattern (Refactoring to Patterns book), it’s simple, component and fast.
  • 13. COMPOSITE PATTERN class TagNode include ActionView::Helpers::TagHelper def initialize(name, options = {}) USAGE: @name = name.to_s table = TagNode.new('table', table_tag_options) @attributes = options table << thead = TagNode.new(:thead) @children = [] thead << tr = TagNode.new(:tr, :class => 'odd') end thead << tr = TagNode.new(:tr, :class => 'even') def to_s table << tbody = TagNode.new('tbody') value = @children.each { |c| c.to_s }.join tbody << tr = TagNode.new('tr', :class => cycle(quot;quot;,quot;oddquot;) ) content_tag(@name, value.to_s, @attributes) end return table.to_s def <<(tag_node) @children << tag_node end end
  • 14. LIVE DEMO • render_menu • render_table (column-oriented table) • breadcrumb
  • 15. 3. HANDICRAFT UJS PLUGIN a jQuery replacement for Ajax on Rails
  • 16. IDEA 1: JRAILS http://ennerchi.com/projects/jrails
  • 17. IDEA 2: UNOBTRUSIVE http://blog.lawrencepit.com/2008/09/04/unobtrusive-jquery-rails/ Separation of functionality from content
  • 18. MY WANT • jQuery (write less, do more) • RJS (in controller, because it keep controller ruby style) • RESTful (Rails way) • unobtrusive and accessible (hate inline js everywhere)
  • 19. INLINE JS EVERYWHERE <%= link_to_remote 'ajax', :url => person_path(person), :method => :get %> <a href=quot;#quot; onclick=quot;new Ajax.Request('/people/1', {asynchronous:true, evalScripts:true, method:'get', parameters:'authenticity_token=' + encodeURIComponent('uwdvZFNiqzfd/iFOX65Ov9AkxVelIUVSylrWWxb58XM=')}); return false;quot;>ajax</a> <% remote_form_for @person, person_path(@person), :html => { :method => :put } do |f| %> <form action=quot;/people/1quot; id=quot;edit_person_1quot; method=quot;postquot; onsubmit=quot;new Ajax.Request('/ people/1', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)}); return false;quot;>
  • 20. HANDICRAFT WAY <%= link_to 'ajax', person_path(person), :class => quot;h-getquot; %> <a href=quot;/people/1quot; class=quot;h-getquot;>ajax</a> <% form_for @person, person_path(@person), :html => { :method => :put, :class => 'h-put' } do |f| %> <form action=quot;/people/1quot; class=quot;h-putquot; id=quot;edit_person_1quot; method=quot;postquot;>
  • 21. <a href=quot;#quot; onclick=quot;new Ajax.Request('/ people/1', {asynchronous:true, evalScripts:true, method:'get', parameters:'authenticity_token=' + <a href=quot;/people/1quot; class=quot;h-getquot;>ajax</a> encodeURIComponent('uwdvZFNiqzfd/ iFOX65Ov9AkxVelIUVSylrWWxb58XM=')}); return false;quot;>ajax</a> <form action=quot;/people/1quot; id=quot;edit_person_1quot; method=quot;postquot; onsubmit=quot;new Ajax.Request('/ people/1', {asynchronous:true, <form action=quot;/people/1quot; class=quot;h-putquot; evalScripts:true, parameters:Form.serialize(this)}); return id=quot;edit_person_1quot; method=quot;postquot;> false;quot;>
  • 22. HOW • JQuery 1.3 live binding • jQuery metadata plugin • jQuery form plugin • jQuery version RJS (extract from jRails plugin)
  • 23. LIVE DEMO • h-get, h-post, h-put, h-delete •{ update: ‘content’ } •{ callback: ‘handle_json’ } •{ confirm: ‘Are you sure? }
  • 24. 4. UI DESIGN PATTERNS IMPLEMENTATION
  • 25. IDEA http://designingwebinterfaces.com/explore
  • 26. LIVE DEMO • Single-Field Inline Edit • Multi-Field Inline Edit • Group Edit • Sortable List