The main view helper, will_paginate, renders pagination links for the given collection. The helper itself is lightweight and serves only as a wrapper around LinkRenderer instantiation; the renderer then does all the hard work of generating the HTML.
Options for pagination helpers are optional and get their default values
from the WillPaginate::ViewHelpers.pagination_options hash.
You can write to this hash to override default options on the global level:
WillPaginate::ViewHelpers.pagination_options[:previous_label] = 'Previous page'
By putting this into “config/initializers/will_paginate.rb” (or simply environment.rb in older versions of Rails) you can easily translate link texts to previous and next pages, as well as override some other defaults to your liking.
Renders a helpful message with numbers of displayed vs. total entries. You can use this as a blueprint for your own, similar helpers.
<%= page_entries_info @posts %> #-> Displaying posts 6 - 10 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 :model parameter:
<%= page_entries_info @posts, :model => 'item' %> #-> Displaying items 6 - 10 of 26 in total
# File lib/will_paginate/view_helpers.rb, line 173 def page_entries_info(collection, options = {}) if options.key? :entry_name WillPaginate::Deprecation::warn(":entry_name parameter is now called :model", caller) end model = options[:model] || options[:entry_name] model = collection.first.class unless model or collection.empty? model ||= 'entry' if html = options.fetch(:html, true) b, eb = '<b>', '</b>' sp = ' ' html_key = '_html' else b = eb = html_key = '' sp = ' ' end model_key = model.to_s.underscore model_count = collection.total_pages > 1 ? 5 : collection.size model_name = will_paginate_translate "models.#{model_key}", :count => model_count do |_, opts| 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 output = if collection.total_pages < 2 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#{sp}#{opts[:count]}#{eb} #{opts[:model]}" end end else 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| %Q{Displaying %s #{b}%d#{sp}-#{sp}%d#{eb} of #{b}%d#{eb} in total} % [ opts[:model], opts[:from], opts[:to], opts[:count] ] end end if html and output.respond_to?(:html_safe) output.html_safe else output end end
Wrapper for rendering pagination links at both top and bottom of a block of content.
<% paginated_section @posts do %>
<ol id="posts">
<% for post in @posts %>
<li> ... </li>
<% end %>
</ol>
<% end %>
will result in:
<div class="pagination"> ... </div> <ol id="posts"> ... </l> <div class="pagination"> ... </div>
Arguments are passed to a will_paginate call, so the same
options apply. Don’t use the :id option; otherwise you’ll
finish with two blocks of pagination links sharing the same ID (which is
invalid HTML).
# File lib/will_paginate/view_helpers.rb, line 148 def paginated_section(*args, &block) pagination = will_paginate(*args).to_s if respond_to? :output_buffer concat pagination yield concat pagination else content = pagination + capture(&block) + pagination concat(content, block.binding) end end
Renders Digg/Flickr-style pagination for a WillPaginate::Collection object. Nil is returned if there is only one page in total; no point in rendering the pagination in that case…
Display options:
:previous_label – default: “« Previous” (this parameter
is called :prev_label in versions 2.3.2 and
older!)
:next_label – default: “Next »”
:page_links – when false, only previous/next links are
rendered (default: true)
:inner_window – how many links are shown around the current
page (default: 4)
:outer_window – how many links are around the first and the
last page (default: 1)
:separator – string separator for page HTML elements
(default: single space)
HTML options:
:class – CSS class name for the generated DIV (default:
“pagination”)
:container – toggles rendering of the DIV container for
pagination links, set to false only when you are rendering your own
pagination markup (default: true)
:id – HTML ID for the container (default: nil). Pass
true to have the ID automatically generated from the class
name of objects in collection: for example, paginating ArticleComment
models would yield an ID of “article_comments_pagination”.
Advanced options:
:param_name – parameter name for page number in URLs
(default: :page)
:params – additional parameters when generating pagination
links (eg. :controller => "foo", :action =>
nil)
:renderer – class name, class or instance of a link renderer
(default: WillPaginate::LinkRenderer)
All options not recognized by #will_paginate will become HTML attributes on the container element for pagination links (the DIV). For example:
<%= will_paginate @posts, :style => 'font-size: small' %>
… will result in:
<div class="pagination" style="font-size: small"> ... </div>
If the helper is called without passing in the collection object, it will
try to read from the instance variable inferred by the controller name. For
example, calling will_paginate while the current controller is
PostsController will result in trying to read from the @posts
variable. Example:
<%= will_paginate :id => true %>
… will result in @post collection getting paginated:
<div class="pagination" id="posts_pagination"> ... </div>
# File lib/will_paginate/view_helpers.rb, line 92 def will_paginate(collection = nil, options = {}) options, collection = collection, nil if collection.is_a? Hash unless collection or !controller collection_name = "@#{controller.controller_name}" collection = instance_variable_get(collection_name) raise ArgumentError, "The #{collection_name} variable appears to be empty. Did you " + "forget to pass the collection object for will_paginate?" unless collection end # early exit if there is nothing to render return nil unless WillPaginate::ViewHelpers.total_pages_for_collection(collection) > 1 options = options.symbolize_keys.reverse_merge WillPaginate::ViewHelpers.pagination_options if options[:prev_label] WillPaginate::Deprecation::warn(":prev_label view parameter is now :previous_label; the old name has been deprecated", caller) options[:previous_label] = options.delete(:prev_label) end options[:previous_label] ||= will_paginate_translate(:previous_label) { '« Previous' } options[:next_label] ||= will_paginate_translate(:next_label) { 'Next »' } # get the renderer instance renderer = case options[:renderer] when String options[:renderer].to_s.constantize.new when Class options[:renderer].new else options[:renderer] end # render HTML for pagination renderer.prepare collection, options, self renderer.to_html end