Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Latest will_paginate/rails3

  • Loading branch information...
commit 6f3bedfa1fa1d4481ab4794798f0af5e3041425c 1 parent ff92009
@lifo lifo authored
Showing with 2,872 additions and 2,950 deletions.
  1. +4 −0 vendor/plugins/will_paginate/.gitignore
  2. +0 −43 vendor/plugins/will_paginate/.manifest
  3. +24 −58 vendor/plugins/will_paginate/CHANGELOG.rdoc
  4. +14 −0 vendor/plugins/will_paginate/Gemfile
  5. +1 −1  vendor/plugins/will_paginate/LICENSE
  6. +78 −60 vendor/plugins/will_paginate/README.rdoc
  7. +14 −35 vendor/plugins/will_paginate/Rakefile
  8. BIN  vendor/plugins/will_paginate/examples/apple-circle.gif
  9. +0 −69 vendor/plugins/will_paginate/examples/index.haml
  10. +0 −92 vendor/plugins/will_paginate/examples/index.html
  11. +0 −90 vendor/plugins/will_paginate/examples/pagination.css
  12. +0 −91 vendor/plugins/will_paginate/examples/pagination.sass
  13. +11 −78 vendor/plugins/will_paginate/lib/will_paginate.rb
  14. +25 −8 vendor/plugins/will_paginate/lib/will_paginate/array.rb
  15. +8 −7 vendor/plugins/will_paginate/lib/will_paginate/collection.rb
  16. +26 −0 vendor/plugins/will_paginate/lib/will_paginate/core_ext.rb
  17. +50 −0 vendor/plugins/will_paginate/lib/will_paginate/deprecation.rb
  18. +0 −264 vendor/plugins/will_paginate/lib/will_paginate/finder.rb
  19. +9 −0 vendor/plugins/will_paginate/lib/will_paginate/finders.rb
  20. +158 −0 vendor/plugins/will_paginate/lib/will_paginate/finders/active_record.rb
  21. +51 −0 vendor/plugins/will_paginate/lib/will_paginate/finders/active_resource.rb
  22. +112 −0 vendor/plugins/will_paginate/lib/will_paginate/finders/base.rb
  23. +30 −0 vendor/plugins/will_paginate/lib/will_paginate/finders/data_mapper.rb
  24. +23 −0 vendor/plugins/will_paginate/lib/will_paginate/finders/sequel.rb
  25. +0 −170 vendor/plugins/will_paginate/lib/will_paginate/named_scope.rb
  26. +0 −37 vendor/plugins/will_paginate/lib/will_paginate/named_scope_patch.rb
  27. +24 −0 vendor/plugins/will_paginate/lib/will_paginate/railtie.rb
  28. +5 −5 vendor/plugins/will_paginate/lib/will_paginate/version.rb
  29. +25 −391 vendor/plugins/will_paginate/lib/will_paginate/view_helpers.rb
  30. +134 −0 vendor/plugins/will_paginate/lib/will_paginate/view_helpers/action_view.rb
  31. +126 −0 vendor/plugins/will_paginate/lib/will_paginate/view_helpers/base.rb
  32. +130 −0 vendor/plugins/will_paginate/lib/will_paginate/view_helpers/link_renderer.rb
  33. +83 −0 vendor/plugins/will_paginate/lib/will_paginate/view_helpers/link_renderer_base.rb
  34. +13 −0 vendor/plugins/will_paginate/lib/will_paginate/view_helpers/merb.rb
  35. +147 −0 vendor/plugins/will_paginate/spec/collection_spec.rb
  36. +2 −2 vendor/plugins/will_paginate/{test → spec}/console
  37. +8 −0 vendor/plugins/will_paginate/spec/console_fixtures.rb
  38. +3 −3 vendor/plugins/will_paginate/{test → spec}/database.yml
  39. +377 −0 vendor/plugins/will_paginate/spec/finders/active_record_spec.rb
  40. +52 −0 vendor/plugins/will_paginate/spec/finders/active_resource_spec.rb
  41. +114 −0 vendor/plugins/will_paginate/spec/finders/activerecord_test_connector.rb
  42. +62 −0 vendor/plugins/will_paginate/spec/finders/data_mapper_spec.rb
  43. +20 −0 vendor/plugins/will_paginate/spec/finders/data_mapper_test_connector.rb
  44. +53 −0 vendor/plugins/will_paginate/spec/finders/sequel_spec.rb
  45. +9 −0 vendor/plugins/will_paginate/spec/finders/sequel_test_connector.rb
  46. +76 −0 vendor/plugins/will_paginate/spec/finders_spec.rb
  47. 0  vendor/plugins/will_paginate/{test → spec}/fixtures/admin.rb
  48. +1 −2  vendor/plugins/will_paginate/{test → spec}/fixtures/developer.rb
  49. 0  vendor/plugins/will_paginate/{test → spec}/fixtures/developers_projects.yml
  50. +2 −4 vendor/plugins/will_paginate/{test → spec}/fixtures/project.rb
  51. +1 −1  vendor/plugins/will_paginate/{test → spec}/fixtures/projects.yml
  52. 0  vendor/plugins/will_paginate/{test → spec}/fixtures/replies.yml
  53. +1 −1  vendor/plugins/will_paginate/{test → spec}/fixtures/reply.rb
  54. 0  vendor/plugins/will_paginate/{test → spec}/fixtures/schema.rb
  55. +7 −0 vendor/plugins/will_paginate/spec/fixtures/topic.rb
  56. 0  vendor/plugins/will_paginate/{test → spec}/fixtures/topics.yml
  57. 0  vendor/plugins/will_paginate/{test → spec}/fixtures/user.rb
  58. 0  vendor/plugins/will_paginate/{test → spec}/fixtures/users.yml
  59. +2 −0  vendor/plugins/will_paginate/spec/rcov.opts
  60. +2 −0  vendor/plugins/will_paginate/spec/spec.opts
  61. +74 −0 vendor/plugins/will_paginate/spec/spec_helper.rb
  62. +60 −0 vendor/plugins/will_paginate/spec/tasks.rake
  63. +356 −0 vendor/plugins/will_paginate/spec/view_helpers/action_view_spec.rb
  64. +64 −0 vendor/plugins/will_paginate/spec/view_helpers/base_spec.rb
  65. +84 −0 vendor/plugins/will_paginate/spec/view_helpers/link_renderer_base_spec.rb
  66. +103 −0 vendor/plugins/will_paginate/spec/view_helpers/view_example_group.rb
  67. +0 −21 vendor/plugins/will_paginate/test/boot.rb
  68. +0 −143 vendor/plugins/will_paginate/test/collection_test.rb
  69. +0 −473 vendor/plugins/will_paginate/test/finder_test.rb
  70. +0 −10 vendor/plugins/will_paginate/test/fixtures/topic.rb
  71. +0 −37 vendor/plugins/will_paginate/test/helper.rb
  72. +0 −43 vendor/plugins/will_paginate/test/lib/activerecord_test_case.rb
  73. +0 −75 vendor/plugins/will_paginate/test/lib/activerecord_test_connector.rb
  74. +0 −11 vendor/plugins/will_paginate/test/lib/load_fixtures.rb
  75. +0 −179 vendor/plugins/will_paginate/test/lib/view_test_process.rb
  76. +0 −59 vendor/plugins/will_paginate/test/tasks.rake
  77. +0 −373 vendor/plugins/will_paginate/test/view_test.rb
  78. +14 −14 vendor/plugins/will_paginate/will_paginate.gemspec
