Module: Sinatra::NiceEasyHelpers

Defined in:
lib/sinatra/nice_easy_helpers.rb

Constant Summary collapse

BOOLEAN_ATTRIBUTES =

:stopdoc:

%w(disabled readonly multiple checked selected).to_set
HTML_ESCAPE =
{ '&' => '&amp;',  '>' => '&gt;',   '<' => '&lt;', '"' => '&quot;' }

Instance Method Summary collapse

Instance Method Details

#button(*args) ⇒ Object

:call-seq:

button(name, content, options = {})
button(name, content, type = "submit", options = {})

Creates a button element with the name/id and with the content provided. Defaults to the submit type.

button "continue", "Save and continue" # =>
  <button id="continue" name="continue" type="submit">Save and continue</button>

button "add-email", "Add another Email", 'button' # =>
  <button id="add-email" name="add-email" type="button">Add another Email</button>


200
201
202
203
204
205
206
# File 'lib/sinatra/nice_easy_helpers.rb', line 200

def button(*args)
  options = args.extract_options!.symbolize_keys
  name = args.shift
  content = args.shift
  type = args.shift || 'submit'
  tag :button, content, options.merge(:type => type, :name => name, :id => name)
end

#checkbox_field(*args) ⇒ Object

:call-seq:

checkbox_field(field, options)
checkbox_field(obj, field, options)

Returns a checkbox input for the specified field, which may be on an object. If there is a value for the field in the request params or an object is provided with that value set, it will mark this field as checked if it matches the value for the field.

checkbox_field :subscriptions, :value => 1 # =>
  <input type="checkbox" name="subscriptions" id="subscriptions" value="1" />

# Where the @params[:subscriptions] value is set already to "1"
checkbox_field :subscriptions, :value => 1 # =>
  <input type="checkbox" name="subscriptions" id="subscriptions" value="1" checked="checked" />

checkbox_field :user, :subscriptions, :value => 1 # =>
  <input type="checkbox" name="user[subscriptions]" id="user_subscriptions" value="1" />

@user = User.new(:subscriptions => ['newsletters'])
checkbox_field @user, :subscriptions, :value => 'newsletters' # =>
  <input type="checkbox" name="user[subscriptions]" id="user_subscriptions" value="newsletters" checked="checked" />


280
281
282
# File 'lib/sinatra/nice_easy_helpers.rb', line 280

def checkbox_field(*args)
  input_tag 'checkbox', *args
end

#file_field(*args) ⇒ Object

:call-seq:

file_field(field, options = {})
file_field(obj, field, options = {})

Returns a file input for the specified field, which may be on an object.

file_field :picture # =>
  <input type="file" name="picture" id="picture" />

file_field :user, :picture # =>
  <input type="file" name="user[picture]" id="user_picture" />

@user = User.new
file_field @user, :picture # =>
  <input type="file" name="user[picture]" id="user_picture" />


183
184
185
# File 'lib/sinatra/nice_easy_helpers.rb', line 183

def file_field(*args)
  input_tag 'file', *args
end

#hidden_field(*args) ⇒ Object

:call-seq:

hidden_field(field, options = {})
hidden_field(obj, field, options = {})

Returns a hidden input for the specified field, which may be on an object. If there is a value for the field in the request params or an object is provided with that value set, it will auto-populate the input. If not you should set the value with the :value option.

hidden_field :external_id, :value => 25 # =>
  <input type="hidden" name="external_id" id="external_id" value="25" />

# Where the @params[:external_id] value is set already to "247"
hidden_field :external_id # =>
  <input type="hidden" name="external_id" id="external_id" value="247" />

hidden_field :user, :external_id, :value => 25 # =>
  <input type="hidden" name="user[external_id]" id="user_external_id" value="25" />

@user = User.new(:external_id => 247)
hidden_field @user, :external_id # =>
  <input type="hidden" name="user[external_id]" id="user_external_id" value="247" />


423
424
425
# File 'lib/sinatra/nice_easy_helpers.rb', line 423

def hidden_field(*args)
  input_tag 'hidden', *args
end

#image_input(src, options = {}) ⇒ Object

Creates an image input field for the source and options provided. The image source is calculated the same way it is for Sinatra::NiceEasyHelpers#image_tag

