pagination 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/.gitignore +23 -0
- data/LICENSE +20 -0
- data/README.md +56 -0
- data/Rakefile +53 -0
- data/VERSION +1 -0
- data/bin/pagination +9 -0
- data/lib/pagination/adapters/ohm.rb +29 -0
- data/lib/pagination/collection.rb +89 -0
- data/lib/pagination/helpers.rb +43 -0
- data/lib/pagination/template.rb +72 -0
- data/lib/pagination.rb +39 -0
- data/test/helper.rb +10 -0
- data/test/test_pagination.rb +112 -0
- data/test/test_pagination_template.rb +75 -0
- data/views/paginate.erb +35 -0
- data/views/paginate.haml +23 -0
- metadata +104 -0
data/.document
ADDED
data/.gitignore
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Cyril David
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
Pagination: Trying to make the pagination world a better place
|
2
|
+
==============================================================
|
3
|
+
|
4
|
+
Why another pagination library?
|
5
|
+
-------------------------------
|
6
|
+
|
7
|
+
Because I constantly work with designers, who prefer to have their own pagination markup customized to their heart's content. Current problems I have:
|
8
|
+
|
9
|
+
1. It is very hard for me to change the markup with the current libraries out there.
|
10
|
+
2. No Ohm / Redis support available (as far as I know).
|
11
|
+
3. NIH?
|
12
|
+
|
13
|
+
Name the Niche:
|
14
|
+
---------------
|
15
|
+
|
16
|
+
This is currently streamlined for use with:
|
17
|
+
|
18
|
+
1. Sinatra
|
19
|
+
2. Ohm
|
20
|
+
3. HAML
|
21
|
+
|
22
|
+
How to use?
|
23
|
+
-----------
|
24
|
+
|
25
|
+
require 'rubygems'
|
26
|
+
require 'sinatra'
|
27
|
+
require 'pagination'
|
28
|
+
|
29
|
+
helpers Pagination::Helpers
|
30
|
+
|
31
|
+
get '/items' do
|
32
|
+
# Let's say current_user returns a User model with an items method
|
33
|
+
|
34
|
+
@items = paginate current_user.items, :page => params[:page]
|
35
|
+
|
36
|
+
haml :'items/index'
|
37
|
+
end
|
38
|
+
|
39
|
+
# then in your view index.haml
|
40
|
+
|
41
|
+
!= pagination @items
|
42
|
+
|
43
|
+
Customize the markup?
|
44
|
+
---------------------
|
45
|
+
|
46
|
+
pagination haml
|
47
|
+
# Spits out the pagination haml markup that's being used
|
48
|
+
|
49
|
+
# Or if you prefer erb, you can also do that too...
|
50
|
+
pagination erb
|
51
|
+
|
52
|
+
# Then you can just use it as a partial
|
53
|
+
pagination haml > app/views/pagination.haml
|
54
|
+
|
55
|
+
# in your view
|
56
|
+
!= partial :pagination, :items => @items
|
data/Rakefile
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "pagination"
|
8
|
+
gem.summary = %Q{A simplistic pagination library}
|
9
|
+
gem.description = %Q{Trying to make the pagination world a better place}
|
10
|
+
gem.email = "cyx.ucron@gmail.com"
|
11
|
+
gem.homepage = "http://github.com/sinefunc/pagination"
|
12
|
+
gem.authors = ["Cyril David"]
|
13
|
+
gem.add_development_dependency "contest"
|
14
|
+
gem.add_development_dependency "haml"
|
15
|
+
end
|
16
|
+
Jeweler::GemcutterTasks.new
|
17
|
+
rescue LoadError
|
18
|
+
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
19
|
+
end
|
20
|
+
|
21
|
+
require 'rake/testtask'
|
22
|
+
Rake::TestTask.new(:test) do |test|
|
23
|
+
test.libs << 'lib' << 'test'
|
24
|
+
test.pattern = 'test/**/test_*.rb'
|
25
|
+
test.verbose = true
|
26
|
+
end
|
27
|
+
|
28
|
+
begin
|
29
|
+
require 'rcov/rcovtask'
|
30
|
+
Rcov::RcovTask.new do |test|
|
31
|
+
test.libs << 'test'
|
32
|
+
test.pattern = 'test/**/test_*.rb'
|
33
|
+
test.verbose = true
|
34
|
+
end
|
35
|
+
rescue LoadError
|
36
|
+
task :rcov do
|
37
|
+
abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
task :test => :check_dependencies
|
42
|
+
|
43
|
+
task :default => :test
|
44
|
+
|
45
|
+
require 'rake/rdoctask'
|
46
|
+
Rake::RDocTask.new do |rdoc|
|
47
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
48
|
+
|
49
|
+
rdoc.rdoc_dir = 'rdoc'
|
50
|
+
rdoc.title = "pagination #{version}"
|
51
|
+
rdoc.rdoc_files.include('README*')
|
52
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
53
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
data/bin/pagination
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
module Pagination
|
2
|
+
class OhmAdapter < Collection
|
3
|
+
def initialize(dataset, options = {})
|
4
|
+
super
|
5
|
+
|
6
|
+
@dataset = dataset
|
7
|
+
@total = dataset.size
|
8
|
+
@order = options[:order]
|
9
|
+
@start = (page - 1) * per_page
|
10
|
+
end
|
11
|
+
|
12
|
+
protected
|
13
|
+
def collection
|
14
|
+
if @dataset.respond_to?(:sort)
|
15
|
+
@dataset.sort sort_options
|
16
|
+
else
|
17
|
+
@dataset.all @start, per_page
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def sort_options
|
22
|
+
{ :start => @start,
|
23
|
+
:limit => @per_page,
|
24
|
+
:order => 'DESC',
|
25
|
+
:by => @order
|
26
|
+
}
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
module Pagination
|
2
|
+
class Collection
|
3
|
+
Unimplemented = Class.new(StandardError)
|
4
|
+
|
5
|
+
include Enumerable
|
6
|
+
|
7
|
+
attr :page, :per_page, :total
|
8
|
+
|
9
|
+
# When subclassing `Pagination::Collection`, make sure you call super
|
10
|
+
# in order to use `page` and `per_page`.
|
11
|
+
def initialize(collection, options = {})
|
12
|
+
@page = Integer(options[:page] || 1)
|
13
|
+
@per_page = Integer(options[:per_page] || Pagination.per_page)
|
14
|
+
end
|
15
|
+
|
16
|
+
# When there's a valid previous page, returns that number
|
17
|
+
#
|
18
|
+
# Otherwise returns nil
|
19
|
+
#
|
20
|
+
def prev_page
|
21
|
+
page - 1 if pages.include?(page - 1)
|
22
|
+
end
|
23
|
+
|
24
|
+
# When there's a valid next page, returns that number
|
25
|
+
#
|
26
|
+
# Otherwise returns nil
|
27
|
+
def next_page
|
28
|
+
page + 1 if pages.include?(page + 1)
|
29
|
+
end
|
30
|
+
|
31
|
+
# Mainly used as syntatic sugar instead of doing
|
32
|
+
#
|
33
|
+
# if items.page == params[:page]
|
34
|
+
#
|
35
|
+
# for example, you will do
|
36
|
+
#
|
37
|
+
# if items.current?(params[:page])
|
38
|
+
#
|
39
|
+
def current?(other_page)
|
40
|
+
page == other_page
|
41
|
+
end
|
42
|
+
|
43
|
+
# Provides dirt-simple logic for spitting out page numbers
|
44
|
+
# based on the current page.
|
45
|
+
#
|
46
|
+
# If we have 100 pages for example and we're at page 50,
|
47
|
+
# this would simple return
|
48
|
+
#
|
49
|
+
# [50, 51, 52, 53, 54, 55, 56, 57, 58, 59]
|
50
|
+
#
|
51
|
+
# When we're at page 1, it displays 1 to 10.
|
52
|
+
#
|
53
|
+
# You can pass in a number to limit the total displayed pages.
|
54
|
+
# 1 2 3 4 5
|
55
|
+
def displayed_pages(limit = 10)
|
56
|
+
lower = [page, [pages.last - limit, 0].max + 1].min
|
57
|
+
upper = [page + limit - 1, pages.last].min
|
58
|
+
|
59
|
+
(lower..upper).to_a
|
60
|
+
end
|
61
|
+
|
62
|
+
# Mainly used in the presentation layer as a front-line check if
|
63
|
+
# we should even proceed with all the nitty-gritty details of rendering.
|
64
|
+
#
|
65
|
+
# This basically returns false when there's only 1 page for the given
|
66
|
+
# collection, otherwise returns true.
|
67
|
+
def render?
|
68
|
+
pages.to_a.size > 1
|
69
|
+
end
|
70
|
+
|
71
|
+
def each(&block)
|
72
|
+
collection.each(&block)
|
73
|
+
end
|
74
|
+
|
75
|
+
protected
|
76
|
+
def collection
|
77
|
+
raise Unimplemented, "You must implement collection"
|
78
|
+
end
|
79
|
+
|
80
|
+
def pages
|
81
|
+
1..last_page
|
82
|
+
end
|
83
|
+
|
84
|
+
def last_page
|
85
|
+
(total / per_page.to_f).ceil
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module Pagination
|
2
|
+
# This module is mostly intended for use with Sinatra.
|
3
|
+
#
|
4
|
+
# The classic sinatra application follows:
|
5
|
+
#
|
6
|
+
# require 'rubygems'
|
7
|
+
# require 'sinatra'
|
8
|
+
# require 'pagination'
|
9
|
+
#
|
10
|
+
# helpers Pagination::Helpers
|
11
|
+
#
|
12
|
+
# get '/items' do
|
13
|
+
# @items = paginate current_user.items, :page => params[:page]
|
14
|
+
# end
|
15
|
+
#
|
16
|
+
# and then in your view
|
17
|
+
#
|
18
|
+
# = pagination @items
|
19
|
+
#
|
20
|
+
module Helpers
|
21
|
+
# This method accepts a dataset which depends entirely on your current adapter.
|
22
|
+
# By default the `Pagination::OhmAdapter` is used, which assumes you are
|
23
|
+
# passing in sets.
|
24
|
+
#
|
25
|
+
# There's nothing stopping you from building your own adapter.
|
26
|
+
# See Pagination::OhmAdapter for details.
|
27
|
+
def paginate(dataset, options = {})
|
28
|
+
Pagination.paginate(dataset, options)
|
29
|
+
end
|
30
|
+
|
31
|
+
# As of now this displays a canned markup. The best way to actually customize
|
32
|
+
# the markup is to use a partial and just pass in the collection as a local i.e.
|
33
|
+
#
|
34
|
+
# partial :pagination, :items => @items
|
35
|
+
#
|
36
|
+
# The actual templates used are in `views/paginate.haml` and `views/paginate.erb`
|
37
|
+
def pagination(paginated_collection)
|
38
|
+
Pagination::Template.new(paginated_collection).render
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
|
@@ -0,0 +1,72 @@
|
|
1
|
+
module Pagination
|
2
|
+
# This class can be used by itself, although there's a `Pagination::Helper`
|
3
|
+
# available to provide convenience methods at your disposal.
|
4
|
+
#
|
5
|
+
# Basic Usage:
|
6
|
+
#
|
7
|
+
# collection = Pagination.paginate(dataset, :page => 1)
|
8
|
+
# Pagination::Template.new(collection).render
|
9
|
+
#
|
10
|
+
class Template
|
11
|
+
ROOT = File.join(File.dirname(__FILE__), '..', '..', 'views')
|
12
|
+
|
13
|
+
attr :items
|
14
|
+
|
15
|
+
# Initialize with your paginated collection.
|
16
|
+
#
|
17
|
+
# == Paramaters:
|
18
|
+
# items::
|
19
|
+
# a `Pagination::Collection` object return by `Pagination.paginate`.
|
20
|
+
def initialize(items)
|
21
|
+
@items = items
|
22
|
+
end
|
23
|
+
|
24
|
+
# Displayed the standard pagination markup as provided by the
|
25
|
+
# `Pagination` library.
|
26
|
+
#
|
27
|
+
# This uses Haml if Haml is required already. Else it uses ERB.
|
28
|
+
#
|
29
|
+
# == Returns:
|
30
|
+
# The actual HTML for the pagination.
|
31
|
+
def render
|
32
|
+
if engine.respond_to?(:render)
|
33
|
+
engine.render(Object.new, :items => items)
|
34
|
+
else
|
35
|
+
engine.result(binding)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# This is used by the command line tool to spit out the markup.
|
40
|
+
#
|
41
|
+
# == Parameters:
|
42
|
+
# type::
|
43
|
+
# either 'haml' or 'erb'
|
44
|
+
#
|
45
|
+
# == Returns:
|
46
|
+
# The actual markup source.
|
47
|
+
def self.markup(type)
|
48
|
+
puts __send__(type)
|
49
|
+
end
|
50
|
+
|
51
|
+
protected
|
52
|
+
def self.haml
|
53
|
+
File.read(File.join(ROOT, 'paginate.haml'))
|
54
|
+
end
|
55
|
+
|
56
|
+
def self.erb
|
57
|
+
File.read(File.join(ROOT, 'paginate.erb'))
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
def engine
|
62
|
+
@engine ||=
|
63
|
+
if defined?(Haml)
|
64
|
+
Haml::Engine.new(self.class.haml)
|
65
|
+
else
|
66
|
+
require 'erb' if not defined?(ERB)
|
67
|
+
ERB.new(self.class.erb)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
end
|
data/lib/pagination.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
module Pagination
|
2
|
+
autoload :OhmAdapter, 'pagination/adapters/ohm'
|
3
|
+
autoload :Collection, 'pagination/collection'
|
4
|
+
autoload :Template, 'pagination/template'
|
5
|
+
|
6
|
+
extend self
|
7
|
+
|
8
|
+
def paginate(collection, options = {})
|
9
|
+
adapter.new(collection, options)
|
10
|
+
end
|
11
|
+
|
12
|
+
def per_page(per_page = nil)
|
13
|
+
@per_page = per_page if per_page
|
14
|
+
@per_page
|
15
|
+
end
|
16
|
+
|
17
|
+
def adapter(adapter = nil)
|
18
|
+
if adapter
|
19
|
+
@adapter = adapter
|
20
|
+
else
|
21
|
+
const_get(@adapter) if @adapter
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# Set the default to 15
|
26
|
+
# You can easily override this by putting the following somewhere in your code:
|
27
|
+
# Pagination.per_page 10
|
28
|
+
#
|
29
|
+
per_page 15
|
30
|
+
|
31
|
+
# Currently we default to Ohm for various reasons.
|
32
|
+
#
|
33
|
+
# If you want to make your own adapter, simply subclass Pagination::Collection
|
34
|
+
# and use `OhmAdapter` as the basis to determine the requirements needed.
|
35
|
+
#
|
36
|
+
# Make sure you put your Adapter under the `Pagination` module
|
37
|
+
# (i.e. Pagination::MongoAdapter).
|
38
|
+
adapter :OhmAdapter
|
39
|
+
end
|
data/test/helper.rb
ADDED
@@ -0,0 +1,112 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class TestPagination < Test::Unit::TestCase
|
4
|
+
should "respond to #paginate" do
|
5
|
+
assert_respond_to Pagination, :paginate
|
6
|
+
end
|
7
|
+
|
8
|
+
context "since we're assume OhmAdapter by default" do
|
9
|
+
should "at minimum accept a collection" do
|
10
|
+
assert_nothing_raised do
|
11
|
+
Pagination.paginate([])
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
context "given an empty collection" do
|
17
|
+
setup do
|
18
|
+
@collection = Pagination.paginate([])
|
19
|
+
end
|
20
|
+
|
21
|
+
should "default to page 1" do
|
22
|
+
assert_equal 1, @collection.page
|
23
|
+
end
|
24
|
+
|
25
|
+
should "be current?(1)" do
|
26
|
+
assert @collection.current?(1)
|
27
|
+
end
|
28
|
+
|
29
|
+
should "default to 15 per page" do
|
30
|
+
assert_equal 15, @collection.per_page
|
31
|
+
end
|
32
|
+
|
33
|
+
should "have no prev page sinced it's page 1" do
|
34
|
+
assert_nil @collection.prev_page
|
35
|
+
end
|
36
|
+
|
37
|
+
should "have no next page since the collection passed was empty" do
|
38
|
+
assert_nil @collection.next_page
|
39
|
+
end
|
40
|
+
|
41
|
+
should "not render" do
|
42
|
+
assert ! @collection.render?
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
context "given 2 items, page 1, per_page 1" do
|
47
|
+
setup do
|
48
|
+
@collection = Pagination.paginate(['first', 'second'], :per_page => 1)
|
49
|
+
end
|
50
|
+
|
51
|
+
should "have no prev page" do
|
52
|
+
assert_nil @collection.prev_page
|
53
|
+
end
|
54
|
+
|
55
|
+
should "have a next page of 2" do
|
56
|
+
assert_equal 2, @collection.next_page
|
57
|
+
end
|
58
|
+
|
59
|
+
context 'when we set page to 2' do
|
60
|
+
setup do
|
61
|
+
@collection = Pagination.paginate(['f', 's'], :page => 2, :per_page => 1)
|
62
|
+
end
|
63
|
+
|
64
|
+
should "have a prev page of 1" do
|
65
|
+
assert_equal 1, @collection.prev_page
|
66
|
+
end
|
67
|
+
|
68
|
+
should "have no next page" do
|
69
|
+
assert_nil @collection.next_page
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
context "given we have 100 pages and we're at page 1" do
|
75
|
+
setup do
|
76
|
+
@collection = Pagination.paginate((1..100).to_a, :per_page => 1)
|
77
|
+
end
|
78
|
+
|
79
|
+
should "have 1 to 10 of displayed_pages" do
|
80
|
+
assert_equal (1..10).to_a, @collection.displayed_pages
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
context "given we have 100 pages and we're at page 50" do
|
85
|
+
setup do
|
86
|
+
@collection = Pagination.paginate((1..100).to_a, :per_page => 1, :page => 50)
|
87
|
+
end
|
88
|
+
|
89
|
+
should "have 50 to 59 of displayed_pages" do
|
90
|
+
assert_equal (50..59).to_a, @collection.displayed_pages
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
context "given we have 100 pages and we're at pages 91 up to 99" do
|
95
|
+
should "start with the 91 end with 100" do
|
96
|
+
(91..99).each do |p|
|
97
|
+
collection = Pagination.paginate((1..100).to_a, :per_page => 1, :page => p)
|
98
|
+
assert_equal (91..100).to_a, collection.displayed_pages
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
context "given we have 5 pages and we're at page 2 up to 5" do
|
104
|
+
should "always display the 5 pages" do
|
105
|
+
(1..5).each do |p|
|
106
|
+
collection = Pagination.paginate((1..100).to_a, :per_page => 20, :page => p)
|
107
|
+
assert_equal (1..5).to_a, collection.displayed_pages
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'helper'
|
2
|
+
require 'nokogiri'
|
3
|
+
require 'haml'
|
4
|
+
|
5
|
+
HamlHere = Haml
|
6
|
+
|
7
|
+
class TestPaginationTemplate < Test::Unit::TestCase
|
8
|
+
setup do
|
9
|
+
@dataset = ['one', 'two', 'three', 'four', 'five']
|
10
|
+
@items = Pagination.paginate(@dataset, :per_page => 1, :page => 1)
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "haml rendering option" do
|
14
|
+
setup do
|
15
|
+
Object.const_set(:Haml, HamlHere) unless defined?(Haml)
|
16
|
+
@render = lambda { Pagination::Template.new(@items).render }
|
17
|
+
end
|
18
|
+
|
19
|
+
def doc
|
20
|
+
Nokogiri(@render.call)
|
21
|
+
end
|
22
|
+
|
23
|
+
should "be able to render using haml" do
|
24
|
+
assert_nothing_raised do
|
25
|
+
@render.call
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
should "have a ul > li.prev-link.disabled" do
|
30
|
+
assert_equal 1,
|
31
|
+
doc.search('ul.pagination > li.prev-link.disabled > a').length
|
32
|
+
end
|
33
|
+
|
34
|
+
should "have a ul > li.next-link with page=2" do
|
35
|
+
assert_equal 1,
|
36
|
+
doc.search('ul.pagination > li.next-link > a[href="?page=2"]').length
|
37
|
+
end
|
38
|
+
|
39
|
+
should "display the first page as the curretn page" do
|
40
|
+
assert_equal 1,
|
41
|
+
doc.search('ul.pagination > li > ul.page-numbers > li > span').length
|
42
|
+
|
43
|
+
assert_equal '1',
|
44
|
+
doc.search('ul.pagination > li > ul.page-numbers > li > span').text
|
45
|
+
end
|
46
|
+
|
47
|
+
should "display pages 2 to 5 as links" do
|
48
|
+
(2..5).each do |page|
|
49
|
+
assert_equal 1,
|
50
|
+
doc.search(%(ul.pagination > li >
|
51
|
+
ul.page-numbers > li > a[href="?page=#{page}"])).length
|
52
|
+
|
53
|
+
assert_equal page.to_s,
|
54
|
+
doc.search(%(ul.pagination > li >
|
55
|
+
ul.page-numbers > li > a[href="?page=#{page}"])).text
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
describe "erb rendering option" do
|
61
|
+
setup do
|
62
|
+
Object.send :remove_const, :Haml
|
63
|
+
end
|
64
|
+
|
65
|
+
should "render without any errors" do
|
66
|
+
template = Pagination::Template.new(@items)
|
67
|
+
assert_kind_of ERB, template.send(:engine)
|
68
|
+
|
69
|
+
assert_nothing_raised do
|
70
|
+
template.render
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
data/views/paginate.erb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
<ul class="pagination">
|
2
|
+
<% if items.prev_page %>
|
3
|
+
<li class="prev-link">
|
4
|
+
<a href='<%= "?page=%s" % items.prev_page %>'>« Prev</a>
|
5
|
+
</li>
|
6
|
+
<% else %>
|
7
|
+
<li class="prev-link disabled">
|
8
|
+
<span>« Prev</span>
|
9
|
+
</li>
|
10
|
+
<% end %>
|
11
|
+
|
12
|
+
<li>
|
13
|
+
<ul class="page-numbers">
|
14
|
+
<% items.displayed_pages.each do |page| %>
|
15
|
+
<li>
|
16
|
+
<% if items.current?(page) %>
|
17
|
+
<span><%= page %></span>
|
18
|
+
<% else %>
|
19
|
+
<a href='<%= "?page=%s" % page %>'><%= page %></a>
|
20
|
+
<% end %>
|
21
|
+
</li>
|
22
|
+
<% end %>
|
23
|
+
</ul>
|
24
|
+
</li>
|
25
|
+
|
26
|
+
<% if items.next_page %>
|
27
|
+
<li class="next-link">
|
28
|
+
<a href='<%= "?page=%s" % items.next_page %>'>Next »</a>
|
29
|
+
</li>
|
30
|
+
<% else %>
|
31
|
+
<li class="next-link disabled">
|
32
|
+
<span>Next »</span>
|
33
|
+
</li>
|
34
|
+
<% end %>
|
35
|
+
</ul>
|
data/views/paginate.haml
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
%ul.notList.pagination
|
2
|
+
- if items.prev_page
|
3
|
+
%li.prev-link
|
4
|
+
%a{:href => ("?page=%s" % items.prev_page)} « Prev
|
5
|
+
- else
|
6
|
+
%li.prev-link.disabled
|
7
|
+
%a(href='javascript:;') « Prev
|
8
|
+
|
9
|
+
%li
|
10
|
+
%ul.notList.page-numbers
|
11
|
+
- items.displayed_pages.each do |page|
|
12
|
+
%li
|
13
|
+
- if items.current?(page)
|
14
|
+
%span= page
|
15
|
+
- else
|
16
|
+
%a{:href => ("?page=%s" % page)}= page
|
17
|
+
|
18
|
+
- if items.next_page
|
19
|
+
%li.next-link
|
20
|
+
%a{:href => ("?page=%s" % items.next_page)} Next »
|
21
|
+
- else
|
22
|
+
%li.next-link.disabled
|
23
|
+
%a(href='javascript:;') Next »
|
metadata
ADDED
@@ -0,0 +1,104 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: pagination
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 1
|
8
|
+
- 0
|
9
|
+
version: 0.1.0
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Cyril David
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-04-25 00:00:00 +08:00
|
18
|
+
default_executable: pagination
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: contest
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
segments:
|
28
|
+
- 0
|
29
|
+
version: "0"
|
30
|
+
type: :development
|
31
|
+
version_requirements: *id001
|
32
|
+
- !ruby/object:Gem::Dependency
|
33
|
+
name: haml
|
34
|
+
prerelease: false
|
35
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ">="
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
segments:
|
40
|
+
- 0
|
41
|
+
version: "0"
|
42
|
+
type: :development
|
43
|
+
version_requirements: *id002
|
44
|
+
description: Trying to make the pagination world a better place
|
45
|
+
email: cyx.ucron@gmail.com
|
46
|
+
executables:
|
47
|
+
- pagination
|
48
|
+
extensions: []
|
49
|
+
|
50
|
+
extra_rdoc_files:
|
51
|
+
- LICENSE
|
52
|
+
- README.md
|
53
|
+
files:
|
54
|
+
- .document
|
55
|
+
- .gitignore
|
56
|
+
- LICENSE
|
57
|
+
- README.md
|
58
|
+
- Rakefile
|
59
|
+
- VERSION
|
60
|
+
- bin/pagination
|
61
|
+
- lib/pagination.rb
|
62
|
+
- lib/pagination/adapters/ohm.rb
|
63
|
+
- lib/pagination/collection.rb
|
64
|
+
- lib/pagination/helpers.rb
|
65
|
+
- lib/pagination/template.rb
|
66
|
+
- test/helper.rb
|
67
|
+
- test/test_pagination.rb
|
68
|
+
- test/test_pagination_template.rb
|
69
|
+
- views/paginate.erb
|
70
|
+
- views/paginate.haml
|
71
|
+
has_rdoc: true
|
72
|
+
homepage: http://github.com/sinefunc/pagination
|
73
|
+
licenses: []
|
74
|
+
|
75
|
+
post_install_message:
|
76
|
+
rdoc_options:
|
77
|
+
- --charset=UTF-8
|
78
|
+
require_paths:
|
79
|
+
- lib
|
80
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
81
|
+
requirements:
|
82
|
+
- - ">="
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
segments:
|
85
|
+
- 0
|
86
|
+
version: "0"
|
87
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
88
|
+
requirements:
|
89
|
+
- - ">="
|
90
|
+
- !ruby/object:Gem::Version
|
91
|
+
segments:
|
92
|
+
- 0
|
93
|
+
version: "0"
|
94
|
+
requirements: []
|
95
|
+
|
96
|
+
rubyforge_project:
|
97
|
+
rubygems_version: 1.3.6
|
98
|
+
signing_key:
|
99
|
+
specification_version: 3
|
100
|
+
summary: A simplistic pagination library
|
101
|
+
test_files:
|
102
|
+
- test/helper.rb
|
103
|
+
- test/test_pagination.rb
|
104
|
+
- test/test_pagination_template.rb
|