bulletproof views john athayde bruce williams
play

* BULLETPROOF VIEWS JOHN ATHAYDE & BRUCE WILLIAMS , - PowerPoint PPT Presentation

BUILDING * BULLETPROOF VIEWS JOHN ATHAYDE & BRUCE WILLIAMS , LivingSocial RAILS CONF 2011 BALTIMORE, MARYLAND JOHN a designer (who also develops) * BRUCE a developer (who also designs) * WE WORK AT WE ARE WRITING A BOOK for ?


  1. REQUIRED FIELDS Love the form you ’ re with <%= f.label :first_name %> <span class=”required”>*</span><br /> <%= f.text_field :first_name %> span.required {color: red;}

  2. REQUIRED FIELDS Progressively enhance! <%= f.label :first_name, :class => “required” %> <%= f.text_field :first_name %> label { display: block; } label.required { color: red; } label.required:after { content: “*”; } Not supported in MSIE 7 and below, 8 does not accept images for content www.quirksmode.org/css/beforeafter.html

  3. DON ’ T FIGHT THE BROWSER Embrace it! html { overflow-y: scroll; }

  4. ID vs. CLASS There should be a standard #this_is_an_id .this-is-a-class

  5. ! TIP: Embrace the browser and its flaws. Design to the power of the medium. (SCROLLING IS NOT A FLAW)

  6. SHORTENING Learn to write concise css http://www.flickr.com/photos/tomsaint/3456155628/

  7. CSS SHORTHAND Combine pieces together application.css margin-top: 4px; margin-right: 2px; margin-bottom: 4px; margin-left: 8px; becomes... margin: 4px 2px 4px 8px;

  8. CSS SHORTHAND Combine pieces together application.css background-color: #333; background-image: url(“../images/texture.png”) background-position: top left; background-repeat: repeat; becomes... background: #333 url(“../images/texture.png”) repeat-x top left;

  9. CSS SHORTHAND Combine pieces together CAN BE USED FOR: font background margin border padding list AND WILL HELP YOU Reduce stylesheet size and improve readability.

  10. HOW TO WRITE CSS Hard to read and find what you ’ re looking for... .button-install { margin-left: 30px; font-family: "Helvetica Neue", helvetica, arial, sans-serif; display: block; width: 250px; margin-bottom: 15px; text-align: left; height: 48px; font-size: 20px; font-weight: bold; padding:4px 0 8px 0; background-color: #67c5e6; background-image: -webkit-gradient( linear, left top, left bottom, color-stop(0.23, rgb(103,197,230)), color-stop(0.81, rgb(94,149,167)) ); background-image: -moz-linear-gradient( center top, rgb(103,197,230) 23%, rgb(94,149,167) 81% ); border-radius: 8px; -webkit-border-radius: 8px; -moz-border-radius: 8px; }

  11. HOW TO WRITE CSS Alpha order your properties, use shorthand, one per line .button-install { background-color: #67c5e6; background-image: -webkit-gradient( linear, left top, left bottom, color-stop(0.23, rgb(103,197,230)), color-stop(0.81, rgb(94,149,167)) ); background-image: -moz-linear-gradient( center top, rgb(103,197,230) 23%, rgb(94,149,167) 81% ); -moz-border-radius: 8px; -webkit-border-radius: 8px; border-radius: 8px; display: block; font: bold 20px "Helvetica Neue", helvetica, arial, sans-serif; height: 48px; margin: 0 0 15px 30px; padding:4px 0 8px 0; text-align: left; width: 250px; }

  12. ! TIP: Write effective and concise CSS. Properties in alpha order, be specific, browser experimental calls before standard calls, and don’t use browser hacks.

  13. ? BUT GUYS, WHY DOES THIS MATTER?

  14. WEB ACCESSIBILITY Take care of your users

  15. GOOGLE IS A BLIND USER

  16. §508 www.section508.gov

  17. START SMALL Cover the basics all the time. www.w3.org/TR/WCAG10/full-checklist.html

  18. WEB ACCESSIBILITY ERB Examples link_to @product.name, product_path(@product), :title => “Take a look at #{@product.name}” image_tag “product_12758.png”, :alt => “#{@product.name}” link_to (image_tag “product_12758.png”, :alt => “# {@product.name}”), product_path(@product), :title => “Take a look at #{@product.name}”

  19. WEB ACCESSIBILITY = Well Formed HTML Not just an afterthought.

  20. ! TIP: HTML is code. Don’t be afraid to write it. Well written HTML helps users of all types access and interact with our content or application.

  21. * 3. BUILDING A LAYOUT

  22. A STORY OF A LAYOUT Default application.html.erb <!DOCTYPE html> <html> <head> <title></title> <%= stylesheet_link_tag :all %> <%= javascript_include_tag :defaults %> <%= csrf_meta_tag %> </head> <body> <%= yield %> </body> </html>

  23. CHARSET Combine pieces together application.html.erb <!DOCTYPE html> <html> <head> <meta charset=”utf-8”> <title></title> <%= stylesheet_link_tag :all %> <%= javascript_include_tag :defaults %> <%= csrf_meta_tag %> </head> <body> <%= yield %> </body> </html>

  24. TARGET MSIE By version application.html.erb <!DOCTYPE html> <!--[if lt IE 7 ]> <html lang="en" class="ie ie6"> <![endif]--> <!--[if IE 7 ]> <html lang="en" class="ie ie7"> <![endif]--> <!--[if IE 8 ]> <html lang="en" class="ie ie8"> <![endif]--> <!--[if IE 9 ]> <html lang="en" class="ie ie9"> <![endif]--> <!--[if (gt IE 9)|!(IE)]><!--> <html lang="en"> <!--<![endif]--> Extracted into a gem by Bruce <%= ie_conditional_tag :html %> http://codefluency.com/post/1100393830/ie-conditional-tag-plugin

  25. TARGET MSIE By version application.css section#page { margin: 0 auto; width: 960px; } .ie7 section#page { overflow: hidden; } http://codefluency.com/post/1100393830/ie-conditional-tag-plugin

  26. RECOGNIZE NEW ELEMENTS HTML5 Shiv (or Shim, same thing) Enables the elements and fixes printing on IE <!--[if lt IE 9]> <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script> <![endif]--> code.google.com/p/html5shiv/

  27. modernizr.com

  28. RESET.CSS Get your browser on the same page First showed up in 2007 Put forth by Eric Meyer NOT about defaults Brings browsers to the same base page Makes you specify everything meyerweb.com/eric/tools/css/reset/

  29. RESET.CSS Get your browser on the same page reset.css tml, body, div, span, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, abbr, address, cite, code, del, dfn, em, img, ins, kbd, q, samp, small, strong, sub, sup, var, b, i, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, figcaption, figure, footer, header, hgroup, menu, nav, section, summary, time, mark, audio, video { margin:0; padding:0; border:0; outline:0; font-size:100%; vertical-align:baseline; background:transparent; } ....etc... html5doctor.com/html-5-reset-stylesheet/

  30. CALLING STYLESHEETS Pitfalls of :all X application.html.erb <%= stylesheet_link_tag :all %> Can load things in alpha order, meaning reset happens after

  31. CALLING STYLESHEETS Manually calling them application.html.erb <%= stylesheet_link_tag ‘reset’, ‘application’, ‘buttons’ %>

  32. CALLING STYLESHEETS Defining :defaults config/application.rb class Application < Rails::Application config.action_view.stylesheet_expansions[:defaults] = %w( nav tipsy iconic ui-lightness/jquery-ui-1.8.11.custom jquery.customSelect dashboard shadows dataTables/css/demo_table dataTables/css/demo_page application ) end

  33. FRAMEWORKS/BOILERPLATE Combine pieces together html5boilerplate.com

  34. Build Your Own BUILD YOUR OWN FRAMEWORK Framework http://www.flickr.com/photos/dystopos/315312589/

  35. HIERARCHY OF H TAGS You can reuse the H1. Really. html |-body | |-header | | |-h1 | |-article | | |-h1 | | |-section | | | |-header | | | | |-h1 | | | |-p | | | |-h2

  36. QUESTIONS AND ANSWERS

  37. * AGENDA HOUR 2 The Art of Template Writing Questions

  38. WELCOME BACK! *

  39. * 4. THE ART OF TEMPLATE WRITING

  40. IMPROVING READABILITY http://www.flickr.com/photos/bluefootedbooby/389279217/

  41. WHY WE REFACTOR ➡ Templates can be verbose ➡ Display logic can be very complex ➡ More people need to read, understand, and modify them. ➡ They need to change more frequently, as they’re more subjective

  42. FORMATTING Don ’ t indent with hard tabs <html> <head> <title>...

  43. FORMATTING Indent <% pets.each do |pet| %> <li> <%= pet.name %> </li> <% end %> Better: <% pets.each do |pet| %> <li> <%= pet.name %> </li> <% end %>

  44. FORMATTING Clean up big blocks of text <p> We believe that many dogs are unnecessarily abandoned because of easily solved, unwanted behavior. To combat this, we offer behavior classes to <strong> all <strong> adopters, and all individuals requiring help with their dogs. </p> Still try to keep line length <= 80 characters per line

  45. TIDY Because templating code gets messy. http://www.flickr.com/photos/muehlinghaus/3564021462/

  46. FORMATTING Output formatting isn ’ t your job $ gem install rack-tidy $ gem install rack-tidy-ffi Use one of these (or similar) as middleware

  47. http://www.flickr.com/photos/miltonkeynesman/5359120312/

  48. Zen Coding Use a tool, not a generator div#page>img.logo+ul#navigation>li*5>a <div id="page"> <img src=”” class="logo" /> <ul id="navigation"> <li><a href=""></a></li> <li><a href=""></a></li> <li><a href=""></a></li> <li><a href=""></a></li> <li><a href=""></a></li> </ul> </div> PROJECT FILES: code.google.com/p/zen-coding/

  49. ! TIP: Know your team. YTMV

  50. TOOLS What do we use for each situation? http://www.flickr.com/photos/anotherphotograph/3571242832/

  51. REFACTORING TOOLS PARTIALS Extract part of a template (usually for reuse) HELPERS Extract complex logic BLOCK HELPERS Extract complex, wrap content, View DSLs VIEW CLASSES Reduce helper spaghetti code, encapsulate state, ease testing

  52. QUERYING, ORDERING, LIMITING Don ’ t do this. X <% Pet.all.order(:adoption_date).each do |pet| %> <%# Use pet %> <% end %>

  53. QUERYING, ORDERING, LIMITING Instead, set an instance variable pets_controller.rb def index @pets_by_adoption = Pet.all.order(:adoption_date) end _adoption_list.html.erb <% @pets_by_adoption.each do |pet| %> <%# Use pet %> <% end %>

  54. QUERYING, ORDERING, LIMITING Or instead, use a helper pets_helper.rb def pets_by_adoption @pets_by_adoption = Pet.all.order(:adoption_date) end _adoption_list.html.erb <% pets_by_adoption.each do |pet| %> <%# Use pet %> <% end %>

  55. ! TIP: Avoid capital letters in your template code (configuration constants and model classes).

  56. LOCAL ASSIGNMENT Don ’ t do this, ever. Never. At no time... X _availability.html.erb <% number_available = Pet.available.count %> <% available, unavailable = pets_by_status %> <% next_month = Date.today >> 1 %> Messy, noisy, undocumentable, easy to accidentally remove

  57. LOCAL ASSIGNMENT Instead, use an instance varaible pets_controller.rb def index # ... other stuff @number_available = Pet.available.count end

  58. LOCAL ASSIGNMENT Or instead, use a helper pets_helper.rb def number_available @number_available ||= Pet.available.count end

  59. CONDITIONAL CONTENT Avoid long if/else clauses X <% if @pet.at_risk? <%# Lots of content %> <% else %> <%# Different lots of content %> <% end %> If lengthy, this makes it hard to get a quick feeling of what the page contains.

  60. CONDITIONAL CONTENT Better, split to files pets_helper.rb def risk_assessment if @pet.at_risk? render partial: 'at_risk' else render partial: 'not_at_risk' end end show.html.erb <%= risk_assesment %>

  61. CONDITIONAL CONTENT Avoid long and complex conditions X <% if current_user.admin? || current_user.can?(:edit_pet) || pet.owner == current_user %> <%= render partial: 'form', locals: {pet: pet} %> <% end %> If lengthy, this makes it hard to get a quick feeling of what the page contains.

  62. CONDITIONAL CONTENT Better, extract condition to a meaningful helper _pet.html.erb <% if can_edit_pet?(pet) %> <%= render partial: 'form', locals: {pet: pet} <% end %>

Recommend


More recommend