image_input "buttons/save_close.png", :alt => 'Save and close'
  <input type="image" src="buttons/save_close.png" alt="Save and close" />


241
242
243
# File 'lib/sinatra/nice_easy_helpers.rb', line 241

def image_input(src, options = {})
  single_tag :input, options.merge(:type => 'image', :src => compute_public_path(src, 'images'))
end

#image_tag(src, options = {}) ⇒ Object

Creates an image tag for the given image file. If a relative source is given it assumes it lives in /images/ on your server.

image_tag "button.jpg" :alt => 'Do some Action' # =>
  <img src="/images/button.jpg" alt="Do some Action" />

image_tag "/icons/delete.jpg" :alt => 'Remove', :class => 'small-button' # =>
  <img src="/icons/delete.jpg" alt="Remove" class="small-button" />

image_tag "http://www.example.com/close.jpg" # =>
  <img src="http://www.example.com/close.jpg" />


33
34
35
# File 'lib/sinatra/nice_easy_helpers.rb', line 33

def image_tag(src, options = {})
  single_tag :img, options.merge(:src => compute_public_path(src, 'images'))
end

#javascript_include_tag(*sources) ⇒ Object

Creates a script tag for each source provided. If you just supply a relative filename (with or without the .js extension) it will assume it can be found in your public/javascripts directory. If you provide an absolute path it will use that.

javascript_include_tag 'jquery' # =>
  <script src="/javascripts/jquery.js" type="text/javascript"></script>

javascript_include_tag 'jquery', 'jquery-ui.min.js' # =>
  <script src="/javascripts/jquery.js" type="text/javascript"></script>
  <script src="/javascripts/jquery-ui.min.js" type="text/javascript"></script>

javascript_include_tag '/js/facebox.js' # =>
  <script src="/js/facebox.js" type="text/javascript"></script>

javascript_include_tag 'http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js' # =>
  <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js" type="text/javascript"></script>


54
55
56
57
58
59
# File 'lib/sinatra/nice_easy_helpers.rb', line 54

def javascript_include_tag(*sources)
  sources.inject([]) { |tags, source|
    tags << tag(:script, '', {:src => compute_public_path(source, 'javascripts', 'js'), :type => 'text/javascript'})
    tags
  }.join("\n")
end

#label(*args) ⇒ Object

:call-seq:

label(field, options = {})
label(obj, field, options = {})

Creates a label tag for the specified field, which may be a field on an object. It will use the field name as the text for the label unless a :text option is provided.

label :email # =>
  <label for="email">Email</label>

label :email, :text => "Email Address:" # =>
  <label for="email">Email Address:</label>

label :user, :email # =>
  <label for="user_email">Email</label>


102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/sinatra/nice_easy_helpers.rb', line 102

def label(*args)
  obj, field, options = extract_options_and_field(*args)
  text = options.delete(:text)
  if text.blank?
    if String.method_defined?(:titleize)
      text = field.blank? ? obj.to_s.titleize : field.to_s.titleize
    else
      text = field.blank? ? obj.to_s : field.to_s
    end
  end
  tag :label, text, options.merge(:for => (field.blank? ? obj : "#{obj}_#{field}"))
end

Creates a link to a given URL with the given text as the link.

link "Check this out", '/path/to/something' # =>
  <a href="/path/to/something">Check this out</a>


18
19
20
# File 'lib/sinatra/nice_easy_helpers.rb', line 18

def link(content, href, options = {})
  tag :a, content, options.merge(:href => href)
end

#password_field(*args) ⇒ Object

:call-seq:

password_field(field, options = {})
password_field(obj, field, options = {})

Returns a password input for the specified field, which may be on an object. If there is a value for the field in the request params or an object is provided with that value set, it will auto-populate the input.

password_field :password # =>
  <input type="password" name="password" id="password" />

# Where the @params[:password] value is set already to "secret"
password_field :password # =>
  <input type="password" name="password" id="password" value="secret" />

password_field :user, :password # =>
  <input type="password" name="user[password]" id="user_password" />

@user = User.new(:password => 'secret')
password_field @user, :password # =>
  <input type="password" name="user[password]" id="user_password" value="secret" />


163
164
165
# File 'lib/sinatra/nice_easy_helpers.rb', line 163

def password_field(*args)
  input_tag 'password', *args
end

#radio_button(*args) ⇒ Object

