Skip to content

Commit

Permalink
Total rdoc love. Point out that this is framework-agnostic now
Browse files Browse the repository at this point in the history
  • Loading branch information
mislav committed Jan 12, 2009
1 parent a27e202 commit 231f964
Show file tree
Hide file tree
Showing 14 changed files with 132 additions and 101 deletions.
21 changes: 11 additions & 10 deletions CHANGELOG.rdoc
@@ -1,25 +1,26 @@
== "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)
* added WP::ViewHelpers::ActionView and LinkRenderer
* 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
Expand Down Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion 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
Expand Down
86 changes: 44 additions & 42 deletions 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:

Expand All @@ -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
Expand All @@ -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 -%>
Expand All @@ -87,31 +95,25 @@ 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:

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:

Expand Down
5 changes: 4 additions & 1 deletion Rakefile
Expand Up @@ -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
Expand Down
4 changes: 3 additions & 1 deletion lib/will_paginate.rb
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion lib/will_paginate/array.rb
Expand Up @@ -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:
Expand Down
2 changes: 1 addition & 1 deletion lib/will_paginate/collection.rb
Expand Up @@ -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
Expand Down
6 changes: 3 additions & 3 deletions lib/will_paginate/finders/active_record.rb
Expand Up @@ -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)

Expand All @@ -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)
Expand All @@ -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)
Expand Down
9 changes: 6 additions & 3 deletions lib/will_paginate/finders/active_resource.rb
Expand Up @@ -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
Expand All @@ -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)
Expand Down
13 changes: 12 additions & 1 deletion lib/will_paginate/finders/base.rb
Expand Up @@ -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
Expand Down
6 changes: 3 additions & 3 deletions lib/will_paginate/finders/data_mapper.rb
Expand Up @@ -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)
Expand All @@ -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]
Expand Down
31 changes: 17 additions & 14 deletions lib/will_paginate/view_helpers.rb
Expand Up @@ -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 = {
Expand Down

0 comments on commit 231f964

Please sign in to comment.