View
4 vendor/plugins/will_paginate/.gitignore
@@ -0,0 +1,4 @@
+.bundle
+doc
+*.gem
+coverage
View
43 vendor/plugins/will_paginate/.manifest
@@ -1,43 +0,0 @@
-CHANGELOG.rdoc
-LICENSE
-README.rdoc
-Rakefile
-examples/apple-circle.gif
-examples/index.haml
-examples/index.html
-examples/pagination.css
-examples/pagination.sass
-init.rb
-lib/will_paginate.rb
-lib/will_paginate/array.rb
-lib/will_paginate/collection.rb
-lib/will_paginate/core_ext.rb
-lib/will_paginate/finder.rb
-lib/will_paginate/named_scope.rb
-lib/will_paginate/named_scope_patch.rb
-lib/will_paginate/version.rb
-lib/will_paginate/view_helpers.rb
-test/boot.rb
-test/collection_test.rb
-test/console
-test/database.yml
-test/finder_test.rb
-test/fixtures/admin.rb
-test/fixtures/developer.rb
-test/fixtures/developers_projects.yml
-test/fixtures/project.rb
-test/fixtures/projects.yml
-test/fixtures/replies.yml
-test/fixtures/reply.rb
-test/fixtures/schema.rb
-test/fixtures/topic.rb
-test/fixtures/topics.yml
-test/fixtures/user.rb
-test/fixtures/users.yml
-test/helper.rb
-test/lib/activerecord_test_case.rb
-test/lib/activerecord_test_connector.rb
-test/lib/load_fixtures.rb
-test/lib/view_test_process.rb
-test/tasks.rake
-test/view_test.rb
View
82 vendor/plugins/will_paginate/CHANGELOG.rdoc
@@ -1,59 +1,25 @@
-= 2.3.12, released 2009-12-01
-
-* make view helpers "HTML safe" for Rails 2.3.5 with rails_xss plugin
-
-= 2.3.11, released 2009-06-02
-
-* fix `enable_actionpack`
-
-= 2.3.10, released 2009-05-21
-
-* count_by_sql: don't use table alias with any adapters starting with "oracle"
-* Add back "AS count_table" alias to `paginate_by_sql` counter SQL
-
-= 2.3.9, released 2009-05-29
-
-* remove "AS count_table" alias from `paginate_by_sql` counter SQL
-* Rails 2.3.2 compat: monkeypatch Rails issue #2189 (count breaks has_many :through)
-* fix generation of page URLs that contain the "@" character
-* check for method existance in a ruby 1.8- and 1.9-compatible way
-* load will_paginate view helpers even if ActiveRecord is not loaded
-
-== 2.3.8, released 2009-03-09
-
-* Rails 2.3 compat: query parameter parsing with Rack
-
-== 2.3.7, released 2009-02-09
-
-* Removed all unnecessary &block variables since they cause serious memory damage and lots of subsequent gc runs.
-
-== 2.3.6, released 2008-10-26
-
-* Rails 2.2 fix: stop using `extract_attribute_names_from_match` inernal AR method, it no longer exists
-
-== 2.3.5, released 2008-10-07
-
-* update the backported named_scope implementation for Rails versions older than 2.1
-* break out of scope of paginated_each() yielded block when used on named scopes
-* fix paginate(:from)
-
-== 2.3.4, released 2008-09-16
-
-* Removed gem dependency to Active Support (causes trouble with vendored rails).
-* Rails 2.1: fix a failing test and a deprecation warning.
-* Cope with scoped :select when counting.
-
-== 2.3.3, released 2008-08-29
-
-* Ensure that paginate_by_sql doesn't change the original SQL query.
-* RDoc love (now live at http://gitrdoc.com/mislav/will_paginate/tree/master)
-* Rename :prev_label to :previous_label for consistency. old name still functions but is deprecated
-* ActiveRecord 2.1: Remove :include option from count_all query when it's possible.
-
-== 2.3.2, released 2008-05-16
-
-* Fixed LinkRenderer#stringified_merge by removing "return" from iterator block
-* Ensure that 'href' values in pagination links are escaped URLs
+== "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
+* 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
== 2.3.1, released 2008-05-04
@@ -84,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
14 vendor/plugins/will_paginate/Gemfile
@@ -0,0 +1,14 @@
+git 'git://github.com/rails/rails.git'
+source :gemcutter
+
+gem 'activerecord', '~> 3.0.0.beta3'
+gem 'activeresource', '~> 3.0.0.beta3'
+gem 'actionpack', '~> 3.0.0.beta3'
+gem 'sequel', '~> 3.8.0'
+gem 'rspec', '~> 1.3.0'
+gem 'mocha', '~> 0.9.8'
+gem 'sqlite3-ruby', '~> 1.2.5'
+gem 'dm-core', '~> 0.10.2'
+gem 'do_sqlite3', '~> 0.10.1.1'
+gem 'mysql', '~> 2.8.1'
+gem 'pg', '~> 0.8.0'
View
2  vendor/plugins/will_paginate/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
138 vendor/plugins/will_paginate/README.rdoc
@@ -1,64 +1,90 @@
-= 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, then? This plugin makes magic happen. Did
-you ever want to be able to do just this on a model:
+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:
Post.paginate :page => 1, :order => 'created_at DESC'
-... and then render the page links with a single view helper? Well, now you
-can.
+Most of the time it's as simple as replacing "find" with "paginate" and specifying the page you want.
Some resources to get you started:
-* {Installation instructions}[http://github.com/mislav/will_paginate/wikis/installation]
- on {the wiki}[http://github.com/mislav/will_paginate/wikis]
-* 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]
+* 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?
-== Example usage
+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.
-Use a paginate finder in the controller:
+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.
- @posts = Post.paginate_by_board_id @board.id, :page => params[:page], :order => 'updated_at DESC'
-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 on WillPaginate::Finder::ClassMethods.
+== Installation
-Render the posts in your view like you would normally do. When you need to render
-pagination, just stick this in:
+The recommended way is that you get the gem hosted on {gems.github.com}[http://gems.github.com/]:
- <%= will_paginate @posts %>
+ gem install mislav-will_paginate
-You're done. (You can find the option list at WillPaginate::ViewHelpers.)
+In <b>Rails 2.1</b>, add a gem dependency:
-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:
+ # for Rails 2.1 and newer
+ config.gem 'mislav-will_paginate', :lib => 'will_paginate', :version => '~> 3.0'
- class Post < ActiveRecord::Base
- cattr_reader :per_page
- @@per_page = 50
- end
+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', '~> 3.0'
+ require 'will_paginate'
+
+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
+wiki}[http://github.com/mislav/will_paginate/wikis].</i>
+
+
+== Example usage
+
+Typical usage involves a paginating find in the controller:
+
+ @posts = Post.paginate :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.
+
+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. Read more in WillPaginate::ViewHelpers::Base.
-... or like this:
+How does it know how much items to fetch per page? It asks your model by calling its
++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.
-But you can always specify the count explicitly when calling +paginate+:
+... 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 resultset that now has
-some new properties. You can use the collection as you would with any ActiveRecord
-resultset. WillPaginate view helpers also need that object to be able to render pagination:
+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 collection object to be able to render pagination:
<ol>
<% for post in @posts -%>
@@ -69,39 +95,31 @@ resultset. WillPaginate view helpers also need that object to be able to render
<p>Now let's render us some pagination!</p>
<%= will_paginate @posts %>
-More detailed documentation:
-
-* WillPaginate::Finder::ClassMethods 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 was PJ Hyett, who later handed over development to Mislav
+Marohnić. (The library was completely rewritten since then.)
-All these people helped making will_paginate what it is now with their code
-contributions or just simply awesome ideas:
+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,
-Denis Barushev, Ben Pickles.
+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, 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 online here}[http://mislav.uniqpath.com/will_paginate/].
+There are example CSS styles to get you started on the will_paginate project page.
More reading about pagination as design pattern:
-* {Pagination 101}[http://kurafire.net/log/archive/2007/06/22/pagination-101]
-* {Pagination gallery}[http://www.smashingmagazine.com/2007/11/16/pagination-gallery-examples-and-good-practices/]
-* {Pagination on Yahoo Design Pattern Library}[http://developer.yahoo.com/ypatterns/parent.php?pattern=pagination]
-
-Want to discuss, request features, ask questions? Join the
-{Google group}[http://groups.google.com/group/will_paginate].
+* {Pagination 101}[http://kurafire.net/log/archive/2007/06/22/pagination-101];
+* {Pagination gallery}[http://www.smashingmagazine.com/2007/11/16/pagination-gallery-examples-and-good-practices/] featured on Smashing Magazine;
+* {Pagination design pattern}[http://developer.yahoo.com/ypatterns/parent.php?pattern=pagination] on Yahoo Design Pattern Library.
+Want to discuss, request features, ask questions? Join the {Google
+group}[http://groups.google.com/group/will_paginate].
View
49 vendor/plugins/will_paginate/Rakefile
@@ -1,23 +1,19 @@
-require 'rubygems'
-begin
- hanna_dir = '/Users/mislav/Projects/Hanna/lib'
- $:.unshift hanna_dir if File.exists? hanna_dir
- require 'hanna/rdoctask'
-rescue LoadError
- require 'rake'
- require 'rake/rdoctask'
-end
-load 'test/tasks.rake'
+require 'rake/rdoctask'
+
+load 'spec/tasks.rake'
-desc 'Default: run unit tests.'
-task :default => :test
+desc 'Default: run specs.'
+task :default => :spec
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/array.rb').
+ 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
@@ -28,26 +24,9 @@ Rake::RDocTask.new(:rdoc) do |rdoc|
rdoc.options << '--webcvs=http://github.com/mislav/will_paginate/tree/master/'
end
-desc %{Update ".manifest" with the latest list of project filenames. Respect\
-.gitignore by excluding everything that git ignores. Update `files` and\
-`test_files` arrays in "*.gemspec" file if it's present.}
-task :manifest do
- list = `git ls-files --full-name --exclude=*.gemspec --exclude=.*`.chomp.split("\n")
-
- if spec_file = Dir['*.gemspec'].first
- spec = File.read spec_file
- spec.gsub! /^(\s* s.(test_)?files \s* = \s* )( \[ [^\]]* \] | %w\( [^)]* \) )/mx do
- assignment = $1
- bunch = $2 ? list.grep(/^test\//) : list
- '%s%%w(%s)' % [assignment, bunch.join(' ')]
- end
-
- File.open(spec_file, 'w') { |f| f << spec }
+task :website do
+ Dir.chdir('website') do
+ %x(haml index.haml index.html)
+ %x(sass pagination.sass pagination.css)
end
- File.open('.manifest', 'w') { |f| f << list.join("\n") }
-end
-
-task :examples do
- %x(haml examples/index.haml examples/index.html)
- %x(sass examples/pagination.sass examples/pagination.css)
end
View
BIN  vendor/plugins/will_paginate/examples/apple-circle.gif
Deleted file not rendered
View
69 vendor/plugins/will_paginate/examples/index.haml
@@ -1,69 +0,0 @@
-!!!
-%html
-%head
- %title Samples of pagination styling for will_paginate
- %link{ :rel => 'stylesheet', :type => 'text/css', :href => 'pagination.css' }
- %style{ :type => 'text/css' }
- :sass
- html
- :margin 0
- :padding 0
- :background #999
- :font normal 76% "Lucida Grande", Verdana, Helvetica, sans-serif
- body
- :margin 2em
- :padding 2em
- :border 2px solid gray
- :background white
- :color #222
- h1
- :font-size 2em
- :font-weight normal
- :margin 0 0 1em 0
- h2
- :font-size 1.4em
- :margin 1em 0 .5em 0
- pre
- :font-size 13px
- :font-family Monaco, "DejaVu Sans Mono", "Bitstream Vera Mono", "Courier New", monospace
-
-- pagination = '<span class="disabled prev_page">&laquo; Previous</span> <span class="current">1</span> <a href="./?page=2" rel="next">2</a> <a href="./?page=3">3</a> <a href="./?page=4">4</a> <a href="./?page=5">5</a> <a href="./?page=6">6</a> <a href="./?page=7">7</a> <a href="./?page=8">8</a> <a href="./?page=9">9</a> <span class="gap">&hellip;</span> <a href="./?page=29">29</a> <a href="./?page=30">30</a> <a href="./?page=2" rel="next" class="next_page">Next &raquo;</a>'
-- pagination_no_page_links = '<span class="disabled prev_page">&laquo; Previous</span> <a href="./?page=2" rel="next" class="next_page">Next &raquo;</a>'
-
-%body
- %h1 Samples of pagination styling for will_paginate
- %p
- Find these styles in <b>"examples/pagination.css"</b> of <i>will_paginate</i> library.
- There is a Sass version of it for all you sassy people.
- %p
- Read about good rules for pagination:
- %a{ :href => 'http://kurafire.net/log/archive/2007/06/22/pagination-101' } Pagination 101
- %p
- %em Warning:
- page links below don't lead anywhere (so don't click on them).
-
- %h2 Unstyled pagination <span style="font-weight:normal">(<i>ewww!</i>)</span>
- %div= pagination
-
- %h2 Digg.com
- .digg_pagination= pagination
-
- %h2 Digg-style, no page links
- .digg_pagination= pagination_no_page_links
- %p Code that renders this:
- %pre= '<code>%s</code>' % %[<%= will_paginate @posts, :page_links => false %>].gsub('<', '&lt;').gsub('>', '&gt;')
-
- %h2 Digg-style, extra content
- .digg_pagination
- .page_info Displaying entries <b>1&nbsp;-&nbsp;6</b> of <b>180</b> in total
- = pagination
- %p Code that renders this:
- %pre= '<code>%s</code>' % %[<div class="digg_pagination">\n <div clas="page_info">\n <%= page_entries_info @posts %>\n </div>\n <%= will_paginate @posts, :container => false %>\n</div>].gsub('<', '&lt;').gsub('>', '&gt;')
-
- %h2 Apple.com store
- .apple_pagination= pagination
-
- %h2 Flickr.com
- .flickr_pagination
- = pagination
- .page_info (118 photos)
View
92 vendor/plugins/will_paginate/examples/index.html
@@ -1,92 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html>
-</html>
-<head>
- <title>Samples of pagination styling for will_paginate</title>
- <link href='pagination.css' rel='stylesheet' type='text/css' />
- <style type='text/css'>
- html {
- margin: 0;
- padding: 0;
- background: #999;
- font: normal 76% "Lucida Grande", Verdana, Helvetica, sans-serif; }
-
- body {
- margin: 2em;
- padding: 2em;
- border: 2px solid gray;
- background: white;
- color: #222; }
-
- h1 {
- font-size: 2em;
- font-weight: normal;
- margin: 0 0 1em 0; }
-
- h2 {
- font-size: 1.4em;
- margin: 1em 0 .5em 0; }
-
- pre {
- font-size: 13px;
- font-family: Monaco, "DejaVu Sans Mono", "Bitstream Vera Mono", "Courier New", monospace; }
- </style>
-</head>
-<body>
- <h1>Samples of pagination styling for will_paginate</h1>
- <p>
- Find these styles in <b>"examples/pagination.css"</b> of <i>will_paginate</i> library.
- There is a Sass version of it for all you sassy people.
- </p>
- <p>
- Read about good rules for pagination:
- <a href='http://kurafire.net/log/archive/2007/06/22/pagination-101'>Pagination 101</a>
- </p>
- <p>
- <em>Warning:</em>
- page links below don't lead anywhere (so don't click on them).
- </p>
- <h2>
- Unstyled pagination <span style="font-weight:normal">(<i>ewww!</i>)</span>
- </h2>
- <div>
- <span class="disabled prev_page">&laquo; Previous</span> <span class="current">1</span> <a href="./?page=2" rel="next">2</a> <a href="./?page=3">3</a> <a href="./?page=4">4</a> <a href="./?page=5">5</a> <a href="./?page=6">6</a> <a href="./?page=7">7</a> <a href="./?page=8">8</a> <a href="./?page=9">9</a> <span class="gap">&hellip;</span> <a href="./?page=29">29</a> <a href="./?page=30">30</a> <a href="./?page=2" rel="next" class="next_page">Next &raquo;</a>
- </div>
- <h2>Digg.com</h2>
- <div class='digg_pagination'>
- <span class="disabled prev_page">&laquo; Previous</span> <span class="current">1</span> <a href="./?page=2" rel="next">2</a> <a href="./?page=3">3</a> <a href="./?page=4">4</a> <a href="./?page=5">5</a> <a href="./?page=6">6</a> <a href="./?page=7">7</a> <a href="./?page=8">8</a> <a href="./?page=9">9</a> <span class="gap">&hellip;</span> <a href="./?page=29">29</a> <a href="./?page=30">30</a> <a href="./?page=2" rel="next" class="next_page">Next &raquo;</a>
- </div>
- <h2>Digg-style, no page links</h2>
- <div class='digg_pagination'>
- <span class="disabled prev_page">&laquo; Previous</span> <a href="./?page=2" rel="next" class="next_page">Next &raquo;</a>
- </div>
- <p>Code that renders this:</p>
- <pre>
- <code>&lt;%= will_paginate @posts, :page_links =&gt; false %&gt;</code>
- </pre>
- <h2>Digg-style, extra content</h2>
- <div class='digg_pagination'>
- <div class='page_info'>
- Displaying entries <b>1&nbsp;-&nbsp;6</b> of <b>180</b> in total
- </div>
- <span class="disabled prev_page">&laquo; Previous</span> <span class="current">1</span> <a href="./?page=2" rel="next">2</a> <a href="./?page=3">3</a> <a href="./?page=4">4</a> <a href="./?page=5">5</a> <a href="./?page=6">6</a> <a href="./?page=7">7</a> <a href="./?page=8">8</a> <a href="./?page=9">9</a> <span class="gap">&hellip;</span> <a href="./?page=29">29</a> <a href="./?page=30">30</a> <a href="./?page=2" rel="next" class="next_page">Next &raquo;</a>
- </div>
- <p>Code that renders this:</p>
- <pre>
- <code>&lt;div class="digg_pagination"&gt;
- &lt;div clas="page_info"&gt;
- &lt;%= page_entries_info @posts %&gt;
- &lt;/div&gt;
- &lt;%= will_paginate @posts, :container =&gt; false %&gt;
- &lt;/div&gt;</code>
- </pre>
- <h2>Apple.com store</h2>
- <div class='apple_pagination'>
- <span class="disabled prev_page">&laquo; Previous</span> <span class="current">1</span> <a href="./?page=2" rel="next">2</a> <a href="./?page=3">3</a> <a href="./?page=4">4</a> <a href="./?page=5">5</a> <a href="./?page=6">6</a> <a href="./?page=7">7</a> <a href="./?page=8">8</a> <a href="./?page=9">9</a> <span class="gap">&hellip;</span> <a href="./?page=29">29</a> <a href="./?page=30">30</a> <a href="./?page=2" rel="next" class="next_page">Next &raquo;</a>
- </div>
- <h2>Flickr.com</h2>
- <div class='flickr_pagination'>
- <span class="disabled prev_page">&laquo; Previous</span> <span class="current">1</span> <a href="./?page=2" rel="next">2</a> <a href="./?page=3">3</a> <a href="./?page=4">4</a> <a href="./?page=5">5</a> <a href="./?page=6">6</a> <a href="./?page=7">7</a> <a href="./?page=8">8</a> <a href="./?page=9">9</a> <span class="gap">&hellip;</span> <a href="./?page=29">29</a> <a href="./?page=30">30</a> <a href="./?page=2" rel="next" class="next_page">Next &raquo;</a>
- <div class='page_info'>(118 photos)</div>
- </div>
-</body>
View
90 vendor/plugins/will_paginate/examples/pagination.css
@@ -1,90 +0,0 @@
-.digg_pagination {
- background: white;
- /* self-clearing method: */ }
- .digg_pagination a, .digg_pagination span {
- padding: .2em .5em;
- display: block;
- float: left;
- margin-right: 1px; }
- .digg_pagination span.disabled {
- color: #999;
- border: 1px solid #DDD; }
- .digg_pagination span.current {
- font-weight: bold;
- background: #2E6AB1;
- color: white;
- border: 1px solid #2E6AB1; }
- .digg_pagination a {
- text-decoration: none;
- color: #105CB6;
- border: 1px solid #9AAFE5; }
- .digg_pagination a:hover, .digg_pagination a:focus {
- color: #003;
- border-color: #003; }
- .digg_pagination .page_info {
- background: #2E6AB1;
- color: white;
- padding: .4em .6em;
- width: 22em;
- margin-bottom: .3em;
- text-align: center; }
- .digg_pagination .page_info b {
- color: #003;
- background: #6aa6ed;
- padding: .1em .25em; }
- .digg_pagination:after {
- content: ".";
- display: block;
- height: 0;
- clear: both;
- visibility: hidden; }
- * html .digg_pagination {
- height: 1%; }
- *:first-child+html .digg_pagination {
- overflow: hidden; }
-
-.apple_pagination {
- background: #F1F1F1;
- border: 1px solid #E5E5E5;
- text-align: center;
- padding: 1em; }
- .apple_pagination a, .apple_pagination span {
- padding: .2em .3em; }
- .apple_pagination span.disabled {
- color: #AAA; }
- .apple_pagination span.current {
- font-weight: bold;
- background: transparent url(apple-circle.gif) no-repeat 50% 50%; }
- .apple_pagination a {
- text-decoration: none;
- color: black; }
- .apple_pagination a:hover, .apple_pagination a:focus {
- text-decoration: underline; }
-
-.flickr_pagination {
- text-align: center;
- padding: .3em; }
- .flickr_pagination a, .flickr_pagination span {
- padding: .2em .5em; }
- .flickr_pagination span.disabled {
- color: #AAA; }
- .flickr_pagination span.current {
- font-weight: bold;
- color: #FF0084; }
- .flickr_pagination a {
- border: 1px solid #DDDDDD;
- color: #0063DC;
- text-decoration: none; }
- .flickr_pagination a:hover, .flickr_pagination a:focus {
- border-color: #003366;
- background: #0063DC;
- color: white; }
- .flickr_pagination .page_info {
- color: #aaa;
- padding-top: .8em; }
- .flickr_pagination .prev_page, .flickr_pagination .next_page {
- border-width: 2px; }
- .flickr_pagination .prev_page {
- margin-right: 1em; }
- .flickr_pagination .next_page {
- margin-left: 1em; }
View
91 vendor/plugins/will_paginate/examples/pagination.sass
@@ -1,91 +0,0 @@
-.digg_pagination
- :background white
- a, span
- :padding .2em .5em
- :display block
- :float left
- :margin-right 1px
- span.disabled
- :color #999
- :border 1px solid #DDD
- span.current
- :font-weight bold
- :background #2E6AB1
- :color white
- :border 1px solid #2E6AB1
- a
- :text-decoration none
- :color #105CB6
- :border 1px solid #9AAFE5
- &:hover, &:focus
- :color #003
- :border-color #003
- .page_info
- :background #2E6AB1
- :color white
- :padding .4em .6em
- :width 22em
- :margin-bottom .3em
- :text-align center
- b
- :color #003
- :background = #2E6AB1 + 60
- :padding .1em .25em
-
- /* self-clearing method:
- &:after
- :content "."
- :display block
- :height 0
- :clear both
- :visibility hidden
- * html &
- :height 1%
- *:first-child+html &
- :overflow hidden
-
-.apple_pagination
- :background #F1F1F1
- :border 1px solid #E5E5E5
- :text-align center
- :padding 1em
- a, span
- :padding .2em .3em
- span.disabled
- :color #AAA
- span.current
- :font-weight bold
- :background transparent url(apple-circle.gif) no-repeat 50% 50%
- a
- :text-decoration none
- :color black
- &:hover, &:focus
- :text-decoration underline
-
-.flickr_pagination
- :text-align center
- :padding .3em
- a, span
- :padding .2em .5em
- span.disabled
- :color #AAA
- span.current
- :font-weight bold
- :color #FF0084
- a
- :border 1px solid #DDDDDD
- :color #0063DC
- :text-decoration none
- &:hover, &:focus
- :border-color #003366
- :background #0063DC
- :color white
- .page_info
- :color #aaa
- :padding-top .8em
- .prev_page, .next_page
- :border-width 2px
- .prev_page
- :margin-right 1em
- .next_page
- :margin-left 1em
View
89 vendor/plugins/will_paginate/lib/will_paginate.rb
@@ -1,90 +1,23 @@
-require 'active_support'
-require 'will_paginate/core_ext'
+require 'will_paginate/deprecation'
# = 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
- class << self
- # shortcut for <tt>enable_actionpack</tt> and <tt>enable_activerecord</tt> combined
- def enable
- enable_actionpack
- enable_activerecord
- end
-
- # hooks WillPaginate::ViewHelpers into ActionView::Base
- def enable_actionpack
- return if ActionView::Base.instance_methods.include_method? :will_paginate
- require 'will_paginate/view_helpers'
- ActionView::Base.send :include, ViewHelpers
-
- if defined?(ActionController::Base) and ActionController::Base.respond_to? :rescue_responses
- ActionController::Base.rescue_responses['WillPaginate::InvalidPage'] = :not_found
- end
- end
-
- # hooks WillPaginate::Finder into ActiveRecord::Base and classes that deal
- # with associations
- def enable_activerecord
- return if ActiveRecord::Base.respond_to? :paginate
- require 'will_paginate/finder'
- ActiveRecord::Base.send :include, Finder
-
- # support pagination on associations
- a = ActiveRecord::Associations
- returning([ a::AssociationCollection ]) { |classes|
- # detect http://dev.rubyonrails.org/changeset/9230
- unless a::HasManyThroughAssociation.superclass == a::HasManyAssociation
- classes << a::HasManyThroughAssociation
- end
- }.each do |klass|
- klass.send :include, Finder::ClassMethods
- klass.class_eval { alias_method_chain :method_missing, :paginate }
- end
-
- # monkeypatch Rails ticket #2189: "count breaks has_many :through"
- ActiveRecord::Base.class_eval do
- protected
- def self.construct_count_options_from_args(*args)
- result = super
- result[0] = '*' if result[0].is_a?(String) and result[0] =~ /\.\*$/
- result
- end
- end
- end
-
- # Enable named_scope, a feature of Rails 2.1, even if you have older Rails
- # (tested on Rails 2.0.2 and 1.2.6).
- #
- # You can pass +false+ for +patch+ parameter to skip monkeypatching
- # *associations*. Use this if you feel that <tt>named_scope</tt> broke
- # has_many, has_many :through or has_and_belongs_to_many associations in
- # your app. By passing +false+, you can still use <tt>named_scope</tt> in
- # your models, but not through associations.
- def enable_named_scope(patch = true)
- return if defined? ActiveRecord::NamedScope
- require 'will_paginate/named_scope'
- require 'will_paginate/named_scope_patch' if patch
-
- ActiveRecord::Base.send :include, WillPaginate::NamedScope
- end
- end
-
- module Deprecation # :nodoc:
- extend ActiveSupport::Deprecation
+end
- def self.warn(message, callstack = caller)
- message = 'WillPaginate: ' + message.strip.gsub(/\s+/, ' ')
- ActiveSupport::Deprecation.warn(message, callstack)
- end
- end
+if defined?(::Rails::Railtie)
+ require 'will_paginate/railtie'
end
-if defined? Rails
- WillPaginate.enable_activerecord if defined? ActiveRecord
- WillPaginate.enable_actionpack if defined? ActionController
+if defined?(::Merb::Plugins)
+ require 'will_paginate/view_helpers/merb'
+ # auto-load the right ORM adapter
+ if adapter = { :datamapper => 'data_mapper', :activerecord => 'active_record', :sequel => 'sequel' }[Merb.orm]
+ require "will_paginate/finders/#{adapter}"
+ end
end
View
33 vendor/plugins/will_paginate/lib/will_paginate/array.rb
@@ -1,16 +1,33 @@
require 'will_paginate/collection'
-# http://www.desimcadam.com/archives/8
-Array.class_eval do
+class Array
+ # Paginates a static array (extracting a subset of it). The result is a
+ # WillPaginate::Collection instance, which is an array with a few more
+ # properties about its paginated state.
+ #
+ # Parameters:
+ # * <tt>:page</tt> - current page, defaults to 1
+ # * <tt>:per_page</tt> - limit of items per page, defaults to 30
+ # * <tt>:total_entries</tt> - total number of items in the array, defaults to
+ # <tt>array.length</tt> (obviously)
+ #
+ # Example:
+ # arr = ['a', 'b', 'c', 'd', 'e']
+ # paged = arr.paginate(:per_page => 2) #-> ['a', 'b']
+ # paged.total_entries #-> 5
+ # arr.paginate(:page => 2, :per_page => 2) #-> ['c', 'd']
+ # arr.paginate(:page => 3, :per_page => 2) #-> ['e']
+ #
+ # This method was originally {suggested by Desi
+ # McAdam}[http://www.desimcadam.com/archives/8] and later proved to be the
+ # most useful method of will_paginate library.
def paginate(options = {})
raise ArgumentError, "parameter hash expected (got #{options.inspect})" unless Hash === options
- WillPaginate::Collection.create(
- options[:page] || 1,
- options[:per_page] || 30,
- options[:total_entries] || self.length
- ) { |pager|
+ WillPaginate::Collection.create options[:page] || 1,
+ options[:per_page] || 30,
+ options[:total_entries] || self.length do |pager|
pager.replace self[pager.offset, pager.per_page].to_a
- }
+ end
end
end
View
15 vendor/plugins/will_paginate/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
@@ -33,10 +33,12 @@ def initialize(page, page_num)
#
# If you are writing a library that provides a collection which you would like
# to conform to this API, you don't have to copy these methods over; simply
- # make your plugin/gem dependant on this library and do:
+ # make your plugin/gem dependant on the "will_paginate" gem:
#
+ # gem 'will_paginate'
# require 'will_paginate/collection'
- # # WillPaginate::Collection is now available for use
+ #
+ # # now use WillPaginate::Collection directly or subclass it
class Collection < Array
attr_reader :current_page, :per_page, :total_entries, :total_pages
@@ -80,7 +82,7 @@ def initialize(page, per_page, total = nil)
#
# The Array#paginate API has since then changed, but this still serves as a
# fine example of WillPaginate::Collection usage.
- def self.create(page, per_page, total = nil)
+ def self.create(page, per_page, total = nil, &block)
pager = new(page, per_page, total)
yield pager
pager
@@ -96,7 +98,7 @@ def out_of_bounds?
# Current offset of the paginated collection. If we're on the first page,
# it is always 0. If we're on the 2nd page and there are 30 entries per page,
# the offset is 30. This property is useful if you want to render ordinals
- # side by side with records in the view: simply start with offset + 1.
+ # besides your records: simply start with offset + 1.
def offset
(current_page - 1) * per_page
end
@@ -110,8 +112,7 @@ def previous_page
def next_page
current_page < total_pages ? (current_page + 1) : nil
end
-
- # sets the <tt>total_entries</tt> property and calculates <tt>total_pages</tt>
+
def total_entries=(number)
@total_entries = number.to_i
@total_pages = (@total_entries / per_page.to_f).ceil
View
26 vendor/plugins/will_paginate/lib/will_paginate/core_ext.rb
@@ -12,6 +12,8 @@ def include_method?(name)
end
end
+## everything below copied from ActiveSupport so we don't depend on it ##
+
unless Hash.instance_methods.include_method? :except
Hash.class_eval do
# Returns a new hash without the given keys.
@@ -41,3 +43,27 @@ def slice!(*keys)
end
end
end
+
+unless String.instance_methods.include_method? :constantize
+ String.class_eval do
+ def constantize
+ unless /\A(?:::)?([A-Z]\w*(?:::[A-Z]\w*)*)\z/ =~ self
+ raise NameError, "#{self.inspect} is not a valid constant name!"
+ end
+
+ Object.module_eval("::#{$1}", __FILE__, __LINE__)
+ end
+ end
+end
+
+unless String.instance_methods.include_method? :underscore
+ String.class_eval do
+ def underscore
+ self.to_s.gsub(/::/, '/').
+ gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
+ gsub(/([a-z\d])([A-Z])/,'\1_\2').
+ tr("-", "_").
+ downcase
+ end
+ end
+end
View
50 vendor/plugins/will_paginate/lib/will_paginate/deprecation.rb
@@ -0,0 +1,50 @@
+# borrowed from ActiveSupport::Deprecation
+module WillPaginate
+ module Deprecation
+ def self.debug() @debug; end
+ def self.debug=(value) @debug = value; end
+ self.debug = false
+
+ # Choose the default warn behavior according to Rails.env.
+ # Ignore deprecation warnings in production.
+ BEHAVIORS = {
+ 'test' => Proc.new { |message, callstack|
+ $stderr.puts(message)
+ $stderr.puts callstack.join("\n ") if debug
+ },
+ 'development' => Proc.new { |message, callstack|
+ logger = defined?(::RAILS_DEFAULT_LOGGER) ? ::RAILS_DEFAULT_LOGGER : Logger.new($stderr)
+ logger.warn message
+ logger.debug callstack.join("\n ") if debug
+ }
+ }
+
+ def self.warn(message, callstack = caller)
+ if behavior
+ message = 'WillPaginate: ' + message.strip.gsub(/\s+/, ' ')
+ behavior.call(message, callstack)
+ end
+ end
+
+ def self.default_behavior
+ if defined?(::Rails)
+ BEHAVIORS[::Rails.env.to_s]
+ else
+ BEHAVIORS['test']
+ end
+ end
+
+ # Behavior is a block that takes a message argument.
+ def self.behavior() @behavior; end
+ def self.behavior=(value) @behavior = value; end
+ self.behavior = default_behavior
+
+ def self.silence
+ old_behavior = self.behavior
+ self.behavior = nil
+ yield
+ ensure
+ self.behavior = old_behavior
+ end
+ end
+end
View
264 vendor/plugins/will_paginate/lib/will_paginate/finder.rb
@@ -1,264 +0,0 @@
-require 'will_paginate/core_ext'
-
-module WillPaginate
- # A mixin for ActiveRecord::Base. Provides +per_page+ class method
- # and hooks things up to provide paginating finders.
- #
- # Find out more in WillPaginate::Finder::ClassMethods
- #
- module Finder
- def self.included(base)
- base.extend ClassMethods
- class << base
- alias_method_chain :method_missing, :paginate
- # alias_method_chain :find_every, :paginate
- define_method(:per_page) { 30 } unless respond_to?(:per_page)
- end
- end
-
- # = Paginating finders for ActiveRecord models
- #
- # WillPaginate adds +paginate+, +per_page+ and other methods to
- # ActiveRecord::Base class methods and associations. It also hooks into
- # +method_missing+ to intercept pagination calls to dynamic finders such as
- # +paginate_by_user_id+ and translate them to ordinary finders
- # (+find_all_by_user_id+ in this case).
- #
- # In short, paginating finders are equivalent to ActiveRecord finders; the
- # only difference is that we start with "paginate" instead of "find" and
- # that <tt>:page</tt> is required parameter:
- #
- # @posts = Post.paginate :all, :page => params[:page], :order => 'created_at DESC'
- #
- # In paginating finders, "all" is implicit. There is no sense in paginating
- # a single record, right? So, you can drop the <tt>:all</tt> argument:
- #
- # Post.paginate(...) => Post.find :all
- # Post.paginate_all_by_something => Post.find_all_by_something
- # Post.paginate_by_something => Post.find_all_by_something
- #
- # == The importance of the <tt>:order</tt> parameter
- #
- # In ActiveRecord finders, <tt>:order</tt> parameter specifies columns for
- # the <tt>ORDER BY</tt> clause in SQL. It is important to have it, since
- # pagination only makes sense with ordered sets. Without the <tt>ORDER
- # BY</tt> clause, databases aren't required to do consistent ordering when
- # performing <tt>SELECT</tt> queries; this is especially true for
- # PostgreSQL.
- #
- # Therefore, make sure you are doing ordering on a column that makes the
- # most sense in the current context. Make that obvious to the user, also.
- # For perfomance reasons you will also want to add an index to that column.
- module ClassMethods
- # This is the main paginating finder.
- #
- # == Special parameters for paginating finders
- # * <tt>:page</tt> -- REQUIRED, but defaults to 1 if false or nil
- # * <tt>:per_page</tt> -- defaults to <tt>CurrentModel.per_page</tt> (which is 30 if not overridden)
- # * <tt>:total_entries</tt> -- use only if you manually count total entries
- # * <tt>:count</tt> -- additional options that are passed on to +count+
- # * <tt>:finder</tt> -- name of the ActiveRecord finder used (default: "find")
- #
- # All other options (+conditions+, +order+, ...) are forwarded to +find+
- # and +count+ calls.
- def paginate(*args)
- options = args.pop
- page, per_page, total_entries = wp_parse_options(options)
- finder = (options[:finder] || 'find').to_s
-
- if finder == 'find'
- # an array of IDs may have been given:
- total_entries ||= (Array === args.first and args.first.size)
- # :all is implicit
- args.unshift(:all) if args.empty?
- end
-
- WillPaginate::Collection.create(page, per_page, total_entries) do |pager|
- count_options = options.except :page, :per_page, :total_entries, :finder
- find_options = count_options.except(:count).update(:offset => pager.offset, :limit => pager.per_page)
-
- args << find_options
- # @options_from_last_find = nil
- pager.replace(send(finder, *args) { |*a| yield(*a) if block_given? })
-
- # magic counting for user convenience:
- pager.total_entries = wp_count(count_options, args, finder) unless pager.total_entries
- end
- end
-
- # Iterates through all records by loading one page at a time. This is useful
- # for migrations or any other use case where you don't want to load all the
- # records in memory at once.
- #
- # It uses +paginate+ internally; therefore it accepts all of its options.
- # You can specify a starting page with <tt>:page</tt> (default is 1). Default
- # <tt>:order</tt> is <tt>"id"</tt>, override if necessary.
- #
- # See {Faking Cursors in ActiveRecord}[http://weblog.jamisbuck.org/2007/4/6/faking-cursors-in-activerecord]
- # where Jamis Buck describes this and a more efficient way for MySQL.
- def paginated_each(options = {})
- options = { :order => 'id', :page => 1 }.merge options
- options[:page] = options[:page].to_i
- options[:total_entries] = 0 # skip the individual count queries
- total = 0
-
- begin
- collection = paginate(options)
- with_exclusive_scope(:find => {}) do
- # using exclusive scope so that the block is yielded in scope-free context
- total += collection.each { |item| yield item }.size
- end
- options[:page] += 1
- end until collection.size < collection.per_page
-
- total
- end
-
- # Wraps +find_by_sql+ by simply adding LIMIT and OFFSET to your SQL string
- # based on the params otherwise used by paginating finds: +page+ and
- # +per_page+.
- #
- # Example:
- #
- # @developers = Developer.paginate_by_sql ['select * from developers where salary > ?', 80000],
- # :page => params[:page], :per_page => 3
- #
- # A query for counting rows will automatically be generated if you don't
- # supply <tt>:total_entries</tt>. If you experience problems with this
- # generated SQL, you might want to perform the count manually in your
- # application.
- #
- def paginate_by_sql(sql, options)
- WillPaginate::Collection.create(*wp_parse_options(options)) do |pager|
- query = sanitize_sql(sql.dup)
- original_query = query.dup
- # add limit, offset
- add_limit! query, :offset => pager.offset, :limit => pager.per_page
- # perfom the find
- pager.replace find_by_sql(query)
-
- unless pager.total_entries
- count_query = original_query.sub /\bORDER\s+BY\s+[\w`,\s]+$/mi, ''
- count_query = "SELECT COUNT(*) FROM (#{count_query})"
-
- unless self.connection.adapter_name =~ /^(oracle|oci$)/i
- count_query << ' AS count_table'
- end
- # perform the count query
- pager.total_entries = count_by_sql(count_query)
- end
- end
- end
-
- def respond_to?(method, include_priv = false) #:nodoc:
- case method.to_sym
- when :paginate, :paginate_by_sql
- true
- else
- super(method.to_s.sub(/^paginate/, 'find'), include_priv)
- end
- end
-
- protected
-
- def method_missing_with_paginate(method, *args) #:nodoc:
- # did somebody tried to paginate? if not, let them be
- unless method.to_s.index('paginate') == 0
- if block_given?
- return method_missing_without_paginate(method, *args) { |*a| yield(*a) }
- else
- return method_missing_without_paginate(method, *args)
- end
- end
-
- # paginate finders are really just find_* with limit and offset
- finder = method.to_s.sub('paginate', 'find')
- finder.sub!('find', 'find_all') if finder.index('find_by_') == 0
-
- options = args.pop
- raise ArgumentError, 'parameter hash expected' unless options.respond_to? :symbolize_keys
- options = options.dup
- options[:finder] = finder
- args << options
-
- paginate(*args) { |*a| yield(*a) if block_given? }
- end
-
- # 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)
- excludees = [:count, :order, :limit, :offset, :readonly]
- excludees << :from unless ActiveRecord::Calculations::CALCULATIONS_OPTIONS.include?(:from)
-
- # we may be in a model or an association proxy
- klass = (@owner and @reflection) ? @reflection.klass : self
-
- # Use :select from scope if it isn't already present.
- options[:select] = scope(:find, :select) unless options[:select]
-
- if options[:select] and options[:select] =~ /^\s*DISTINCT\b/i
- # Remove quoting and check for table_name.*-like statement.
- if options[:select].gsub('`', '') =~ /\w+\.\*/
- options[:select] = "DISTINCT #{klass.table_name}.#{klass.primary_key}"
- end
- else
- excludees << :select # only exclude the select param if it doesn't begin with DISTINCT
- end
-
- # count expects (almost) the same options as find
- count_options = options.except *excludees
-
- # merge the hash found in :count
- # this allows you to specify :select, :order, or anything else just for the count query
- count_options.update options[:count] if options[:count]
-
- # forget about includes if they are irrelevant (Rails 2.1)
- if count_options[:include] and
- klass.private_methods.include_method?(:references_eager_loaded_tables?) and
- !klass.send(:references_eager_loaded_tables?, count_options)
- count_options.delete :include
- end
-
- # we may have to scope ...
- counter = Proc.new { count(count_options) }
-
- count = if finder.index('find_') == 0 and klass.respond_to?(scoper = finder.sub('find', 'with'))
- # scope_out adds a 'with_finder' method which acts like with_scope, if it's present
- # then execute the count with the scoping provided by the with_finder
- send(scoper, &counter)
- elsif finder =~ /^find_(all_by|by)_([_a-zA-Z]\w*)$/
- # extract conditions from calls like "paginate_by_foo_and_bar"
- attribute_names = $2.split('_and_')
- conditions = construct_attributes_from_arguments(attribute_names, args)
- with_scope(:find => { :conditions => conditions }, &counter)
- else
- counter.call
- end
-
- count.respond_to?(:length) ? count.length : count
- end
-
- def wp_parse_options(options) #:nodoc:
- raise ArgumentError, 'parameter hash expected' unless options.respond_to? :symbolize_keys
- options = options.symbolize_keys
- raise ArgumentError, ':page parameter required' unless options.key? :page
-
- if options[:count] and options[:total_entries]
- raise ArgumentError, ':count and :total_entries are mutually exclusive'
- end
-
- page = options[:page] || 1
- per_page = options[:per_page] || self.per_page
- total = options[:total_entries]
- [page, per_page, total]
- end
-
- private
-
- # def find_every_with_paginate(options)
- # @options_from_last_find = options
- # find_every_without_paginate(options)
- # end
- end
- end
-end
View
9 vendor/plugins/will_paginate/lib/will_paginate/finders.rb
@@ -0,0 +1,9 @@
+require 'will_paginate/core_ext'
+
+module WillPaginate
+ # Database logic for different ORMs
+ #
+ # See WillPaginate::Finders::Base
+ module Finders
+ end
+end
View
158 vendor/plugins/will_paginate/lib/will_paginate/finders/active_record.rb
@@ -0,0 +1,158 @@
+require 'will_paginate/finders/base'
+require 'active_record'
+
+module WillPaginate::Finders
+ # = Paginating finders for ActiveRecord models
+ #
+ # WillPaginate adds +paginate+, +per_page+ and other methods to
+ # ActiveRecord::Base class methods and associations. It also hooks into
+ # +method_missing+ to intercept pagination calls to dynamic finders such as
+ # +paginate_by_user_id+ and translate them to ordinary finders
+ # (+find_all_by_user_id+ in this case).
+ #
+ # In short, paginating finders are equivalent to ActiveRecord finders; the
+ # only difference is that we start with "paginate" instead of "find" and
+ # that <tt>:page</tt> is required parameter:
+ #
+ # @posts = Post.paginate :all, :page => params[:page], :order => 'created_at DESC'
+ #
+ # In paginating finders, "all" is implicit. There is no sense in paginating
+ # a single record, right? So, you can drop the <tt>:all</tt> argument:
+ #
+ # Post.paginate(...) => Post.find :all
+ # Post.paginate_all_by_something => Post.find_all_by_something
+ # Post.paginate_by_something => Post.find_all_by_something
+ #
+ module ActiveRecord
+ include WillPaginate::Finders::Base
+
+ # In Rails, this is automatically called to mix-in pagination functionality to ActiveRecord.
+ def self.enable!
+ ::ActiveRecord::Base.class_eval do
+ extend ActiveRecord
+ end
+
+ # support pagination on associations and scopes
+ [::ActiveRecord::Relation, ::ActiveRecord::Associations::AssociationCollection].each do |klass|
+ klass.send(:include, ActiveRecord)
+ end
+ end
+
+ # Wraps +find_by_sql+ by simply adding LIMIT and OFFSET to your SQL string
+ # based on the params otherwise used by paginating finds: +page+ and
+ # +per_page+.
+ #
+ # Example:
+ #
+ # @developers = Developer.paginate_by_sql ['select * from developers where salary > ?', 80000],
+ # :page => params[:page], :per_page => 3
+ #
+ # A query for counting rows will automatically be generated if you don't
+ # supply <tt>:total_entries</tt>. If you experience problems with this
+ # generated SQL, you might want to perform the count manually in your
+ # application.
+ #
+ def paginate_by_sql(sql, options)
+ WillPaginate::Collection.create(*wp_parse_options(options)) do |pager|
+ query = sanitize_sql(sql.dup)
+ original_query = query.dup
+ # add limit, offset
+ query << " LIMIT #{pager.per_page} OFFSET #{pager.offset}"
+ # perfom the find
+ pager.replace find_by_sql(query)
+
+ unless pager.total_entries
+ count_query = original_query.sub /\bORDER\s+BY\s+[\w`,\s]+$/mi, ''
+ count_query = "SELECT COUNT(*) FROM (#{count_query})"
+
+ unless ['oracle', 'oci'].include?(self.connection.adapter_name.downcase)
+ count_query << ' AS count_table'
+ end
+ # perform the count query
+ pager.total_entries = count_by_sql(count_query)
+ end
+ end
+ end
+
+ protected
+
+ 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)
+
+ if finder == 'find'
+ if Array === args.first and !pager.total_entries
+ pager.total_entries = args.first.size
+ end
+ args << :all if args.empty?
+ end
+
+ args << find_options
+ pager.replace send(finder, *args, &block)
+
+ unless pager.total_entries
+ # magic counting
+ pager.total_entries = wp_count(options, args, finder)
+ end
+ end
+
+ # 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) #: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)
+
+ # we may have to scope ...
+ counter = Proc.new { count(count_options) }
+
+ count = if finder.index('find_') == 0 and klass.respond_to?(scoper = finder.sub('find', 'with'))
+ # scope_out adds a 'with_finder' method which acts like with_scope, if it's present
+ # then execute the count with the scoping provided by the with_finder
+ send(scoper, &counter)
+ elsif finder =~ /^find_(all_by|by)_([_a-zA-Z]\w*)$/
+ # extract conditions from calls like "paginate_by_foo_and_bar"
+ attribute_names = $2.split('_and_')
+ conditions = construct_attributes_from_arguments(attribute_names, args)
+ with_scope(:find => { :conditions => conditions }, &counter)
+ else
+ counter.call
+ end
+
+ count.respond_to?(:length) ? count.length : count
+ end
+
+ def wp_parse_count_options(options, klass) #:nodoc:
+ excludees = [:count, :order, :limit, :offset, :readonly]
+
+ # Use :select from scope if it isn't already present.
+ # FIXME: this triggers extra queries when going through associations
+ # if options[:select].blank? && current_scoped_methods && current_scoped_methods.select_values.present?
+ # options[:select] = current_scoped_methods.select_values.join(", ")
+ # end
+
+ if options[:select] and options[:select] =~ /^\s*DISTINCT\b/i
+ # Remove quoting and check for table_name.*-like statement.
+ if options[:select].gsub('`', '') =~ /\w+\.\*/
+ options[:select] = "DISTINCT #{klass.table_name}.#{klass.primary_key}"
+ end
+ else
+ excludees << :select
+ end
+
+ # count expects (almost) the same options as find
+ count_options = options.except *excludees
+
+ # merge the hash found in :count
+ # this allows you to specify :select, :order, or anything else just for the count query
+ count_options.update options[:count] if options[:count]
+
+ # forget about includes if they are irrelevant when counting
+ if count_options[:include] and count_options[:conditions].blank? and count_options[:group].blank?
+ count_options.delete :include
+ end
+
+ count_options
+ end
+ end
+end
View
51 vendor/plugins/will_paginate/lib/will_paginate/finders/active_resource.rb
@@ -0,0 +1,51 @@
+require 'will_paginate/finders/base'
+require 'active_resource'
+
+module WillPaginate::Finders
+ # Paginate your ActiveResource models.
+ #
+ # @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) #:nodoc:
+ unless args.empty? or args.first == :all
+ raise ArgumentError, "finder arguments other than :all are not supported for pagination (#{args.inspect} given)"
+ end
+ params = (options[:params] ||= {})
+ params[:page] = pager.current_page
+ params[:per_page] = pager.per_page
+
+ pager.replace find_every(options, &block)
+ end
+
+ # Takes the format that Hash.from_xml produces out of an unknown type
+ # (produced by WillPaginate::Collection#to_xml_with_collection_type),
+ # 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 = {}) #: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)
+ instantiated_collection = WillPaginate::Collection.create(collection["current_page"], collection["per_page"], collection["total_entries"]) do |pager|
+ pager.replace instantiate_collection_without_collection(collectables, prefix_options)
+ end
+ else
+ instantiate_collection_without_collection(collection, prefix_options)
+ end
+ end
+ end
+end
+
+ActiveResource::Base.class_eval do
+ extend WillPaginate::Finders::ActiveResource
+ class << self
+ # alias_method_chain :instantiate_collection, :collection
+ end
+end
View
112 vendor/plugins/will_paginate/lib/will_paginate/finders/base.rb
@@ -0,0 +1,112 @@
+require 'will_paginate/core_ext'
+
+module WillPaginate
+ module Finders
+ # = 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.
+ #
+ # == The importance of SQL's <tt>ORDER BY</tt>
+ #
+ # In most ORMs, <tt>:order</tt> parameter specifies columns for the
+ # <tt>ORDER BY</tt> clause in SQL. It is important to have it, since
+ # pagination only makes sense with ordered sets. Without the order clause,
+ # databases aren't required to do consistent ordering when performing
+ # <tt>SELECT</tt> queries.
+ #
+ # Ordering by a field for which many records share the same value (e.g.
+ # "status") can still result in incorrect ordering with some databases (MS
+ # SQL and Postgres for instance). With these databases it's recommend that
+ # you order by primary key as well. That is, instead of ordering by
+ # "status DESC", use the alternative "status DESC, id DESC" and this will
+ # yield consistent results.
+ #
+ # Therefore, make sure you are doing ordering on a column that makes the
+ # most sense in the current context. Make that obvious to the user, also.
+ # For perfomance reasons you will also want to add an index to that column.
+ module Base
+ def per_page
+ @per_page ||= 30
+ end
+
+ def per_page=(limit)
+ @per_page = limit.to_i
+ end
+
+ # This is the main paginating finder.
+ #
+ # == Special parameters for paginating finders
+ # * <tt>:page</tt> -- REQUIRED, but defaults to 1 if false or nil
+ # * <tt>:per_page</tt> -- defaults to <tt>CurrentModel.per_page</tt> (which is 30 if not overridden)
+ # * <tt>:total_entries</tt> -- use only if you manually count total entries
+ # * <tt>:count</tt> -- additional options that are passed on to +count+
+ # * <tt>:finder</tt> -- name of the finder method to use (default: "find")
+ #
+ # All other options (+conditions+, +order+, ...) are forwarded to +find+
+ # and +count+ calls.
+ def paginate(*args, &block)
+ options = args.pop
+ page, per_page, total_entries = wp_parse_options(options)
+
+ WillPaginate::Collection.create(page, per_page, total_entries) do |pager|
+ query_options = options.except :page, :per_page, :total_entries
+ wp_query(query_options, pager, args, &block)
+ end
+ end
+
+ # Iterates through all records by loading one page at a time. This is useful
+ # for migrations or any other use case where you don't want to load all the
+ # records in memory at once.
+ #
+ # It uses +paginate+ internally; therefore it accepts all of its options.
+ # You can specify a starting page with <tt>:page</tt> (default is 1). Default
+ # <tt>:order</tt> is <tt>"id"</tt>, override if necessary.
+ #
+ # {Jamis Buck describes this}[http://weblog.jamisbuck.org/2007/4/6/faking-cursors-in-activerecord]
+ # and also uses a more efficient way for MySQL.
+ def paginated_each(options = {}, &block)
+ options = { :order => 'id', :page => 1 }.merge options
+ options[:page] = options[:page].to_i
+ options[:total_entries] = 0 # skip the individual count queries
+ total = 0
+
+ begin
+ collection = paginate(options)
+ total += collection.each(&block).size
+ options[:page] += 1
+ end until collection.size < collection.per_page
+
+ total
+ end
+
+ protected
+
+ def wp_parse_options(options) #:nodoc:
+ raise ArgumentError, 'parameter hash expected' unless Hash === options
+ raise ArgumentError, ':page parameter required' unless options.key? :page
+
+ if options[:count] and options[:total_entries]
+ raise ArgumentError, ':count and :total_entries are mutually exclusive'
+ end
+
+ page = options[:page] || 1
+ per_page = options[:per_page] || self.per_page
+ total = options[:total_entries]
+
+ return [page, per_page, total]
+ end
+
+ end
+ end
+end
View
30 vendor/plugins/will_paginate/lib/will_paginate/finders/data_mapper.rb
@@ -0,0 +1,30 @@
+require 'will_paginate/finders/base'
+require 'dm-core'
+
+module WillPaginate::Finders
+ module DataMapper
+ include WillPaginate::Finders::Base
+
+ protected
+
+ 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)
+
+ unless pager.total_entries
+ pager.total_entries = wp_count(options)
+ end
+ end
+
+ 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]
+
+ count_options.empty?? count() : count(count_options)
+ end
+ end
+end
+
+DataMapper::Model.send(:include, WillPaginate::Finders::DataMapper)
View
23 vendor/plugins/will_paginate/lib/will_paginate/finders/sequel.rb
@@ -0,0 +1,23 @@
+require 'will_paginate/core_ext'
+require 'sequel'
+require 'sequel/extensions/pagination'
+
+existing_methods = Sequel::Dataset::Pagination.instance_methods
+
+Sequel::Dataset::Pagination.module_eval do
+ # it should quack like a WillPaginate::Collection
+
+ alias :total_pages :page_count unless existing_methods.include_method? :total_pages
+ alias :per_page :page_size unless existing_methods.include_method? :per_page
+ alias :previous_page :prev_page unless existing_methods.include_method? :previous_page
+ alias :total_entries :pagination_record_count unless existing_methods.include_method? :total_entries
+
+ def out_of_bounds?
+ current_page > total_pages
+ end
+
+ # Current offset of the paginated collection
+ def offset
+ (current_page - 1) * per_page
+ end
+end
View
170 vendor/plugins/will_paginate/lib/will_paginate/named_scope.rb
@@ -1,170 +0,0 @@
-module WillPaginate
- # This is a feature backported from Rails 2.1 because of its usefullness not only with will_paginate,
- # but in other aspects when managing complex conditions that you want to be reusable.
- module NamedScope
- # All subclasses of ActiveRecord::Base have two named_scopes:
- # * <tt>all</tt>, which is similar to a <tt>find(:all)</tt> query, and
- # * <tt>scoped</tt>, which allows for the creation of anonymous scopes, on the fly: <tt>Shirt.scoped(:conditions => {:color => 'red'}).scoped(:include => :washing_instructions)</tt>
- #
- # These anonymous scopes tend to be useful when procedurally generating complex queries, where passing
- # intermediate values (scopes) around as first-class objects is convenient.
- def self.included(base)
- base.class_eval do
- extend ClassMethods
- named_scope :scoped, lambda { |scope| scope }
- end
- end
-
- module ClassMethods
- def scopes
- read_inheritable_attribute(:scopes) || write_inheritable_attribute(:scopes, {})
- end
-
- # Adds a class method for retrieving and querying objects. A scope represents a narrowing of a database query,
- # such as <tt>:conditions => {:color => :red}, :select => 'shirts.*', :include => :washing_instructions</tt>.
- #
- # class Shirt < ActiveRecord::Base
- # named_scope :red, :conditions => {:color => 'red'}
- # named_scope :dry_clean_only, :joins => :washing_instructions, :conditions => ['washing_instructions.dry_clean_only = ?', true]
- # end
- #
- # The above calls to <tt>named_scope</tt> define class methods <tt>Shirt.red</tt> and <tt>Shirt.dry_clean_only</tt>. <tt>Shirt.red</tt>,
- # in effect, represents the query <tt>Shirt.find(:all, :conditions => {:color => 'red'})</tt>.
- #
- # Unlike Shirt.find(...), however, the object returned by <tt>Shirt.red</tt> is not an Array; it resembles the association object
- # constructed by a <tt>has_many</tt> declaration. For instance, you can invoke <tt>Shirt.red.find(:first)</tt>, <tt>Shirt.red.count</tt>,
- # <tt>Shirt.red.find(:all, :conditions => {:size => 'small'})</tt>. Also, just
- # as with the association objects, name scopes acts like an Array, implementing Enumerable; <tt>Shirt.red.each(&block)</tt>,
- # <tt>Shirt.red.first</tt>, and <tt>Shirt.red.inject(memo, &block)</tt> all behave as if Shirt.red really were an Array.
- #
- # These named scopes are composable. For instance, <tt>Shirt.red.dry_clean_only</tt> will produce all shirts that are both red and dry clean only.
- # Nested finds and calculations also work with these compositions: <tt>Shirt.red.dry_clean_only.count</tt> returns the number of garments
- # for which these criteria obtain. Similarly with <tt>Shirt.red.dry_clean_only.average(:thread_count)</tt>.
- #
- # All scopes are available as class methods on the ActiveRecord::Base descendent upon which the scopes were defined. But they are also available to
- # <tt>has_many</tt> associations. If,
- #
- # class Person < ActiveRecord::Base
- # has_many :shirts
- # end
- #
- # then <tt>elton.shirts.red.dry_clean_only</tt> will return all of Elton's red, dry clean
- # only shirts.
- #
- # Named scopes can also be procedural.
- #
- # class Shirt < ActiveRecord::Base
- # named_scope :colored, lambda { |color|
- # { :conditions => { :color => color } }
- # }
- # end
- #
- # In this example, <tt>Shirt.colored('puce')</tt> finds all puce shirts.
- #
- # Named scopes can also have extensions, just as with <tt>has_many</tt> declarations:
- #
- # class Shirt < ActiveRecord::Base
- # named_scope :red, :conditions => {:color => 'red'} do
- # def dom_id
- # 'red_shirts'
- # end
- # end
- # end
- #
- #
- # For testing complex named scopes, you can examine the scoping options using the
- # <tt>proxy_options</tt> method on the proxy itself.
- #
- # class Shirt < ActiveRecord::Base
- # named_scope :colored, lambda { |color|
- # { :conditions => { :color => color } }
- # }
- # end
- #
- # expected_options = { :conditions => { :colored => 'red' } }
- # assert_equal expected_options, Shirt.colored('red').proxy_options
- def named_scope(name, options = {})
- name = name.to_sym
- scopes[name] = lambda do |parent_scope, *args|
- Scope.new(parent_scope, case options
- when Hash
- options
- when Proc
- options.call(*args)
- end) { |*a| yield(*a) if block_given? }
- end
- (class << self; self end).instance_eval do
- define_method name do |*args|
- scopes[name].call(self, *args)
- end
- end
- end
- end
-
- class Scope
- attr_reader :proxy_scope, :proxy_options
-
- [].methods.each do |m|
- unless m =~ /(^__|^nil\?|^send|^object_id$|class|extend|^find$|count|sum|average|maximum|minimum|paginate|first|last|empty\?|respond_to\?)/
- delegate m, :to => :proxy_found
- end
- end
-
- delegate :scopes, :with_scope, :to => :proxy_scope
-
- def initialize(proxy_scope, options)
- [options[:extend]].flatten.each { |extension| extend extension } if options[:extend]
- extend Module.new { |*args| yield(*args) } if block_given?
- @proxy_scope, @proxy_options = proxy_scope, options.except(:extend)
- end
-
- def reload
- load_found; self
- end
-
- def first(*args)
- if args.first.kind_of?(Integer) || (@found && !args.first.kind_of?(Hash))
- proxy_found.first(*args)
- else
- find(:first, *args)
- end
- end
-
- def last(*args)
- if args.first.kind_of?(Integer) || (@found && !args.first.kind_of?(Hash))
- proxy_found.last(*args)
- else
- find(:last, *args)
- end
- end
-
- def empty?
- @found ? @found.empty? : count.zero?
- end
-
- def respond_to?(method, include_private = false)
- super || @proxy_scope.respond_to?(method, include_private)
- end
-
- protected
- def proxy_found
- @found || load_found
- end
-
- private
- def method_missing(method, *args)
- if scopes.include?(method)
- scopes[method].call(self, *args)
- else
- with_scope :find => proxy_options do
- proxy_scope.send(method, *args) { |*a| yield(*a) if block_given? }
- end
- end
- end
-
- def load_found
- @found = find(:all)
- end
- end
- end
-end
View
37 vendor/plugins/will_paginate/lib/will_paginate/named_scope_patch.rb
@@ -1,37 +0,0 @@
-ActiveRecord::Associations::AssociationProxy.class_eval do
- protected
- def with_scope(*args)
- @reflection.klass.send(:with_scope, *args) { |*a| yield(*a) if block_given? }
- end
-end
-
-[ ActiveRecord::Associations::AssociationCollection,
- ActiveRecord::Associations::HasManyThroughAssociation ].each do |klass|
- klass.class_eval do
- protected
- alias :method_missing_without_scopes :method_missing_without_paginate
- def method_missing_without_paginate(method, *args)
- if @reflection.klass.scopes.include?(method)
- @reflection.klass.scopes[method].call(self, *args) { |*a| yield(*a) if block_given? }
- else
- method_missing_without_scopes(method, *args) { |*a| yield(*a) if block_given? }
- end
- end
- end
-end
-
-# Rails 1.2.6
-ActiveRecord::Associations::HasAndBelongsToManyAssociation.class_eval do
- protected
- def method_missing(method, *args)
- if @target.respond_to?(method) || (!@reflection.klass.respond_to?(method) && Class.respond_to?(method))
- super
- elsif @reflection.klass.scopes.include?(method)
- @reflection.klass.scopes[method].call(self, *args)
- else
- @reflection.klass.with_scope(:find => { :conditions => @finder_sql, :joins => @join_sql, :readonly => false }) do
- @reflection.klass.send(method, *args) { |*a| yield(*a) if block_given? }
- end
- end
- end
-end if ActiveRecord::Base.respond_to? :find_first
View
24 vendor/plugins/will_paginate/lib/will_paginate/railtie.rb
@@ -0,0 +1,24 @@
+require 'will_paginate'
+require 'will_paginate/collection'
+
+module WillPaginate
+ class Railtie < Rails::Railtie
+ initializer "will_paginate.active_record" do |app|
+ if defined? ::ActiveRecord
+ require 'will_paginate/finders/active_record'
+ WillPaginate::Finders::ActiveRecord.enable!
+ end
+ end
+
+ initializer "will_paginate.action_dispatch" do |app|
+ if defined? ::ActionDispatch::ShowExceptions
+ ActionDispatch::ShowExceptions.rescue_responses['WillPaginate::InvalidPage'] = :not_found
+ end
+ end
+
+ initializer "will_paginate.action_view" do |app|
+ require 'will_paginate/view_helpers/action_view'
+ ActionView::Base.send(:include, WillPaginate::ViewHelpers::ActionView)
+ end
+ end
+end
View
10 vendor/plugins/will_paginate/lib/will_paginate/version.rb
@@ -1,8 +1,8 @@
-module WillPaginate
- module VERSION
- MAJOR = 2
- MINOR = 3
- TINY = 12
+module WillPaginate #:nodoc:
+ module VERSION #:nodoc:
+ MAJOR = 3
+ MINOR = 0
+ TINY = 'pre'
STRING = [MAJOR, MINOR, TINY].join('.')
end
View
416 vendor/plugins/will_paginate/lib/will_paginate/view_helpers.rb
@@ -1,408 +1,42 @@
-require 'will_paginate/core_ext'
+require 'will_paginate/deprecation'
module WillPaginate
# = Will Paginate view helpers
#
- # 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.
+ # 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
- # <tt>WillPaginate::ViewHelpers.pagination_options</tt> 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.
+ # Read more in WillPaginate::ViewHelpers::Base
module ViewHelpers
- # default options that can be overridden on the global level
- @@pagination_options = {
+ # ==== 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 = {
:class => 'pagination',
- :previous_label => '&laquo; Previous',
- :next_label => 'Next &raquo;',
+ :previous_label => '&#8592; Previous',
+ :next_label => 'Next &#8594;',
:inner_window => 4, # links around the current page
:outer_window => 1, # links around beginning and end
:separator => ' ', # single space is friendly to spiders and non-graphic browsers
:param_name => :page,
:params => nil,
- :renderer => 'WillPaginate::LinkRenderer',
+ :renderer => 'WillPaginate::ViewHelpers::LinkRenderer',
:page_links => true,
:container => true
}
- mattr_reader :pagination_options
-
- # 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
- # Display options:
- # * <tt>:previous_label</tt> -- default: "« Previous" (this parameter is called <tt>:prev_label</tt> in versions <b>2.3.2</b> and older!)
- # * <tt>:next_label</tt> -- default: "Next »"
- # * <tt>:page_links</tt> -- when false, only previous/next links are rendered (default: true)
- # * <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)
- #
- # HTML options:
- # * <tt>:class</tt> -- CSS class name for the generated DIV (default: "pagination")
- # * <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".
- #
- # Advanced options:
- # * <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>)
- #
- # 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>
- #
- # ==== 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 = 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
-
- # 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
-
- # 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">
- # ...
- # </ol>
- # <div class="pagination"> ... </div>
- #
- # Arguments are passed to a <tt>will_paginate</tt> call, so the same options