create custom html helpers in ruby on rails
To create a new helper:
- choose a name for the helper file, for instance tags_helper.rb
- create the file in the /app/helpers directory
create a module according to the file name. In this case
module TagsHelper
enddefine your helper as method
module TagsHelper
def hello_world(name)
"hello #{name}"
end
end
Now you can use the hello_world
helper method in your view.
Helpers in Rails - What's the best approach when building the html string?
If html is longer than 1 line, i usually put the html in a partial and call it with a custom helper method
view
<= display_my_html(@item, {html_class: "active"}) %>
helper
def display_my_html(item, opts={})
name = item.name.upcase
html_class = opts.key?(:html_class) ? opts[:html_class] : "normal"
render "my_html", name: name, html_class: html_class
end
partial
<div class="<%= html_class %>">
<span class="user">
<%= name %>
</span>
</div>
Custom HTML attribute requires a custom helper?
Oops. It's just
<%= f.text_field :question, :id=>"poll_question", :class=>"BigInput", :style=>"width:98%;", 'data-submit_clear'=>'1' %>
Restrict title display to admin users - custom html helper
I had to create a helper to check for admin users:
def admin?
# check if this user is an admin
end
Then I had to create a custom helper which returns a title for an admin user:
def generate_title(this)
if admin?
"id:#{this}"
end
end
And finally update my cell to use the custom helper:
<td title="<%= generate_title(alert.id) %>">Hello</td>
Its all about the custom helpers!
Ruby on Rails Custom Helper outputting HTML nested list
If you want to stick with helpers, then something like this could help:
def present_search_results(results)
content_tag(:ul, class: "websites-list") do
results.map do |website_id, bookmarks|
bookmarks = [bookmarks] unless bookmarks.is_a?(Array)
content_tag(:li, class: "website-#{website_id}") do
website = Website.find(website_id)
concat(website.url)
concat(
content_tag(:ul, class: "bookmarks-list") do
bookmarks.map do |bookmark_id|
bookmark = Bookmark.find(bookmark_id)
content_tag(:li, bookmark.title)
end.reduce(:+)
end
)
end
end.reduce(:+)
end
end
But, in my opinion, that code is not easy to read, so you could use plain html
instead, like this:
def present_search_results(results)
list = "<ul class='websites-list'>"
results.each do |(website_id, bookmarks)|
bookmarks = [bookmarks] unless bookmarks.is_a?(Array)
website = Website.find(website_id)
list += "<li class='website-#{website_id}'>#{website}"
list += "<ul class='bookmarks-list'>"
bookmarks.each do |bookmark_id|
bookmark = Bookmark.find(bookmark_id)
list += "<li>#{bookmark.title}</li>"
end
list += "</ul></li>"
end
list += "</ul>"
list.html_safe
end
I like this one better, since it is easier to read. But both with output the list you want.
Create a helper or something for haml with ruby on rails
You can use haml_tag too
def content_box
haml_tag :div, :class => "holder" do
haml_tag :div, :class => "top"
haml_tag :div, :class => "content" do
yield
haml_tag :div, :class => "bottom"
end
end
and in haml
%html
%head
%body
Maybee some content here.
= content_box do
Content that goes in the content_box like news or stuff
Custom form helpers
Yes, you can add to the FormBuilder class and get access to the object passed into the form_for. I've done this for a lot of things: dates, times, measurements, etc. Heres an example:
class ActionView::Helpers::FormBuilder
include ActionView::Helpers::TagHelper
include ActionView::Helpers::FormTagHelper
include ActionView::Helpers::FormOptionsHelper
include ActionView::Helpers::CaptureHelper
include ActionView::Helpers::AssetTagHelper
# Accepts an int and displays a smiley based on >, <, or = 0
def smile_tag(method, options = {})
value = @object.nil? ? 0 : @object.send(method).to_i
options[:id] = field_id(method,options[:index])
smiley = ":-|"
if value > 0
smiley = ":-)"
elsif smiley < 0
smiley = ":-("
end
return text_field_tag(field_name(method,options[:index]),options) + smiley
end
def field_name(label,index=nil)
output = index ? "[#{index}]" : ''
return @object_name + output + "[#{label}]"
end
def field_id(label,index=nil)
output = index ? "_#{index}" : ''
return @object_name + output + "_#{label}"
end
end
Which you can use like this:
<% form_for @quiz do |f| %>
<%= f.smile_tag(:score) %>
<% end %>
There are some instance variables created by Rails that you can access in these helper methods:
- @object - the model object specified by the form
- @object_name - the class name of the object
- @template - I think its an instance of the ActionView, you can possibly bypass all the includes I added by calling methods on the template. Haven't tried that yet.
- @options - options passed to the FormBuilder when its created by the form_for call
I wrote the field_id and field_name methods to create these attributes on the HTML input elements the same way the regular helpers do, I'm sure there is a way to tie into the same methods that Rails uses, but I haven't found it yet.
The sky is the limit on what you can do with these helper methods, they simply return strings. You can create entire HTML tables or pages in one, but you better have a good reason to.
This file should be added in the app/helpers folder
Rails: understanding custom form helper
form.radio_button
helper returns a string and I18n.t
too returns a string. So, you can concatenate them.
More details how form tag is generated
This is a code of radio_button
:
https://github.com/casunlight/rails/blob/master/actionview/lib/action_view/helpers/form_helper.rb
def radio_button(object_name, method, tag_value, options = {})
Tags::RadioButton.new(object_name, method, self, tag_value, options).render
end
Look at implementation of render method
https://github.com/casunlight/rails/blob/master/actionview/lib/action_view/helpers/tags/radio_button.rb#L20
def render
options = @options.stringify_keys
options["type"] = "radio"
options["value"] = @tag_value
options["checked"] = "checked" if input_checked?(object, options)
add_default_name_and_id_for_value(@tag_value, options)
tag("input", options)
end
Tag helper generate html tag and return his as html safed string:
https://github.com/casunlight/rails/blob/master/actionview/lib/action_view/helpers/tag_helper.rb#L67
def tag(name, options = nil, open = false, escape = true)
"<#{name}#{tag_options(options, escape) if options}#{open ? ">" : " />"}".html_safe
end
Rails: Best practice to generate custom HTML in Model?
I would do the following
def embed_element(external_video)
content_tag(:embed, '', :src => external_video.video_source)
end
You should probably check the docs for more information on the content tag method.
Also note that the content_tag() method will insert a closing tag. Something you seem to be forgetting...
Related Topics
Ruby (And Rails) Nested Module Syntax
Ruby Block to String Instead of Executing
Ruby Array to JSON and Rails JSON Rendering
What Does "||=" Do in Ruby 1.9.2
How to Create Symbol (Hash Key) from Association, Using New Ruby (1.9) Hash Syntax
Installing Postgresql on Ubuntu for Ruby on Rails
Ruby: What Is the Easiest Method to Update Hash Values
Storing Arrays in Database Using Activerecord
Rails Put Validation in a Module Mixin
Test Output to Command Line with Rspec
Has Anyone Successfully Deployed a Rails Project with Ruby 1.9.1
Problems Setting a Custom Primary Key in a Rails 4 Migration
Getting Openssl::X509::Certificateerror Nested Asn1 Error on Ruby