public
Rubygem
Description: Most awesome pagination solution for Ruby
Homepage: http://github.com/mislav/will_paginate/wikis
Clone URL: git://github.com/mislav/will_paginate.git
Search Repo:
mislav (author)
Fri May 09 02:48:50 -0700 2008
commit  ad66001d7f816ddfcdaf24e75c0fd1fd1dfc464a
tree    51cd7137d5ad585605c58e0e3e420e5bb62c05c3
parent  42c8e31fde4c554a56a99614dbd834c5c1da57ca
100644 132 lines (124 sloc) 5.717 kb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
require 'will_paginate/view_helpers'
 
module WillPaginate
  module ViewHelpers
    module Common
      # 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...
      #
      # ==== Options
      # * <tt>:class</tt> -- CSS class name for the generated DIV (default: "pagination")
      # * <tt>:prev_label</tt> -- default: "« Previous"
      # * <tt>:next_label</tt> -- default: "Next »"
      # * <tt>:inner_window</tt> -- how many links are shown around the current page (default: 4)
      # * <tt>:outer_window</tt> -- how many links are around the first and the last page (default: 1)
      # * <tt>:separator</tt> -- string separator for page HTML elements (default: single space)
      # * <tt>:param_name</tt> -- parameter name for page number in URLs (default: <tt>:page</tt>)
      # * <tt>:params</tt> -- additional parameters when generating pagination links
      # (eg. <tt>:controller => "foo", :action => nil</tt>)
      # * <tt>:renderer</tt> -- class name, class or instance of a link renderer (default:
      # <tt>WillPaginate::LinkRenderer</tt>)
      # * <tt>:page_links</tt> -- when false, only previous/next links are rendered (default: true)
      # * <tt>:container</tt> -- toggles rendering of the DIV container for pagination links, set to
      # false only when you are rendering your own pagination markup (default: true)
      # * <tt>:id</tt> -- 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".
      #
      # All options beside listed ones are passed as HTML attributes to the container
      # element for pagination links (the DIV). For example:
      #
      # <%= will_paginate @posts, :id => 'wp_posts' %>
      #
      # ... will result in:
      #
      # <div class="pagination" id="wp_posts"> ... </div>
      #
      # ==== Using the helper without arguments
      # 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 <tt>@posts</tt>
      # variable. Example:
      #
      # <%= will_paginate :id => true %>
      #
      # ... will result in <tt>@post</tt> collection getting paginated:
      #
      # <div class="pagination" id="posts_pagination"> ... </div>
      #
      def will_paginate(collection, options = {})
        # early exit if there is nothing to render
        return nil unless WillPaginate::ViewHelpers.total_pages_for_collection(collection) > 1
        
        options = WillPaginate::ViewHelpers.pagination_options.merge(options)
        
        # 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
      
      # 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 to your liking 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.
      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
          entry_name + 's'
        end
 
        unless options[:html] == false
          b = '<b>'
          eb = '</b>'
          sp = '&nbsp;'
        else
          b = eb = ''
          sp = ' '
        end
        
        if collection.total_pages < 2
          case collection.size
          when 0; "No #{plural_name} found"
          when 1; "Displaying #{b}1#{eb} #{entry_name}"
          else; "Displaying #{b}all #{collection.size}#{eb} #{plural_name}"
          end
        else
          %{Displaying #{plural_name} #{b}%d#{sp}-#{sp}%d#{eb} of #{b}%d#{eb} in total} % [
            collection.offset + 1,
            collection.offset + collection.length,
            collection.total_entries
          ]
        end
      end
    end
  end
end