aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib/action_view/helpers/text_helper.rb
diff options
context:
space:
mode:
Diffstat (limited to 'actionpack/lib/action_view/helpers/text_helper.rb')
-rw-r--r--actionpack/lib/action_view/helpers/text_helper.rb97
1 files changed, 44 insertions, 53 deletions
diff --git a/actionpack/lib/action_view/helpers/text_helper.rb b/actionpack/lib/action_view/helpers/text_helper.rb
index fae1e44a8f..0cc0d069ea 100644
--- a/actionpack/lib/action_view/helpers/text_helper.rb
+++ b/actionpack/lib/action_view/helpers/text_helper.rb
@@ -62,9 +62,11 @@ module ActionView
#
# Pass a <tt>:separator</tt> to truncate +text+ at a natural break.
#
- # The result is not marked as HTML-safe, so will be subject to the default escaping when
- # used in views, unless wrapped by <tt>raw()</tt>. Care should be taken if +text+ contains HTML tags
- # or entities, because truncation may produce invalid HTML (such as unbalanced or incomplete tags).
+ # Pass a block if you want to show extra content when the text is truncated.
+ #
+ # The result is marked as HTML-safe, but it is escaped by default, unless <tt>:escape</tt> is
+ # +false+. Care should be taken if +text+ contains HTML tags or entities, because truncation
+ # may produce invalid HTML (such as unbalanced or incomplete tags).
#
# truncate("Once upon a time in a world far far away")
# # => "Once upon a time in a world..."
@@ -80,9 +82,18 @@ module ActionView
#
# truncate("<p>Once upon a time in a world far far away</p>")
# # => "<p>Once upon a time in a wo..."
- def truncate(text, options = {})
- options.reverse_merge!(:length => 30)
- text.truncate(options.delete(:length), options) if text
+ #
+ # truncate("Once upon a time in a world far far away") { link_to "Continue", "#" }
+ # # => "Once upon a time in a wo...<a href="#">Continue</a>"
+ def truncate(text, options = {}, &block)
+ if text
+ length = options.fetch(:length, 30)
+
+ content = text.truncate(length, options)
+ content = options[:escape] == false ? content.html_safe : ERB::Util.html_escape(content)
+ content << capture(&block) if block_given? && text.length > length
+ content
+ end
end
# Highlights one or more +phrases+ everywhere in +text+ by inserting it into
@@ -101,25 +112,15 @@ module ActionView
#
# highlight('You searched for: rails', 'rails', :highlighter => '<a href="search?q=\1">\1</a>')
# # => You searched for: <a href="search?q=rails">rails</a>
- #
- # You can still use <tt>highlight</tt> with the old API that accepts the
- # +highlighter+ as its optional third parameter:
- #
- # highlight('You searched for: rails', 'rails', '<a href="search?q=\1">\1</a>')
- # # => You searched for: <a href="search?q=rails">rails</a>
- def highlight(text, phrases, *args)
- options = args.extract_options!
- unless args.empty?
- options[:highlighter] = args[0]
- end
- options[:highlighter] ||= '<mark>\1</mark>'
+ def highlight(text, phrases, options = {})
+ highlighter = options.fetch(:highlighter, '<mark>\1</mark>')
- text = sanitize(text) unless options[:sanitize] == false
+ text = sanitize(text) if options.fetch(:sanitize, true)
if text.blank? || phrases.blank?
text
else
match = Array(phrases).map { |p| Regexp.escape(p) }.join('|')
- text.gsub(/(#{match})(?![^<]*?>)/i, options[:highlighter])
+ text.gsub(/(#{match})(?![^<]*?>)/i, highlighter)
end.html_safe
end
@@ -143,22 +144,10 @@ module ActionView
#
# excerpt('This is also an example', 'an', :radius => 8, :omission => '<chop> ')
# # => <chop> is also an example
- #
- # You can still use <tt>excerpt</tt> with the old API that accepts the
- # +radius+ as its optional third and the +ellipsis+ as its
- # optional forth parameter:
- # excerpt('This is an example', 'an', 5) # => ...s is an exam...
- # excerpt('This is also an example', 'an', 8, '<chop> ') # => <chop> is also an example
- def excerpt(text, phrase, *args)
+ def excerpt(text, phrase, options = {})
return unless text && phrase
-
- options = args.extract_options!
- unless args.empty?
- options[:radius] = args[0]
- options[:omission] = args[1]
- end
- radius = options[:radius] || 100
- omission = options[:omission] || "..."
+ radius = options.fetch(:radius, 100)
+ omission = options.fetch(:omission, "...")
phrase = Regexp.escape(phrase)
return unless found_pos = text =~ /(#{phrase})/i
@@ -174,7 +163,7 @@ module ActionView
# Attempts to pluralize the +singular+ word unless +count+ is 1. If
# +plural+ is supplied, it will use that when count is > 1, otherwise
- # it will use the Inflector to determine the plural form
+ # it will use the Inflector to determine the plural form.
#
# pluralize(1, 'person')
# # => 1 person
@@ -188,7 +177,13 @@ module ActionView
# pluralize(0, 'person')
# # => 0 people
def pluralize(count, singular, plural = nil)
- "#{count || 0} " + ((count == 1 || count =~ /^1(\.0+)?$/) ? singular : (plural || singular.pluralize))
+ word = if (count == 1 || count =~ /^1(\.0+)?$/)
+ singular
+ else
+ plural || singular.pluralize
+ end
+
+ "#{count || 0} #{word}"
end
# Wraps the +text+ into lines no longer than +line_width+ width. This method
@@ -199,23 +194,15 @@ module ActionView
# # => Once upon a time
#
# word_wrap('Once upon a time, in a kingdom called Far Far Away, a king fell ill, and finding a successor to the throne turned out to be more trouble than anyone could have imagined...')
- # # => Once upon a time, in a kingdom called Far Far Away, a king fell ill, and finding\n a successor to the throne turned out to be more trouble than anyone could have\n imagined...
+ # # => Once upon a time, in a kingdom called Far Far Away, a king fell ill, and finding\na successor to the throne turned out to be more trouble than anyone could have\nimagined...
#
# word_wrap('Once upon a time', :line_width => 8)
- # # => Once upon\na time
+ # # => Once\nupon a\ntime
#
# word_wrap('Once upon a time', :line_width => 1)
# # => Once\nupon\na\ntime
- #
- # You can still use <tt>word_wrap</tt> with the old API that accepts the
- # +line_width+ as its optional second parameter:
- # word_wrap('Once upon a time', 8) # => Once upon\na time
- def word_wrap(text, *args)
- options = args.extract_options!
- unless args.blank?
- options[:line_width] = args[0]
- end
- line_width = options[:line_width] || 80
+ def word_wrap(text, options = {})
+ line_width = options.fetch(:line_width, 80)
text.split("\n").collect do |line|
line.length > line_width ? line.gsub(/(.{1,#{line_width}})(\s+|$)/, "\\1\n").strip : line
@@ -233,7 +220,7 @@ module ActionView
#
# ==== Options
# * <tt>:sanitize</tt> - If +false+, does not sanitize +text+.
- # * <tt>:wrapper_tag</tt> - String representing the tag wrapper, defaults to <tt>"p"</tt>
+ # * <tt>:wrapper_tag</tt> - String representing the wrapper tag, defaults to <tt>"p"</tt>
#
# ==== Examples
# my_text = "Here is some basic text...\n...with a line break."
@@ -241,6 +228,9 @@ module ActionView
# simple_format(my_text)
# # => "<p>Here is some basic text...\n<br />...with a line break.</p>"
#
+ # simple_format(my_text, {}, :wrapper_tag => "div")
+ # # => "<div>Here is some basic text...\n<br />...with a line break.</div>"
+ #
# more_text = "We want to put a paragraph...\n\n...right there."
#
# simple_format(more_text)
@@ -251,9 +241,10 @@ module ActionView
#
# simple_format("<span>I'm allowed!</span> It's true.", {}, :sanitize => false)
# # => "<p><span>I'm allowed!</span> It's true.</p>"
- def simple_format(text, html_options={}, options={})
- text = sanitize(text) unless options[:sanitize] == false
+ def simple_format(text, html_options = {}, options = {})
wrapper_tag = options.fetch(:wrapper_tag, :p)
+
+ text = sanitize(text) if options.fetch(:sanitize, true)
paragraphs = split_paragraphs(text)
if paragraphs.empty?
@@ -304,7 +295,7 @@ module ActionView
# <% end %>
def cycle(first_value, *values)
options = values.extract_options!
- name = options.fetch(:name, "default")
+ name = options.fetch(:name, 'default')
values.unshift(first_value)