Module: ActionView::Helpers::TextHelper
- Defined in:
- lib/action_view/helpers/text_helper.rb
Overview
Provides a set of methods for working with text strings that can help unburden the level of inline Ruby code in the templates. In the example below we iterate over a collection of posts provided to the template and print each title after making sure it doesn’t run longer than 20 characters:
<% for post in @posts %>
Title: <%= truncate(post.title, 20) %>
<% end %>
Defined Under Namespace
Classes: Cycle
Constant Summary collapse
- VERBOTEN_TAGS =
%w(form script)
- VERBOTEN_ATTRS =
/^on/i
- AUTO_LINK_RE =
/ ( # leading text <\w+.*?>| # leading HTML tag, or [^=!:'"\/]| # leading punctuation, or ^ # beginning of line ) ( (?:http[s]?:\/\/)| # protocol spec, or (?:www\.) # www.* ) ( ([\w]+[=?&\/.-]?)* # url segment \w+[\/]? # url tail (?:\#\w*)? # trailing anchor ) ([[:punct:]]|\s|<|$) # trailing text /x
Instance Method Summary collapse
-
#auto_link(text, link = :all, href_options = {}, &block) ⇒ Object
Turns all urls and email addresses into clickable links.
-
#concat(string, binding) ⇒ Object
The regular puts and print are outlawed in eRuby.
-
#cycle(first_value, *values) ⇒ Object
Returns a Cycle object whose to_s value cycles through items of an array every time it is called.
-
#excerpt(text, phrase, radius = 100, excerpt_string = "...") ⇒ Object
Extracts an excerpt from the
text
surrounding thephrase
with a number of characters on each side determined byradius
. -
#highlight(text, phrase, highlighter = '<strong class="highlight">\1</strong>') ⇒ Object
Highlights the
phrase
where it is found in thetext
by surrounding it like <strong class=“highlight”>I’m a highlight phrase</strong>. -
#pluralize(count, singular, plural = nil) ⇒ Object
Attempts to pluralize the
singular
word unlesscount
is 1. -
#reset_cycle(name = "default") ⇒ Object
Resets a cycle so that it starts from the first element in the array the next time it is used.
-
#sanitize(html) ⇒ Object
Sanitizes the given HTML by making form and script tags into regular text, and removing all “onxxx” attributes (so that arbitrary Javascript cannot be executed).
-
#simple_format(text) ⇒ Object
Returns
text
transformed into HTML using very simple formatting rules Surrounds paragraphs with<p>
tags, and converts line breaks into<br />
Two consecutive newlines(\n\n
) are considered as a paragraph, one newline (\n
) is considered a linebreak, three or more consecutive newlines are turned into two newlines. -
#strip_links(text) ⇒ Object
Turns all links into words, like “<a href=”something“>else</a>” to “else”.
-
#strip_tags(html) ⇒ Object
Strips all HTML tags from the input, including comments.
-
#truncate(text, length = 30, truncate_string = "...") ⇒ Object
Truncates
text
to the length oflength
and replaces the last three characters with thetruncate_string
if thetext
is longer thanlength
. -
#word_wrap(text, line_width = 80) ⇒ Object
Word wrap long lines to line_width.
Instance Method Details
#auto_link(text, link = :all, href_options = {}, &block) ⇒ Object
Turns all urls and email addresses into clickable links. The link
parameter can limit what should be linked. Options are :all (default), :email_addresses, and :urls.
Example:
auto_link("Go to http://www.rubyonrails.com and say hello to [email protected]") =>
Go to <a href="http://www.rubyonrails.com">http://www.rubyonrails.com</a> and
say hello to <a href="mailto:[email protected]">[email protected]</a>
If a block is given, each url and email address is yielded and the result is used as the link text. Example:
auto_link(post.body, :all, :target => '_blank') do |text|
truncate(text, 15)
end
144 145 146 147 148 149 150 |
# File 'lib/action_view/helpers/text_helper.rb', line 144 def auto_link(text, link = :all, = {}, &block) case link when :all then auto_link_urls(auto_link_email_addresses(text, &block), , &block) when :email_addresses then auto_link_email_addresses(text, &block) when :urls then auto_link_urls(text, , &block) end end |
#concat(string, binding) ⇒ Object
The regular puts and print are outlawed in eRuby. It’s recommended to use the <%= “hello” %> form instead of print “hello”. If you absolutely must use a method-based output, you can use concat. It’s used like this: <% concat “hello”, binding %>. Notice that it doesn’t have an equal sign in front. Using <%= concat “hello” %> would result in a double hello.
15 16 17 |
# File 'lib/action_view/helpers/text_helper.rb', line 15 def concat(string, binding) eval("_erbout", binding).concat(string) end |
#cycle(first_value, *values) ⇒ Object
Returns a Cycle object whose to_s value cycles through items of an array every time it is called. This can be used to alternate classes for table rows:
<%- for item in @items do -%>
<tr class="<%= cycle("even", "odd") %>">
... use item ...
</tr>
<%- end -%>
You can use named cycles to prevent clashes in nested loops. You’ll have to reset the inner cycle, manually:
<%- for item in @items do -%>
<tr class="<%= cycle("even", "odd", :name => "row_class")
<td>
<%- for value in item.values do -%>
<span style="color:'<%= cycle("red", "green", "blue"
:name => "colors") %>'">
item
</span>
<%- end -%>
<%- reset_cycle("colors") -%>
</td>
</tr>
<%- end -%>
259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 |
# File 'lib/action_view/helpers/text_helper.rb', line 259 def cycle(first_value, *values) if (values.last.instance_of? Hash) params = values.pop name = params[:name] else name = "default" end values.unshift(first_value) cycle = get_cycle(name) if (cycle.nil? || cycle.values != values) cycle = set_cycle(name, Cycle.new(*values)) end return cycle.to_s end |
#excerpt(text, phrase, radius = 100, excerpt_string = "...") ⇒ Object
Extracts an excerpt from the text
surrounding the phrase
with a number of characters on each side determined by radius
. If the phrase isn’t found, nil is returned. Ex:
excerpt("hello my world", "my", 3) => "...lo my wo..."
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/action_view/helpers/text_helper.rb', line 44 def excerpt(text, phrase, radius = 100, excerpt_string = "...") if text.nil? || phrase.nil? then return end phrase = Regexp.escape(phrase) if found_pos = text =~ /(#{phrase})/i start_pos = [ found_pos - radius, 0 ].max end_pos = [ found_pos + phrase.length + radius, text.length ].min prefix = start_pos > 0 ? excerpt_string : "" postfix = end_pos < text.length ? excerpt_string : "" prefix + text[start_pos..end_pos].strip + postfix else nil end end |
#highlight(text, phrase, highlighter = '<strong class="highlight">\1</strong>') ⇒ Object
Highlights the phrase
where it is found in the text
by surrounding it like <strong class=“highlight”>I’m a highlight phrase</strong>. The highlighter can be specialized by passing highlighter
as single-quoted string with 1 where the phrase is supposed to be inserted. N.B.: The phrase
is sanitized to include only letters, digits, and spaces before use.
36 37 38 39 |
# File 'lib/action_view/helpers/text_helper.rb', line 36 def highlight(text, phrase, highlighter = '<strong class="highlight">\1</strong>') if phrase.blank? then return text end text.gsub(/(#{Regexp.escape(phrase)})/i, highlighter) unless text.nil? end |
#pluralize(count, singular, plural = nil) ⇒ Object
Attempts to pluralize the singular
word unless count
is 1. See source for pluralization rules.
62 63 64 65 66 67 68 69 70 71 72 |
# File 'lib/action_view/helpers/text_helper.rb', line 62 def pluralize(count, singular, plural = nil) "#{count} " + if count == 1 singular elsif plural plural elsif Object.const_defined?("Inflector") Inflector.pluralize(singular) else singular + "s" end end |
#reset_cycle(name = "default") ⇒ Object
Resets a cycle so that it starts from the first element in the array the next time it is used.
277 278 279 280 281 |
# File 'lib/action_view/helpers/text_helper.rb', line 277 def reset_cycle(name = "default") cycle = get_cycle(name) return if cycle.nil? cycle.reset end |
#sanitize(html) ⇒ Object
Sanitizes the given HTML by making form and script tags into regular text, and removing all “onxxx” attributes (so that arbitrary Javascript cannot be executed). Also removes href attributes that start with “javascript:”.
Returns the sanitized text.
179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 |
# File 'lib/action_view/helpers/text_helper.rb', line 179 def sanitize(html) # only do this if absolutely necessary if html.index("<") tokenizer = HTML::Tokenizer.new(html) new_text = "" while token = tokenizer.next node = HTML::Node.parse(nil, 0, 0, token, false) new_text << case node when HTML::Tag if VERBOTEN_TAGS.include?(node.name) node.to_s.gsub(/</, "<") else if node.closing != :close node.attributes.delete_if { |attr,v| attr =~ VERBOTEN_ATTRS } if node.attributes["href"] =~ /^javascript:/i node.attributes.delete "href" end end node.to_s end else node.to_s.gsub(/</, "<") end end html = new_text end html end |
#simple_format(text) ⇒ Object
Returns text
transformed into HTML using very simple formatting rules Surrounds paragraphs with <p>
tags, and converts line breaks into <br />
Two consecutive newlines(\n\n
) are considered as a paragraph, one newline (\n
) is considered a linebreak, three or more consecutive newlines are turned into two newlines
122 123 124 125 126 127 128 129 |
# File 'lib/action_view/helpers/text_helper.rb', line 122 def simple_format(text) text.gsub!(/(\r\n|\n|\r)/, "\n") # lets make them newlines crossplatform text.gsub!(/\n\n+/, "\n\n") # zap dupes text.gsub!(/\n\n/, '</p>\0<p>') # turn two newlines into paragraph text.gsub!(/([^\n])(\n)([^\n])/, '\1\2<br />\3') # turn single newline into <br /> content_tag("p", text) end |
#strip_links(text) ⇒ Object
Turns all links into words, like “<a href=”something“>else</a>” to “else”.
153 154 155 |
# File 'lib/action_view/helpers/text_helper.rb', line 153 def strip_links(text) text.gsub(/<a.*>(.*)<\/a>/m, '\1') end |
#strip_tags(html) ⇒ Object
Strips all HTML tags from the input, including comments. This uses the html-scanner tokenizer and so it’s HTML parsing ability is limited by that of html-scanner.
Returns the tag free text.
215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 |
# File 'lib/action_view/helpers/text_helper.rb', line 215 def (html) if html.index("<") text = "" tokenizer = HTML::Tokenizer.new(html) while token = tokenizer.next node = HTML::Node.parse(nil, 0, 0, token, false) # result is only the content of any Text nodes text << node.to_s if node.class == HTML::Text end # strip any comments, and if they have a newline at the end (ie. line with # only a comment) strip that too text.gsub(/<!--(.*?)-->[\n]?/m, "") else html # already plain text end end |
#truncate(text, length = 30, truncate_string = "...") ⇒ Object
Truncates text
to the length of length
and replaces the last three characters with the truncate_string
if the text
is longer than length
.
21 22 23 24 25 26 27 28 29 30 |
# File 'lib/action_view/helpers/text_helper.rb', line 21 def truncate(text, length = 30, truncate_string = "...") if text.nil? then return end if $KCODE == "NONE" text.length > length ? text[0..(length - 3)] + truncate_string : text else chars = text.split(//) chars.length > length ? chars[0..(length-3)].join + truncate_string : text end end |
#word_wrap(text, line_width = 80) ⇒ Object
Word wrap long lines to line_width.
75 76 77 |
# File 'lib/action_view/helpers/text_helper.rb', line 75 def word_wrap(text, line_width = 80) text.gsub(/\n/, "\n\n").gsub(/(.{1,#{line_width}})(\s+|$)/, "\\1\n").strip end |