:call-seq:

radio_button(field, options)
radio_button(obj, field, options)

Returns a radio button input for the specified field, which may be on an object. If there is a value for the field in the request params or an object is provided with that value set, it will mark this field as checked if it matches the value for the field.

radio_button :education, :value => 'college' # =>
  <input type="radio" name="education" id="education" value="college" />

# Where the @params[:education] value is set already to "college"
radio_button :education, :value => 'college # =>
  <input type="radio" name="education" id="education" value="college" checked="checked" />

radio_button :user, :education, :value => 'college' # =>
  <input type="radio" name="user[education]" id="user_education" value="college" />

@user = User.new(:education => 'college')
radio_button @user, :education, :value => 'college' # =>
  <input type="radio" name="user[education]" id="user_education" value="college" checked="checked" />


307
308
309
# File 'lib/sinatra/nice_easy_helpers.rb', line 307

def radio_button(*args)
  input_tag 'radio', *args
end

#select_field(*args) ⇒ Object

:call-seq:

select_field(field, choices, options = {})
select_field(obj, field, choices, options = {})

Creates a select tag for the specified field, which may be on an object. The helper also creates the options elements inside the select tag for each of the choices provided.

Given a choices container of an array of strings the strings will be used for the test and value of the options. Given a container where the elements respond to first and last (such as a two-element array), the “lasts” serve as option values and the “firsts” as option text. Hashes are turned into this form automatically, so the keys become “firsts” and values become lasts.

If there is a value for the field in the request params or an object is provided with that value set, it will auto-select that options from the choices.

select_field :membership_type, ['Lifetime', '1 Month', '1 Year'] # =>
  <select name="membership_type" id="membership_type">
    <option value="Lifetime">Lifetime</option>
    <option value="1 Month">1 Month</option>
    <option value="1 Year">1 Year</option>
  </select>

select_field :membership_type, [['Lifetime', 1], ['1 Month', 2], ['1 Year', 3]] # =>
  <select name="membership_type" id="membership_type">
    <option value="1">Lifetime</option>
    <option value="2">1 Month</option>
    <option value="3">1 Year</option>
  </select>

select_field :membership_type, {'Lifetime' => 1, '1 Month' => 2, '1 Year' => 3} # =>
  <select name="membership_type" id="membership_type">
    <option value="1">Lifetime</option>
    <option value="2">1 Month</option>
    <option value="3">1 Year</option>
  </select>

# Where the @params[:membership_type] value is set already to "year"
select_field :membership_type, {'Lifetime' => 'life', '1 Month' => 'month', '1 Year' => 'year'} # =>
  <select name="membership_type" id="membership_type">
    <option value="life">Lifetime</option>
    <option value="month">1 Month</option>
    <option value="year" selected="selected">1 Year</option>
  </select>

select_field :user, :membership_type, ['Lifetime', '1 Month', '1 Year'] # =>
  <select name="user[membership_type]" id="user_membership_type">
    <option value="Lifetime">Lifetime</option>
    <option value="1 Month">1 Month</option>
    <option value="1 Year">1 Year</option>
  </select>

@user = User.new(:membership_type => 'month')
select_field :user, :membership_type, {'Lifetime' => 'life', '1 Month' => 'month', '1 Year' => 'year'} # =>
  <select name="user[membership_type]" id="user_membership_type">
    <option value="life">Lifetime</option>
    <option value="month" selected="selected">1 Month</option>
    <option value="year">1 Year</option>
  </select>


372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
# File 'lib/sinatra/nice_easy_helpers.rb', line 372

def select_field(*args)
  case args.size
  when 2
    options = {}
    choices = args.pop
    obj = args.shift
    field = nil
  else
    options = args.extract_options!.symbolize_keys
    choices = args.pop
    obj = args.shift
    field = args.shift
  end
  
  unless choices.is_a? Enumerable
    raise ArgumentError, 'the choices parameter must be an Enumerable object'
  end
  
  value = get_value(obj, field)
  
  content = choices.inject([]) { |opts, choice|
    text, opt_val = option_text_and_value(choice)
    opts << tag(:option, escape_once(text), {:value => escape_once(opt_val), :selected => (opt_val == value)})
  }.join("\n")
  
  tag :select, "\n#{content}\n", options.merge(get_id_and_name(obj, field))
