Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

refactor i18n and `page_entries_info` helper

  • Loading branch information...
commit 52056eedac7f87e6f28f739d3c0faf220f75ba38 1 parent a82b59e
@mislav authored
View
46 lib/will_paginate/locale/en.yml
@@ -1,19 +1,33 @@
en:
- views:
- will_paginate:
- previous_label: "← Previous"
- next_label: "Next →"
- page_gap: "…"
+ will_paginate:
+ previous_label: "← Previous"
+ next_label: "Next →"
+ page_gap: "…"
- page_entries_info:
- single_page:
- zero: "No %{plural} found"
- one: "Displaying 1 %{name}"
- other: "Displaying all %{count} %{plural}"
- single_page_html:
- zero: "No %{plural} found"
- one: "Displaying <b>1</b> %{name}"
- other: "Displaying <b>all&nbsp;%{count}</b> %{plural}"
+ page_entries_info:
+ single_page:
+ zero: "No %{model} found"
+ one: "Displaying 1 %{model}"
+ other: "Displaying all %{count} %{model}"
+ single_page_html:
+ zero: "No %{model} found"
+ one: "Displaying <b>1</b> %{model}"
+ other: "Displaying <b>all&nbsp;%{count}</b> %{model}"
- multi_page: "Displaying %{plural} %{from} - %{to} of %{total} in total"
- multi_page_html: "Displaying %{plural} <b class='range'>%{from}&nbsp;-&nbsp;%{to}</b> of <b class='total'>%{total}</b> in total"
+ multi_page: "Displaying %{model} %{from} - %{to} of %{count} in total"
+ multi_page_html: "Displaying %{model} <b>%{from}&nbsp;-&nbsp;%{to}</b> of <b>%{count}</b> in total"
+
+ # models:
+ # entry:
+ # zero: entries
+ # one: entry
+ # few: entries
+ # other: entries
+
+ # line_item:
+ # page_entries_info:
+ # single_page:
+ # zero: "Your shopping cart is empty"
+ # one: "Displaying one item in your cart"
+ # other: "Displaying all %{count} items"
+ # multi_page: "Displaying items %{from} - %{to} of %{count} in total"
View
104 lib/will_paginate/view_helpers.rb
@@ -67,9 +67,8 @@ def will_paginate(collection, options = {})
options = WillPaginate::ViewHelpers.pagination_options.merge(options)
- scope = 'views.will_paginate'
- options[:previous_label] ||= will_paginate_translate(:previous_label, :scope => scope) { '&#8592; Previous' }
- options[:next_label] ||= will_paginate_translate(:next_label, :scope => scope) { 'Next &#8594;' }
+ options[:previous_label] ||= will_paginate_translate(:previous_label) { '&#8592; Previous' }
+ options[:next_label] ||= will_paginate_translate(:next_label) { 'Next &#8594;' }
# get the renderer instance
renderer = case options[:renderer]
@@ -88,74 +87,73 @@ def will_paginate(collection, options = {})
renderer.to_html
end
- # Renders a helpful message with numbers of displayed vs. total entries.
- # You can use this as a blueprint for your own, similar helpers.
+ # Renders a message containing number of displayed vs. total entries.
#
# <%= page_entries_info @posts %>
- # #-> Displaying posts 6 - 10 of 26 in total
+ # #-> Displaying posts 6 - 12 of 26 in total
#
- # By default, the message will use the humanized class name of objects
- # in collection: for instance, "project types" for ProjectType models.
- # Override this with the <tt>:entry_name</tt> parameter:
- #
- # <%= page_entries_info @posts, :entry_name => 'item' %>
- # #-> Displaying items 6 - 10 of 26 in total
- #
- # Entry name is entered in singular and pluralized with
- # <tt>String#pluralize</tt> method from ActiveSupport. If it isn't
- # loaded, specify plural with <tt>:plural_name</tt> parameter:
- #
- # <%= page_entries_info @posts, :entry_name => 'item', :plural_name => 'items' %>
- #
- # By default, this method produces HTML output. You can trigger plain
- # text output by passing <tt>:html => false</tt> in options.
+ # The default output contains HTML. Use ":html => false" for plain text.
def page_entries_info(collection, options = {})
- entry_name = options[:entry_name] || (collection.empty?? 'entry' :
- collection.first.class.name.underscore.gsub('_', ' '))
-
- plural_name = if options[:plural_name]
- options[:plural_name]
- elsif entry_name == 'entry'
- plural_name = 'entries'
- elsif entry_name.respond_to? :pluralize
- plural_name = entry_name.pluralize
- else
- raise ArgumentError, "must provide :plural_name for #{entry_name.inspect}"
- end
+ html = options[:html] != false
+ model = options[:model]
+ model = collection.first.class unless model or collection.empty?
+ model ||= 'entry'
+ model_key = if model.respond_to? :model_name
+ model.model_name.i18n_key # ActiveModel::Naming
+ else
+ model.to_s.underscore
+ end
- unless options[:html] == false
- b = '<b>'
- eb = '</b>'
+ if html
+ b, eb = '<b>', '</b>'
sp = '&nbsp;'
- key = '_html'
+ html_key = '_html'
else
- b = eb = key = ''
+ b = eb = html_key = ''
sp = ' '
end
- scope = 'views.will_paginate.page_entries_info'
+ model_count = collection.total_pages > 1 ? 5 : collection.size
+ model_name = will_paginate_translate "models.#{model_key}", :count => model_count do |_, opts|
+ if model.respond_to? :model_name
+ model.model_name.human(:count => opts[:count])
+ else
+ name = model_key.to_s.tr('_', ' ')
+ raise "can't pluralize model name: #{model.inspect}" unless name.respond_to? :pluralize
+ opts[:count] == 1 ? name : name.pluralize
+ end
+ end
if collection.total_pages < 2
- will_paginate_translate "single_page#{key}", :scope => scope, :count => collection.size,
- :name => entry_name, :plural => plural_name do |_, opts|
- case opts[:count]
- when 0; "No #{opts[:plural]} found"
- when 1; "Displaying #{b}1#{eb} #{opts[:name]}"
- else "Displaying #{b}all #{opts[:count]}#{eb} #{opts[:plural]}"
- end
+ i18n_key = :"page_entries_info.single_page#{html_key}"
+ keys = [:"#{model_key}.#{i18n_key}", i18n_key]
+
+ will_paginate_translate keys, :count => collection.size, :model => model_name do |_, opts|
+ case opts[:count]
+ when 0; "No #{opts[:model]} found"
+ when 1; "Displaying #{b}1#{eb} #{opts[:model]}"
+ else "Displaying #{b}all #{opts[:count]}#{eb} #{opts[:model]}"
end
+ end
else
- will_paginate_translate "multi_page#{key}", :scope => scope, :total => collection.total_entries, :plural => plural_name,
- :from => collection.offset + 1, :to => collection.offset + collection.length do |_, opts|
- %{Displaying %s #{b}%d#{sp}-#{sp}%d#{eb} of #{b}%d#{eb} in total} %
- [ opts[:plural], opts[:from], opts[:to], opts[:total] ]
- end
+ i18n_key = :"page_entries_info.multi_page#{html_key}"
+ keys = [:"#{model_key}.#{i18n_key}", i18n_key]
+ params = {
+ :model => model_name, :count => collection.total_entries,
+ :from => collection.offset + 1, :to => collection.offset + collection.length
+ }
+ will_paginate_translate keys, params do |_, opts|
+ %{Displaying %s #{b}%d#{sp}-#{sp}%d#{eb} of #{b}%d#{eb} in total} %
+ [ opts[:model], opts[:from], opts[:to], opts[:count] ]
+ end
end
end
- def will_paginate_translate(key, options = {})
+ def will_paginate_translate(keys, options = {})
if defined? ::I18n
- ::I18n.translate(key, options.merge(:default => Proc.new))
+ defaults = Array(keys).dup
+ defaults << Proc.new if block_given?
+ ::I18n.translate(defaults.shift, options.merge(:default => defaults, :scope => :will_paginate))
else
yield key, options
end
View
11 lib/will_paginate/view_helpers/action_view.rb
@@ -71,8 +71,15 @@ def paginated_section(*args, &block)
end
end
- def will_paginate_translate(key, options = {})
- translate(key, options)
+ def will_paginate_translate(keys, options = {})
+ if Array === keys
+ defaults = keys.dup
+ key = defaults.shift
+ else
+ defaults = nil
+ key = keys
+ end
+ translate(key, options.merge(:default => defaults, :scope => :will_paginate))
end
protected
View
53 spec/view_helpers/base_spec.rb
@@ -2,12 +2,17 @@
require 'will_paginate/view_helpers'
require 'will_paginate/array'
require 'active_support'
+require 'active_support/core_ext/string/inflections'
+require 'active_support/inflections'
describe WillPaginate::ViewHelpers do
before(:all) do
# make sure default translations aren't loaded
I18n.load_path.clear
+ end
+
+ before(:each) do
I18n.reload!
end
@@ -35,17 +40,31 @@
end
def info(params, options = {})
- options[:html] ||= false unless options.key?(:html) and options[:html].nil?
collection = Hash === params ? @array.paginate(params) : params
- page_entries_info collection, options
+ page_entries_info collection, {:html => false}.merge(options)
end
it "should display middle results and total count" do
info(:page => 2, :per_page => 5).should == "Displaying strings 6 - 10 of 26 in total"
end
+ it "uses translation if available" do
+ translation :will_paginate => {
+ :page_entries_info => {:multi_page => 'Showing %{from} - %{to}'}
+ }
+ info(:page => 2, :per_page => 5).should == "Showing 6 - 10"
+ end
+
+ it "uses specific translation if available" do
+ translation :will_paginate => {
+ :page_entries_info => {:multi_page => 'Showing %{from} - %{to}'},
+ :string => { :page_entries_info => {:multi_page => 'Strings %{from} to %{to}'} }
+ }
+ info(:page => 2, :per_page => 5).should == "Strings 6 to 10"
+ end
+
it "should output HTML by default" do
- info({ :page => 2, :per_page => 5 }, :html => nil).should ==
+ info({ :page => 2, :per_page => 5 }, :html => true).should ==
"Displaying strings <b>6&nbsp;-&nbsp;10</b> of <b>26</b> in total"
end
@@ -55,7 +74,8 @@ def info(params, options = {})
it "should handle longer class names" do
collection = @array.paginate(:page => 2, :per_page => 5)
- collection.first.stubs(:class).returns(mock('Class', :name => 'ProjectType'))
+ model = stub('Class', :name => 'ProjectType', :to_s => 'ProjectType')
+ collection.first.stubs(:class).returns(model)
info(collection).should include_phrase('project types')
end
@@ -67,5 +87,30 @@ def info(params, options = {})
it "should display 'no entries found' for empty collections" do
info([].paginate(:page => 1, :per_page => 5)).should == "No entries found"
end
+
+ it "uses model_name.human when available" do
+ name = stub('model name', :i18n_key => :flower_key)
+ name.expects(:human).with(:count => 1).returns('flower')
+ model = stub('Class', :model_name => name)
+ collection = [1].paginate(:page => 1)
+
+ info(collection, :model => model).should == "Displaying 1 flower"
+ end
+
+ it "uses custom translation instead of model_name.human" do
+ name = stub('model name', :i18n_key => :flower_key)
+ name.expects(:human).never
+ model = stub('Class', :model_name => name)
+ translation :will_paginate => {:models => {:flower_key => 'tulip'}}
+ collection = [1].paginate(:page => 1)
+
+ info(collection, :model => model).should == "Displaying 1 tulip"
+ end
+
+ private
+
+ def translation(data)
+ I18n.backend.store_translations(:en, data)
+ end
end
end
Please sign in to comment.
Something went wrong with that request. Please try again.