Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Total rdoc love. Point out that this is framework-agnostic now

  • Loading branch information...
commit 231f9640d82d725f252621d85761dc79dd49e421 1 parent a27e202
@mislav authored
View
21 CHANGELOG.rdoc
@@ -1,5 +1,13 @@
== "agnostic" branch
+* added Sequel support
+* added an initialization hook for Merb
+* refactored URL generation
+* BACKWARDS INCOMPATIBLE: refactored LinkRenderer; also markup changes
+ <span class="current">1</span> is now <em>1</em>
+ a.prev_page -> a.previous_page (for consistency)
+* "prev_label" -> "previous_label"
+* ported view tests to specs
* setup Autotest
* added per_page=(limit) attribute writer to set default per_page
* Remove :include option from count_all query when possible (Rails 2.1)
@@ -7,19 +15,12 @@
* specs for ViewHelpers::Base and LinkRendererBase
* created LinkRendererBase that implements windowed visible page numbers logic
* created WP::ViewHelpers::Base abstract module that implements generic view helpers
-* converted finder tests to specs
+* ported finder tests to specs
* added WP::Finders::DataMapper
* added WP::Finders::ActiveRecord mixin for ActiveRecord::Base
* created WP::Finders::Base abstract module that implements generic pagination logic
* removed dependency to ActiveSupport
-=== TODO:
-
-* Make a concrete implementation of LinkRendererBase that will generate HTML for both ActionView and Merb
-* ActionView and Merb integration tests for view helpers
-* 3c4725 Oops, I used return in an iterator block. I obviously write too much JavaScript
-* 537f22 ensure that 'href' values in pagination links are escaped URLs
-
== 2.3.1, released 2008-05-04
* Fixed page numbers not showing with custom routes and implicit first page
@@ -49,14 +50,14 @@
gem install mislav-will_paginate
* extract reusable pagination testing stuff into WillPaginate::View
-* rethink the page URL construction mechanizm to be more bulletproof when
+* rethink the page URL construction mechanism to be more bulletproof when
combined with custom routing for page parameter
* test that anchor parameter can be used in pagination links
== 2.2.2, released 2008-04-21
* Add support for page parameter in custom routes like "/foo/page/2"
-* Change output of "page_entries_info" on single-page collection and erraneous
+* Change output of "page_entries_info" on single-page collection and erroneous
output with empty collection as reported by Tim Chater
== 2.2.1, released 2008-04-08
View
2  LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2007 PJ Hyett and Mislav Marohnić
+Copyright (c) 2009 Mislav Marohnić
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
View
86 README.rdoc
@@ -1,7 +1,7 @@
-= WillPaginate
+= The will_paginate Ruby library
-Pagination is just limiting the number of records displayed. Why should you let it get in your way
-while developing?
+Pagination is just limiting the number of records loaded and displayed. Why should you let it get in
+your way while developing?
This is how you paginate on an ActiveRecord model:
@@ -11,30 +11,43 @@ Most of the time it's as simple as replacing "find" with "paginate" and specifyi
Some resources to get you started:
-* The {will_paginate project page}[http://github.com/mislav/will_paginate];
+* The {will_paginate project page}[http://mislav.github.com/will_paginate/];
* Your mind reels with questions? Join our {Google group}[http://groups.google.com/group/will_paginate];
* {How to report bugs}[http://github.com/mislav/will_paginate/wikis/report-bugs];
* {Watch the will_paginate screencast}[http://railscasts.com/episodes/51] by Ryan Bates.
+== I'm not using Rails; can I still use will_paginate?
+
+Absolutely -- although will_paginate started off as a Rails plugin, now it is a <em>completely
+framework-agnostic</em> library with support for Rails and Merb built-in. The core library doesn't
+have any dependences and you can safely use it in any Ruby code.
+
+When will_paginate is loaded in an environment where ActiveRecord and ActionView are present, it
+automatically hooks into these frameworks to provide easy pagination on your models and in your
+views. The same mechanism works for Merb applications, too. But, if no known framework is present
+then you have absolute control over what parts of will_paginate do you want to load and where you want
+them mixed in.
+
== Installation
-The recommended way is that you get the gem:
+The recommended way is that you get the gem hosted on {gems.github.com}[http://gems.github.com/]:
- gem install --source=http://gems.github.com/ mislav-will_paginate
+ gem install mislav-will_paginate
-After that you don't need the will_paginate <i>plugin</i> in your Rails application anymore. In
-<b>Rails 2.1</b>, add a gem dependency:
+In <b>Rails 2.1</b>, add a gem dependency:
- config.gem 'mislav-will_paginate', :lib => 'will_paginate', :version => '~> 2.5'
+ # for Rails 2.1 and newer
+ config.gem 'mislav-will_paginate', :lib => 'will_paginate', :version => '~> 3.0'
-If you're using Rails 2.0 or older, just add a simple require to the end of your
-"config/environment.rb" instead:
+If you're using Rails 2.0 or older, or any other Ruby framework, just add a simple require to a file
+that initializes your application. For example, in Rails you would put this at the end of
+"config/environment.rb".
- gem 'mislav-will_paginate', '~> 2.5'
+ gem 'mislav-will_paginate', '~> 3.0'
require 'will_paginate'
-That's it. Remember to install the gem on <b>all</b> machines that you are deploying to.
+That's it. Remember to install the gem on <strong>all</strong> machines that you are deploying to.
<i>There are extensive {installation
instructions}[http://github.com/mislav/will_paginate/wikis/installation] on {the
@@ -43,40 +56,35 @@ wiki}[http://github.com/mislav/will_paginate/wikis].</i>
== Example usage
-Use a paginate finder in the controller:
+Typical usage involves a paginating find in the controller:
+
+ @posts = Post.paginate :page => params[:page], :order => 'updated_at DESC'
- @posts = Post.paginate_by_board_id(
- @board.id,
- :page => params[:page],
- :order => 'updated_at DESC'
- )
+It's true: +paginate+ works just like +find+ -- it just doesn't fetch all the records. Don't forget
+to tell it which page you want, or it will complain! Read more in WillPaginate::Finders.
-Yeah, +paginate+ works just like +find+ -- it just doesn't fetch all the records. Don't forget to
-tell it which page you want, or it will complain! Read more about WillPaginate::Finders.
-
-Render the posts in your view like you would normally do. When you need to render pagination, just
-stick this in:
+Render the posts in your view like you would normally do, and when you need to render pagination,
+just stick this in:
<%= will_paginate @posts %>
-You're done. (Copy and paste the example fancy CSS styles from the bottom.) You can find the option
-list at WillPaginate::ViewHelpers.
+You're done. Read more in WillPaginate::ViewHelpers::Base.
How does it know how much items to fetch per page? It asks your model by calling its
-<tt>per_page</tt> class method. You can define it like this:
++per_page+ class method. You can define it like this:
class Post < ActiveRecord::Base
- def self.per_page() 50 end
+ self.per_page = 50
end
-... or don't worry about it at all. WillPaginate defines it to be <b>30</b> by default. You can
+... or don't worry about it at all. WillPaginate defines it to be <strong>30</strong> by default. You can
always specify the count explicitly when calling +paginate+:
- @posts = Post.paginate :page => params[:page], :per_page => 50
+ Post.paginate :page => params[:page], :per_page => 50
The +paginate+ finder wraps the original finder and returns your result set that now has some new
properties. You can use the collection as you would use any other array. WillPaginate view helpers
-also need that object to be able to render pagination:
+also need that collection object to be able to render pagination:
<ol>
<% for post in @posts -%>
@@ -87,17 +95,11 @@ also need that object to be able to render pagination:
<p>Now let's render us some pagination!</p>
<%= will_paginate @posts %>
-More detailed documentation:
-
-* WillPaginate::Finders for pagination on your models;
-* WillPaginate::ViewHelpers for your views.
-
== Authors and credits
-Authors:: Mislav Marohnić, PJ Hyett
-Original announcement:: http://errtheblog.com/post/929
-Original PHP source:: http://www.strangerstudios.com/sandbox/pagination/diggstyle.php
+The original author of will_paginate is PJ Hyett, who later handed over development to Mislav
+Marohnić. The library was almost completely rewritten twice since then.
All these people helped making will_paginate what it is now with their code contributions or just
simply awesome ideas:
@@ -105,13 +107,13 @@ simply awesome ideas:
Chris Wanstrath, Dr. Nic Williams, K. Adam Christensen, Mike Garey, Bence Golda, Matt Aimonetti,
Charles Brian Quinn, Desi McAdam, James Coglan, Matijs van Zuijlen, Maria, Brendan Ribera, Todd
Willey, Bryan Helmkamp, Jan Berkel, Lourens Naudé, Rick Olson, Russell Norris, Piotr Usewicz, Chris
-Eppstein.
+Eppstein, Brandon Arbini, Denis Barushev, Paul Barry, Ben Pickles, Ken Collins, Lida Tang and Pieter
+Noordhuis.
== Usable pagination in the UI
-There are some CSS styles to get you started in the "examples/" directory. They are showcased in the
-<b>"examples/index.html"</b> file.
+There are example CSS styles to get you started on the will_paginate project page.
More reading about pagination as design pattern:
View
5 Rakefile
@@ -16,8 +16,11 @@ desc 'Generate RDoc documentation for the will_paginate plugin.'
Rake::RDocTask.new(:rdoc) do |rdoc|
rdoc.rdoc_files.include('README.rdoc', 'LICENSE', 'CHANGELOG.rdoc').
include('lib/**/*.rb').
- exclude('lib/will_paginate/named_scope*').
+ exclude('lib/will_paginate/finders/active_record/named_scope*').
+ exclude('lib/will_paginate/finders/sequel.rb').
+ exclude('lib/will_paginate/view_helpers/merb.rb').
exclude('lib/will_paginate/deprecation.rb').
+ exclude('lib/will_paginate/core_ext.rb').
exclude('lib/will_paginate/version.rb')
rdoc.main = "README.rdoc" # page to start on
View
4 lib/will_paginate.rb
@@ -2,12 +2,14 @@
# = You *will* paginate!
#
-# First read about WillPaginate::Finder::ClassMethods, then see
+# First read about WillPaginate::Finders::Base, then see
# WillPaginate::ViewHelpers. The magical array you're handling in-between is
# WillPaginate::Collection.
#
# Happy paginating!
module WillPaginate
+ # This method used to hook in ActiveRecord and ActionView at load time,
+ # but now doesn't do anything anymore and will be removed in future releases.
def self.enable
Deprecation.warn "WillPaginate::enable() doesn't do anything anymore"
end
View
2  lib/will_paginate/array.rb
@@ -2,7 +2,7 @@
class Array
# Paginates a static array (extracting a subset of it). The result is a
- # WillPaginate::Collection instance, which is an array with few more
+ # WillPaginate::Collection instance, which is an array with a few more
# properties about its paginated state.
#
# Parameters:
View
2  lib/will_paginate/collection.rb
@@ -17,7 +17,7 @@ module WillPaginate
# requested. Use <tt>WillPaginate::Collection#out_of_bounds?</tt> method to
# check for those cases and manually deal with them as you see fit.
class InvalidPage < ArgumentError
- def initialize(page, page_num)
+ def initialize(page, page_num) #:nodoc:
super "#{page.inspect} given as value, which translates to '#{page_num}' as page number"
end
end
View
6 lib/will_paginate/finders/active_record.rb
@@ -99,7 +99,7 @@ def method_missing_with_paginate(method, *args, &block) #:nodoc:
paginate(*args, &block)
end
- def wp_query(options, pager, args, &block)
+ def wp_query(options, pager, args, &block) #:nodoc:
finder = (options.delete(:finder) || 'find').to_s
find_options = options.except(:count).update(:offset => pager.offset, :limit => pager.per_page)
@@ -121,7 +121,7 @@ def wp_query(options, pager, args, &block)
# Does the not-so-trivial job of finding out the total number of entries
# in the database. It relies on the ActiveRecord +count+ method.
- def wp_count(options, args, finder)
+ def wp_count(options, args, finder) #:nodoc:
# find out if we are in a model or an association proxy
klass = (@owner and @reflection) ? @reflection.klass : self
count_options = wp_parse_count_options(options, klass)
@@ -145,7 +145,7 @@ def wp_count(options, args, finder)
count.respond_to?(:length) ? count.length : count
end
- def wp_parse_count_options(options, klass)
+ def wp_parse_count_options(options, klass) #:nodoc:
excludees = [:count, :order, :limit, :offset, :readonly]
unless ::ActiveRecord::Calculations::CALCULATIONS_OPTIONS.include?(:from)
View
9 lib/will_paginate/finders/active_resource.rb
@@ -4,13 +4,16 @@
module WillPaginate::Finders
# Paginate your ActiveResource models.
#
- # @posts = Post.paginate :all, :params => { :page => params[:page], :order => 'created_at DESC' }
+ # @posts = Post.paginate :all, :params => {
+ # :page => params[:page], :order => 'created_at DESC'
+ # }
+ #
module ActiveResource
include WillPaginate::Finders::Base
protected
- def wp_query(options, pager, args, &block)
+ def wp_query(options, pager, args, &block) #:nodoc:
unless args.empty? or args.first == :all
raise ArgumentError, "finder arguments other than :all are not supported for pagination (#{args.inspect} given)"
end
@@ -26,7 +29,7 @@ def wp_query(options, pager, args, &block)
# parses it into a WillPaginate::Collection,
# and forwards the result to the former +instantiate_collection+ method.
# It only does this for hashes that have a :type => "collection".
- def instantiate_collection_with_collection(collection, prefix_options = {})
+ def instantiate_collection_with_collection(collection, prefix_options = {}) #:nodoc:
if collection.is_a?(Hash) && collection["type"] == "collection"
collectables = collection.values.find{ |c| c.is_a?(Hash) || c.is_a?(Array) }
collectables = [collectables].compact unless collectables.kind_of?(Array)
View
13 lib/will_paginate/finders/base.rb
@@ -2,7 +2,18 @@
module WillPaginate
module Finders
- # Database-agnostic finder logic
+ # = Database-agnostic finder module
+ #
+ # Out of the box, will_paginate supports hooking in several ORMs to provide paginating
+ # finders based on their API. As of this writing, the supported libraries are:
+ #
+ # * ActiveRecord
+ # * DataMapper
+ # * Sequel
+ #
+ # It's easy to write your own adapter for anything that can load data with explicit
+ # limit and offset settings. DataMapper adapter is a nice and compact example of
+ # writing an adapter to bring the +paginate+ method to DataMapper models.
module Base
def per_page
@per_page ||= 30
View
6 lib/will_paginate/finders/data_mapper.rb
@@ -5,9 +5,9 @@ module WillPaginate::Finders
module DataMapper
include WillPaginate::Finders::Base
- protected
+ protected
- def wp_query(options, pager, args, &block)
+ def wp_query(options, pager, args, &block) #:nodoc
find_options = options.except(:count).update(:offset => pager.offset, :limit => pager.per_page)
pager.replace all(find_options, &block)
@@ -17,7 +17,7 @@ def wp_query(options, pager, args, &block)
end
end
- def wp_count(options)
+ def wp_count(options) #:nodoc
count_options = options.except(:count, :order)
# merge the hash found in :count
count_options.update options[:count] if options[:count]
View
31 lib/will_paginate/view_helpers.rb
@@ -3,23 +3,26 @@
module WillPaginate
# = Will Paginate view helpers
#
- # Currently there is only one view helper: +will_paginate+. It renders the
- # pagination links for the given collection. The helper itself is lightweight
- # and serves only as a wrapper around link renderer instantiation; the
- # renderer then does all the hard work of generating the HTML.
+ # The main view helper is +will_paginate+. It renders the 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.
#
- # == Global options for helpers
- #
- # 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 your environment.rb you can easily translate link texts to previous
- # and next pages, as well as override some other defaults to your liking.
+ # Read more in WillPaginate::ViewHelpers::Base
module ViewHelpers
+ # ==== Global options for helpers
+ #
+ # 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 your environment.rb you can easily translate link
+ # texts to previous and next pages, as well as override some other defaults
+ # to your liking.
def self.pagination_options() @pagination_options; end
+ # Overrides the default +pagination_options+
def self.pagination_options=(value) @pagination_options = value; end
self.pagination_options = {
View
25 lib/will_paginate/view_helpers/action_view.rb
@@ -5,18 +5,35 @@
module WillPaginate
module ViewHelpers
- # ActionView helpers for Rails integration
+ # = ActionView helpers
+ #
+ # This module serves for availability in ActionView templates. It also adds a new
+ # view helper: +paginated_section+.
+ #
+ # == 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>
+ #
module ActionView
include WillPaginate::ViewHelpers::Base
- def will_paginate(collection = nil, options = {})
+ def will_paginate(collection = nil, options = {}) #:nodoc:
options, collection = collection, nil if collection.is_a? Hash
collection ||= infer_collection_from_controller
super(collection, options.symbolize_keys)
end
- def page_entries_info(collection = nil, options = {})
+ def page_entries_info(collection = nil, options = {}) #:nodoc:
options, collection = collection, nil if collection.is_a? Hash
collection ||= infer_collection_from_controller
@@ -72,7 +89,7 @@ def infer_collection_from_controller
end
ActionView::Base.send :include, WillPaginate::ViewHelpers::ActionView
-
+# :stopdoc:
if defined?(ActionController::Base) and ActionController::Base.respond_to? :rescue_responses
ActionController::Base.rescue_responses['WillPaginate::InvalidPage'] = :not_found
end
View
21 lib/will_paginate/view_helpers/base.rb
@@ -3,10 +3,12 @@
module WillPaginate
module ViewHelpers
+ # = The main view helpers module
+ #
+ # This is the base module which provides the +will_paginate+ view helper.
module Base
- # 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...
+ # Renders Digg/Flickr-style pagination for a WillPaginate::Collection object. Nil is
+ # returned if there is only one page in total; pagination links aren't needed in that case.
#
# ==== Options
# * <tt>:class</tt> -- CSS class name for the generated DIV (default: "pagination")
@@ -36,19 +38,6 @@ module Base
#
# <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 collection.total_pages > 1
Please sign in to comment.
Something went wrong with that request. Please try again.