end

#single_tag(name, options = {}) ⇒ Object

Creates a self-closing/empty-element tag of the name specified.

single_tag :img, :src => "/images/face.jpg" # =>
  <img src="/images/face.jpg" />


440
441
442
# File 'lib/sinatra/nice_easy_helpers.rb', line 440

def single_tag(name, options = {})
  "<#{name.to_s}#{tag_options(options)} />"
end

:call-seq:

stylesheet_link_tag(*sources, options = {})

This helper is used to create a set of link tags for CSS stylesheets. If you just supply a relative filename (with or without the .css extension) it will assume it can be found in your public/javascripts directory. If you provide an absolute path it will use that. You can also pass attributes for the link tag in a hash as the last argument.

stylesheet_link_tag 'global' # =>
  <link href="/stylesheets/global.css" rel="stylesheet" type="text/css" media="screen" />

stylesheet_link_tag 'global' # =>
  <link href="/stylesheets/global.css" rel="stylesheet" type="text/css" media="screen" />


76
77
78
79
80
81
82
83
# File 'lib/sinatra/nice_easy_helpers.rb', line 76

def stylesheet_link_tag(*sources)
  options = sources.extract_options!.symbolize_keys
  sources.inject([]) { |tags, source|
    tags << single_tag(:link, {:href => compute_public_path(source, 'stylesheets', 'css'),
                               :type => 'text/css', :rel => 'stylesheet', :media => 'screen'}.merge(options))
    tags
  }.join("\n")
end

#submit(value = "Save", options = {}) ⇒ Object

Creates as submit input field with the text and options provided.

submit # =>
  <input type="submit" value="Save" />

submit 'Save and continue' # =>
  <input type="submit" value="Save and continue" />


253
254
255
# File 'lib/sinatra/nice_easy_helpers.rb', line 253

def submit(value = "Save", options = {})
  single_tag :input, options.merge(:type => "submit", :value => value)
end

#tag(name, content, options = {}) ⇒ Object

Creats a standard open and close tags for the name provided with the content and attributes supplied.

tag :h2, "Sinatra Steps to the Stage", :title => "Applause" # =>
  <h1 title="Applause">Sinatra Steps to the Stage</h1>


432
433
434
# File 'lib/sinatra/nice_easy_helpers.rb', line 432

def tag(name, content, options = {})
  "<#{name.to_s}#{tag_options(options)}>#{content}</#{name.to_s}>"
end

#text_area(*args) ⇒ Object

:call-seq:

text_area(field, options = {})
text_area(obj, field, options = {})

Returns a text area tag for the specified field, which may be on an object. If there is a value for the field in the request params or an object is provided with that value set, it will auto-populate the input.

text_area :description # =>
  <textarea name="description" id="description"></textarea>

# Where the @params[:description] value is set already to "A brand new book."
text_area :description # =>
  <textarea name="description" id="description">A brand new book.</textarea>

text_area :product, :description # =>
  <textarea name="product[description]" id="product_description"></textarea>

@product = Product.new(:description => 'A brand new book.')
text_area @product, :description # =>
  <textarea name="product[description]" id="product_description"></textarea>


230
231
232
233
234
# File 'lib/sinatra/nice_easy_helpers.rb', line 230

def text_area(*args)
  obj, field, options = extract_options_and_field(*args)
  value = get_value(obj, field)
  tag :textarea, value, options.merge(get_id_and_name(obj, field))
end

#text_field(*args) ⇒ Object

:call-seq:

text_field(field, options = {})
text_field(obj, field, options = {})

Returns a text input for the specified field, which may be on an object. If there is a value for the field in the request params or an object is provided with that value set, it will auto-populate the input.

text_field :email # =>
  <input type="text" name="email" id="email" />

# Where the @params[:email] value is set already to "[email protected]"
text_field :email # =>
  <input type="text" name="email" id="email" value="[email protected]" />

text_field :user, :email # =>
  <input type="text" name="user[email]" id="user_email" />

@user = User.new(:email => '[email protected]')
text_field @user, :email # =>
  <input type="text" name="user[email]" id="user_email" value="[email protected]" />


137
138
139
# File 'lib/sinatra/nice_easy_helpers.rb', line 137

def text_field(*args)
  input_tag 'text', *args
end