= Application Extensions and Helpers (padrino-helpers) === Overview This component provides a great deal of view helpers related to html markup generation. There are helpers for generating tags, forms, links, images, and more. Most of the basic methods should be very familiar to anyone who has used rails view helpers. === Output Helpers Output helpers are a collection of important methods for managing, capturing and displaying output in various ways and is used frequently to support higher-level helper functions. There are three output helpers worth mentioning: <tt>content_for</tt>, <tt>capture_html</tt>, and <tt>concat_content</tt> The content_for functionality supports capturing content and then rendering this into a different place such as within a layout. One such popular example is including assets onto the layout from a template: # app/views/site/index.erb ... <% content_for :assets do %> <%= stylesheet_link_tag 'index', 'custom' %> <% end %> ... Added to a template, this will capture the includes from the block and allow them to be yielded into the layout: # app/views/layout.erb ... <head> <title>Example</title> <%= stylesheet_link_tag 'style' %> <%= yield_content :assets %> </head> ... This will automatically insert the contents of the block (in this case a stylesheet include) into the location the content is yielded within the layout. The capture_html and the concat_content methods allow content to be manipulated and stored for use in building additional helpers accepting blocks or displaying information in a template. One example is the use of these in constructing a simplified 'form_tag' helper which accepts a block. # form_tag '/register' do ... end def form_tag(url, options={}, &block) # ... truncated ... inner_form_html = capture_html(&block) concat_content '<form>' + inner_form_html + '</form>' end This will capture the template body passed into the form_tag block and then append the content to the template through the use of <tt>concat_content</tt>. Note have been built to work for both haml and erb templates using the same syntax. The list of defined helpers in the 'output helpers' category: * <tt>content_for(key, &block)</tt> * Capture a block of content to be rendered at a later time. * <tt>content_for(:head) { ...content... }</tt> * Also supports arguments passed to the content block * <tt>content_for(:head) { |param1, param2| ...content... }</tt> * <tt>yield_content(key, *args)</tt> * Render the captured content blocks for a given key. * <tt>yield_content :head</tt> * Also supports arguments yielded to the content block * <tt>yield_content :head, param1, param2</tt> * <tt>capture_html(*args, &block)</tt> * Captures the html from a block of template code for erb or haml * <tt>capture_html(&block)</tt> => "...html..." * <tt>concat_content(text="")</tt> * Outputs the given text to the templates buffer directly in erb or haml * <tt>concat_content("This will be output to the template buffer in erb or haml")</tt> === Tag Helpers Tag helpers are the basic building blocks used to construct html 'tags' within a view template. There are three major functions for this category: <tt>tag</tt>, <tt>content_tag</tt> and <tt>input_tag</tt>. The tag and content_tag are for building arbitrary html tags with a name and specified options. If the tag contains 'content' within then <tt>content_tag</tt> is used. For example: tag(:br, :style => ‘clear:both’) => <br style="clear:both" /> content_tag(:p, "demo", :class => ‘light’) => <p class="light">demo</p> The input_tag is used to build tags that are related to accepting input from the user: input_tag :text, :class => "demo" => <input type='text' class='demo' /> input_tag :password, :value => "secret", :class => "demo" Note that all of these accept html options and result in returning a string containing html tags. The list of defined helpers in the 'tag helpers' category: * <tt>tag(name, options={})</tt> * Creates an html tag with the given name and options * <tt>tag(:br, :style => 'clear:both')</tt> => <br style="clear:both" /> * <tt>tag(:p, :content => "demo", :class => 'large')</tt> => <p class="large">demo</p> * <tt>content_tag(name, content, options={})</tt> * Creates an html tag with given name, content and options * <tt>content_tag(:p, "demo", :class => 'light')</tt> => <p class="light">demo</p> * <tt>content_tag(:p, :class => 'dark') { ...content... }</tt> => <p class="dark">...content...</p> * <tt>input_tag(type, options = {})</tt> * Creates an html input field with given type and options * <tt>input_tag :text, :class => "demo"</tt> * <tt>input_tag :password, :value => "secret", :class => "demo"</tt> === Asset Helpers Asset helpers are intended to help insert useful html onto a view template such as 'flash' notices, hyperlinks, mail_to links, images, stylesheets and javascript. An example of their uses would be on a simple view template: # app/views/example.haml ... %head = stylesheet_link_tag 'layout' = javascript_include_tag 'application' %body ... = flash_tag :notice %p= link_to 'Blog', '/blog', :class => 'example' %p Mail me at #{mail_to 'fake@faker.com', "Fake Email Link", :cc => "test@demo.com"} %p= image_tag 'padrino.png', :width => '35', :class => 'logo' The list of defined helpers in the 'asset helpers' category: * <tt>flash_tag(kind, options={})</tt> * Creates a div to display the flash of given type if it exists * <tt>flash_tag(:notice, :class => 'flash', :id => 'flash-notice')</tt> * <tt>link_to(*args, &block)</tt> * Creates a link element with given name, url and options * <tt>link_to 'click me', '/dashboard', :class => 'linky'</tt> * <tt>link_to 'click me', '/dashboard', :class => 'linky', :if => @foo.present?</tt> * <tt>link_to 'click me', '/dashboard', :class => 'linky', :unless => @foo.blank?</tt> * <tt>link_to 'click me', '/dashboard', :class => 'linky', :unless => :current</tt> * <tt>link_to('/dashboard', :class => 'blocky') { ...content... }</tt> * <tt>mail_to(email, caption=nil, mail_options={})</tt> * Creates a mailto link tag to the specified email_address * <tt>mail_to "me@demo.com"</tt> * <tt>mail_to "me@demo.com", "My Email", :subject => "Feedback", :cc => 'test@demo.com'</tt> * <tt>image_tag(url, options={})</tt> * Creates an image element with given url and options * <tt>image_tag('icons/avatar.png')</tt> * <tt>stylesheet_link_tag(*sources)</tt> * Returns a stylesheet link tag for the sources specified as arguments * <tt>stylesheet_link_tag 'style', 'application', 'layout'</tt> * <tt>javascript_include_tag(*sources)</tt> * Returns an html script tag for each of the sources provided. * <tt>javascript_include_tag 'application', 'special'</tt> === Form Helpers Form helpers are the 'standard' form tag helpers you would come to expect when building forms. A simple example of constructing a non-object form would be: - form_tag '/destroy', :class => 'destroy-form', :method => 'delete' do = flash_tag(:notice) - field_set_tag do %p = label_tag :username, :class => 'first' = text_field_tag :username, :value => params[:username] %p = label_tag :password, :class => 'first' = password_field_tag :password, :value => params[:password] %p = label_tag :strategy = select_tag :strategy, :options => ['delete', 'destroy'], :selected => 'delete' %p = check_box_tag :confirm_delete - field_set_tag(:class => 'buttons') do = submit_tag "Remove" The list of defined helpers in the 'form helpers' category: * <tt>form_tag(url, options={}, &block)</tt> * Constructs a form without object based on options * Supports form methods 'put' and 'delete' through hidden field * <tt>form_tag('/register', :class => 'example') { ... }</tt> * <tt>field_set_tag(*args, &block)</tt> * Constructs a field_set to group fields with given options * <tt>field_set_tag(:class => 'office-set') { }</tt> * <tt>field_set_tag("Office", :class => 'office-set') { }</tt> * <tt>error_messages_for(:record, options={})</tt> * Constructs list html for the errors for a given object * <tt>error_messages_for :user</tt> * <tt>label_tag(name, options={}, &block)</tt> * Constructs a label tag from the given options * <tt>label_tag :username, :class => 'long-label'</tt> * <tt>label_tag(:username, :class => 'blocked-label') { ... }</tt> * <tt>hidden_field_tag(name, options={})</tt> * Constructs a hidden field input from the given options * <tt>hidden_field_tag :session_key, :value => 'secret'</tt> * <tt>text_field_tag(name, options={})</tt> * Constructs a text field input from the given options * <tt>text_field_tag :username, :class => 'long'</tt> * <tt>text_area_tag(name, options={})</tt> * Constructs a text area input from the given options * <tt>text_area_tag :username, :class => 'long'</tt> * <tt>password_field_tag(name, options={})</tt> * Constructs a password field input from the given options * <tt>password_field_tag :password, :class => 'long'</tt> * <tt>check_box_tag(name, options={})</tt> * Constructs a checkbox input from the given options * <tt>check_box_tag :remember_me, :checked => true</tt> * <tt>radio_button_tag(name, options={})</tt> * Constructs a radio button input from the given options * <tt>radio_button_tag :gender, :value => 'male'</tt> * <tt>select_tag(name, settings={})</tt> * Constructs a select tag with options from the given settings * <tt>select_tag(:favorite_color, :options => ['1', '2', '3'], :selected => '1')</tt> * <tt>select_tag(:more_color, :options => [['label', '1'], ['label2', '2']])</tt> * <tt>select_tag(:multiple_color, :options => [...], :multiple => true)</tt> * <tt>file_field_tag(name, options={})</tt> * Constructs a file field input from the given options * <tt>file_field_tag :photo, :class => 'long'</tt> * <tt>submit_tag(caption, options={})</tt> * Constructs a submit button from the given options * <tt>submit_tag "Create", :class => 'success'</tt> * <tt>button_tag(caption, options={})</tt> * Constructs an input (type => 'button') from the given options * <tt>button_tag "Cancel", :class => 'clear'</tt> * <tt>image_submit_tag(source, options={})</tt> * Constructs an image submit button from the given options * <tt>image_submit_tag "submit.png", :class => 'success'</tt> === FormBuilders Form builders are full-featured objects allowing the construction of complex object-based forms using a simple, intuitive syntax. A form_for using these basic fields might look like: - form_for @user, '/register', :id => 'register' do |f| = f.error_messages %p = f.label :username, :caption => "Nickname" = f.text_field :username %p = f.label :email = f.text_field :email %p = f.label :password = f.password_field :password %p = f.label :is_admin, :caption => "Admin User?" = f.check_box :is_admin %p = f.label :color, :caption => "Favorite Color?" = f.select :color, :options => ['red', 'black'] %p - fields_for @user.location do |location| = location.text_field :street = location.text_field :city %p = f.submit "Create", :class => 'button' The list of defined helpers in the 'form builders' category: * <tt>form_for(object, url, settings={}, &block)</tt> * Constructs a form using given or default form_builder * Supports form methods 'put' and 'delete' through hidden field * Defaults to StandardFormBuilder but you can easily create your own! * <tt>form_for(@user, '/register', :id => 'register') { |f| ...field-elements... }</tt> * <tt>form_for(:user, '/register', :id => 'register') { |f| ...field-elements... }</tt> * <tt>fields_for(object, settings={}, &block)</tt> * Constructs fields for a given object for use in an existing form * Defaults to StandardFormBuilder but you can easily create your own! * <tt>fields_for @user.assignment do |assignment| ... end</tt> * <tt>fields_for :assignment do |assigment| ... end</tt> The following are fields provided by AbstractFormBuilder that can be used within a form_for or fields_for: * <tt>error_messages(options={})</tt> * Displays list html for the errors on form object * <tt>f.errors_messages</tt> * <tt>label(field, options={})</tt> * <tt>f.label :name, :class => 'long'</tt> * <tt>text_field(field, options={})</tt> * <tt>f.text_field :username, :class => 'long'</tt> * <tt>check_box(field, options={})</tt> * Uses hidden field to provide a 'unchecked' value for field * <tt>f.check_box :remember_me, :uncheck_value => 'false'</tt> * <tt>radio_button(field, options={})</tt> * <tt>f.radio_button :gender, :value => 'male'</tt> * <tt>hidden_field(field, options={})</tt> * <tt>f.hidden_field :session_id, :class => 'hidden'</tt> * <tt>text_area(field, options={})</tt> * <tt>f.text_area :summary, :class => 'long'</tt> * <tt>password_field(field, options={})</tt> * <tt>f.password_field :secret, :class => 'long'</tt> * <tt>file_field(field, options={})</tt> * <tt>f.file_field :photo, :class => 'long'</tt> * <tt>select(field, options={})</tt> * <tt>f.select(:state, :options => ['California', 'Texas', 'Wyoming'])</tt> * <tt>f.select(:state, :collection => @states, :fields => [:name, :id])</tt> * <tt>f.select(:state, :options => [...], :include_blank => true)</tt> * <tt>submit(caption, options={})</tt> * <tt>f.submit "Update", :class => 'long'</tt> * <tt>image_submit(source, options={})</tt> * <tt>f.image_submit "submit.png", :class => 'long'</tt> There is also an additional StandardFormBuilder which builds on the abstract fields that can be used within a form_for. A form_for using these standard fields might be: - form_for @user, '/register', :id => 'register' do |f| = f.error_messages = f.text_field_block :name, :caption => "Full name" = f.text_field_block :email = f.check_box_block :remember_me = f.select_block :fav_color, :options => ['red', 'blue'] = f.password_field_block :password = f.submit_block "Create", :class => 'button' and would generate this html (with each input contained in a paragraph and containing a label): <form id="register" action="/register" method="post"> <p><label for="user_name">Full name: </label><input type="text" id="user_name" name="user[name]"></p> ...omitted... <p><input type="submit" value="Create" class="button"></p> </form> The following are fields provided by StandardFormBuilder that can be used within a form_for or fields_for: * <tt>text_field_block(field, options={}, label_options={})</tt> * <tt>text_field_block(:nickname, :class => 'big', :caption => "Username")</tt> * <tt>text_area_block(field, options={}, label_options={})</tt> * <tt>text_area_block(:about, :class => 'big')</tt> * <tt>password_field_block(field, options={}, label_options={})</tt> * <tt>password_field_block(:code, :class => 'big')</tt> * <tt>file_field_block(field, options={}, label_options={})</tt> * <tt>file_field_block(:photo, :class => 'big')</tt> * <tt>check_box_block(field, options={}, label_options={})</tt> * <tt>check_box_block(:remember_me, :class => 'big')</tt> * <tt>select_block(field, options={}, label_options={})</tt> * <tt>select_block(:country, :option => ['USA', 'Canada'])</tt> * <tt>submit_block(caption, options={})</tt> * <tt>submit_block(:username, :class => 'big')</tt> * <tt>image_submit_block(source, options={})</tt> * <tt>image_submit_block('submit.png', :class => 'big')</tt> You can also easily build your own FormBuilder which allows for customized fields and behavior: class MyCustomFormBuilder < AbstractFormBuilder # Here we have access to a number of useful variables # # * template (use this to invoke any helpers)(ex. template.hidden_field_tag(...)) # * object (the record for this form) (ex. object.valid?) # * object_name (object's underscored type) (ex. object_name => 'admin_user') # # We also have access to self.field_types => [:text_field, :text_area, ...] # In addition, we have access to all the existing field tag helpers (text_field, hidden_field, file_field, ...) end Once a custom builder is defined, any call to form_for can use the new builder: - form_for @user, '/register', :builder => 'MyCustomFormBuilder', :id => 'register' do |f| ...fields here... The form builder can even be made into the default builder when form_for is invoked: # anywhere in the Padrino or Sinatra application set :default_builder, 'MyCustomFormBuilder' And there you have it, a fairly complete form builder solution for Padrino (and Sinatra). I hope to create or merge in an even better 'default' form_builder in the near future. === Format Helpers Format helpers are several useful utilities for manipulating the format of text to achieve a goal. The four format helpers are <tt>escape_html</tt>, <tt>relative_time_ago</tt>, <tt>time_in_words</tt>, and <tt>js_escape_html</tt>. The escape_html and js_escape_html function are for taking an html string and escaping certain characters. <tt>escape_html</tt> will escape ampersands, brackets and quotes to their HTML/XML entities. This is useful to sanitize user content before displaying this on a template. <tt>js_escape_html</tt> is used for passing javascript information from a js template to a javascript function. escape_html('<hello>&<goodbye>') # => <hello>&<goodbye> There is also an alias for escape_html called <tt>h</tt> for even easier usage within templates. Format helpers also includes a number of useful text manipulation functions such as <tt>simple_format</tt>, <tt>pluralize</tt>, <tt>word_wrap</tt>, and <tt>truncate</tt>. simple_format("hello\nworld") # => "<p>hello<br/>world</p>" pluralize(2, 'person') => '2 people' word_wrap('Once upon a time', :line_width => 8) => "Once upon\na time" truncate("Once upon a time in a world far far away", :length => 8) => "Once upon..." These helpers can be invoked from any route or view within your application. The list of defined helpers in the 'format helpers' category: * <tt>simple_format(text, html_options)</tt> * Returns text transformed into HTML using simple formatting rules. * <tt>simple_format("hello\nworld")</tt> => "<p>hello<br/>world</p>" * <tt>pluralize(count, singular, plural = nil)</tt> * Attempts to pluralize the singular word unless count is 1. * <tt>pluralize(2, 'person')</tt> => '2 people' * <tt>word_wrap(text, *args)</tt> * Wraps the text into lines no longer than line_width width. * <tt>word_wrap('Once upon a time', :line_width => 8)</tt> => "Once upon\na time" * <tt>truncate(text, *args)</tt> * Truncates a given text after a given :length if text is longer than :length (defaults to 30). * <tt>truncate("Once upon a time in a world far far away", :length => 8)</tt> => "Once upon..." * <tt>escape_html</tt> (alias <tt>h</tt> and <tt>h!</tt>) * (from RackUtils) Escape ampersands, brackets and quotes to their HTML/XML entities. * <tt>relative_time_ago(date)</tt> * Returns relative time in words referencing the given date * <tt>relative_time_ago(2.days.ago)</tt> => "2 days" * <tt>relative_time_ago(5.minutes.ago)</tt> => "5 minutes" * <tt>relative_time_ago(2800.days.ago)</tt> => "over 7 years" * <tt>time_in_words(date)</tt> * Returns relative time in the past or future using appropriate date format * <tt>time_in_words(2.days.ago)</tt> => "2 days ago" * <tt>time_in_words(100.days.ago)</tt> => "Tuesday, July 21" * <tt>time_in_words(1.day.from_now)</tt> => "tomorrow" * <tt>js_escape_html(html_content)</tt> * Escapes html to allow passing information to javascript. Used for passing data inside an ajax .js.erb template * <tt>js_escape_html("<h1>Hey</h1>")</tt> See the wiki article for additional information: <...WIKI...> === Render Helpers This component provides a number of rendering helpers making the process of displaying templates a bit easier. This plugin also has support for useful additions such as partials (with support for :collection) for the templating system. Using render plugin helpers is extremely simple. If you want to render an erb template in your view path: erb_template 'path/to/my/template' or using haml templates works just as well: haml_template 'path/to/haml/template' There is also a method which renders the first view matching the path and removes the need to define an engine: render_template 'path/to/any/template' It is worth noting these are mostly for convenience. With nested view file paths in Sinatra, this becomes tiresome: haml :"the/path/to/file" erb "/path/to/file".to_sym Finally, we have the all-important partials support for rendering mini-templates onto a page: partial 'photo/_item', :object => @photo, :locals => { :foo => 'bar' } partial 'photo/_item', :collection => @photos This works as you would expect and also supports the collection counter inside the partial <tt>item_counter</tt> # /views/photo/_item.haml # Access to collection counter with <partial_name>_counter i.e item_counter # Access the object with the partial_name i.e item The list of defined helpers in the 'render helpers' category: * <tt>erb_template(template_path, options={})</tt> * Renders a erb template based on the given path * <tt>erb_template 'users/new'</tt> * <tt>haml_template(template_path, options={})</tt> * Renders a haml template based on the given path * <tt>haml_template 'users/new'</tt> * <tt>render_template(template_path, options={})</tt> * Renders the first detected template based on the given path * <tt>render_template 'users/new'</tt> * <tt>render_template 'users/index', :template_engine => 'haml'</tt> * <tt>partial(template, *args)</tt> * Renders the html related to the partial template for object or collection * <tt>partial 'photo/_item', :object => @photo, :locals => { :foo => 'bar' }</tt> * <tt>partial 'photo/_item', :collection => @photos</tt> See the wiki article for additional information: <...WIKI...> == Copyright Copyright (c) 2010 Padrino. See LICENSE for details.