genki-dm-pagination 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Rakefile +1 -1
- data/lib/dm-pagination.rb +9 -0
- data/lib/dm-pagination/paginatable.rb +9 -0
- data/lib/dm-pagination/pagination.rb +36 -0
- data/lib/dm-pagination/pagination_builder.rb +83 -0
- data/spec/dm-pagination_spec.rb +64 -20
- data/spec/fixture/app/controllers/pagination_builder.rb +6 -0
- data/spec/fixture/app/models/post.rb +6 -0
- data/spec/fixture/app/views/layout/application.html.erb +11 -0
- data/spec/fixture/app/views/pagination_builder/simple.html.erb +7 -0
- data/spec/fixture/config/router.rb +13 -0
- data/spec/spec_helper.rb +40 -0
- metadata +19 -2
data/Rakefile
CHANGED
data/lib/dm-pagination.rb
CHANGED
@@ -20,6 +20,15 @@ if defined?(Merb::Plugins)
|
|
20
20
|
extend DmPagination::Paginatable
|
21
21
|
end
|
22
22
|
end
|
23
|
+
|
24
|
+
require 'dm-pagination/pagination_builder'
|
25
|
+
module Merb
|
26
|
+
module GlobalHelpers
|
27
|
+
def paginate(pagination, *args, &block)
|
28
|
+
DmPagination::PaginationBuilder.new(self, pagination, *args, &block)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
23
32
|
end
|
24
33
|
|
25
34
|
Merb::BootLoader.after_app_loads do
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module DmPagination
|
2
|
+
class Pagination
|
3
|
+
def initialize(collection, options)
|
4
|
+
@page = (options[:page] || 1).to_i
|
5
|
+
@per_page = (options[:per_page] || 10).to_i
|
6
|
+
@proxy_collection = collection
|
7
|
+
@collection = collection.all(
|
8
|
+
:offset => (@page - 1)*@per_page, :limit => @per_page)
|
9
|
+
end
|
10
|
+
|
11
|
+
def page
|
12
|
+
@page
|
13
|
+
end
|
14
|
+
|
15
|
+
def num_pages
|
16
|
+
(@proxy_collection.count + @per_page - 1) / @per_page
|
17
|
+
end
|
18
|
+
|
19
|
+
def pages(window = 5, left = 2, right = 2)
|
20
|
+
return [] if num_pages <= 1
|
21
|
+
(1..num_pages).inject([]) do |result, i|
|
22
|
+
i <= left || (num_pages - i) < right || (i-page).abs < window ?
|
23
|
+
result << i : (result.last.nil? ? result : result << nil)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def count
|
28
|
+
offset = (@page - 1)*@per_page
|
29
|
+
[0, [@proxy_collection.count - offset, @per_page].min].max
|
30
|
+
end
|
31
|
+
|
32
|
+
def method_missing(method, *args, &block)
|
33
|
+
@collection.send(method, *args, &block)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
module DmPagination
|
2
|
+
class PaginationBuilder
|
3
|
+
def initialize(context, pagination, *args, &block)
|
4
|
+
@context = context
|
5
|
+
@pagination = pagination
|
6
|
+
@block = block
|
7
|
+
@options = args.last.kind_of?(Hash) ? args.pop : {}
|
8
|
+
@args = args.blank? ? [:prev, :pages, :next] : []
|
9
|
+
end
|
10
|
+
|
11
|
+
def to_s(*args)
|
12
|
+
args = @args if args.blank?
|
13
|
+
items = args.map{|i| respond_to?("link_to_#{i}") ?
|
14
|
+
send("link_to_#{i}") : []}.flatten
|
15
|
+
@context.tag(:div, items.join("\n"), :class => "pagination")
|
16
|
+
end
|
17
|
+
|
18
|
+
def link_to_pages
|
19
|
+
@pagination.pages.map{|page| link_to_page(page)}
|
20
|
+
end
|
21
|
+
|
22
|
+
def link_to_prev
|
23
|
+
if @pagination.page > 1
|
24
|
+
@context.link_to prev_label,
|
25
|
+
url(:page => @pagination.page - 1),
|
26
|
+
:class => :prev, :rel => "prev"
|
27
|
+
else
|
28
|
+
span.call(prev_label)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def link_to_next
|
33
|
+
if @pagination.page < @pagination.num_pages
|
34
|
+
@context.link_to next_label,
|
35
|
+
url(:page => @pagination.page + 1),
|
36
|
+
:class => :older, :rel => "next"
|
37
|
+
else
|
38
|
+
span.call(next_label)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def link_to_page(page)
|
43
|
+
if page.nil?
|
44
|
+
span.call truncate, @options[:style]
|
45
|
+
elsif page == @pagination.page
|
46
|
+
span.call page, [@options[:style], 'current'].compact.join(' ')
|
47
|
+
else
|
48
|
+
span.call link(page), @options[:style]
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
def span
|
54
|
+
proc do |*args|
|
55
|
+
@context.tag(:span, args[0].to_s, :class => (args[1]||"disabled"))
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def link(page, *args)
|
60
|
+
if @block
|
61
|
+
@block.call(page, *args)
|
62
|
+
else
|
63
|
+
@context.link_to(page, url(:page => page))
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def truncate
|
68
|
+
@options[:truncate] || '...'
|
69
|
+
end
|
70
|
+
|
71
|
+
def prev_label
|
72
|
+
@options[:prev] || '« Prev'
|
73
|
+
end
|
74
|
+
|
75
|
+
def next_label
|
76
|
+
@options[:next] || 'Next »'
|
77
|
+
end
|
78
|
+
|
79
|
+
def url(params)
|
80
|
+
@context.url(@context.params.merge(params))
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
data/spec/dm-pagination_spec.rb
CHANGED
@@ -1,34 +1,78 @@
|
|
1
1
|
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
-
require 'dm-core'
|
3
|
-
require 'dm-pagination/paginatable'
|
4
2
|
|
5
3
|
DataMapper.setup(:default, "sqlite3::memory:")
|
6
4
|
|
7
|
-
|
8
|
-
module Resource
|
9
|
-
module ClassMethods
|
10
|
-
include DmPagination::Paginatable
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
class TestPost
|
16
|
-
include DataMapper::Resource
|
17
|
-
|
18
|
-
property :id, Serial
|
19
|
-
end
|
5
|
+
Post.auto_migrate!
|
20
6
|
|
21
7
|
describe "dm-pagination" do
|
22
|
-
describe "
|
8
|
+
describe "paginatable" do
|
23
9
|
it "should extend DataMapper::Resource" do
|
24
|
-
test =
|
10
|
+
test = Post.new
|
25
11
|
test.should_not be_nil
|
26
|
-
|
27
|
-
|
12
|
+
Post.should be_respond_to(:paginate)
|
13
|
+
Post.all.should be_respond_to(:paginate)
|
28
14
|
end
|
29
15
|
|
30
16
|
it "should return Pagination object" do
|
31
|
-
|
17
|
+
Post.paginate.should be_kind_of(DmPagination::Pagination)
|
18
|
+
Post.all.paginate.should be_kind_of(DmPagination::Pagination)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "pagination" do
|
23
|
+
before :all do
|
24
|
+
Post.all.destroy!
|
25
|
+
101.times{|i| Post.create(:index => i)}
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should be specified on 101 test posts" do
|
29
|
+
Post.count.should == 101
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should have 10 pages" do
|
33
|
+
Post.paginate.num_pages.should == 11
|
34
|
+
Post.all.paginate.num_pages.should == 11
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should be able to calculate num pages on scope" do
|
38
|
+
Post.all(:index.gt => 50).count.should == 50
|
39
|
+
Post.all(:index.gt => 50).paginate.num_pages.should == 5
|
40
|
+
Post.all(:index.gt => 49).paginate.num_pages.should == 6
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should act as Collection" do
|
44
|
+
Post.paginate(:page => 8).count.should == 10
|
45
|
+
Post.paginate(:page => 11).count.should == 1
|
46
|
+
Post.paginate(:page => 12).count.should == 0
|
47
|
+
Post.paginate(:page => 5, :per_page => 6).count.should == 6
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe "pagination builder" do
|
52
|
+
include Merb::Helpers::Tag
|
53
|
+
|
54
|
+
before :all do
|
55
|
+
Post.all.destroy!
|
56
|
+
101.times{|i| Post.create(:index => i)}
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should be tested on 101 posts" do
|
60
|
+
Post.count.should == 101
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should have rendered with pagination" do
|
64
|
+
response = request "/pagination_builder/simple"
|
65
|
+
response.should be_successful
|
66
|
+
response.should have_selector("div.pagination")
|
67
|
+
response.should have_selector("ul")
|
68
|
+
response.should have_selector("li")
|
69
|
+
response.should have_selector("a[rel=next]")
|
70
|
+
end
|
71
|
+
|
72
|
+
it "should have rendered with pagination at page 2" do
|
73
|
+
response = request "/pagination_builder/simple", :params => {:page => 2}
|
74
|
+
response.should be_successful
|
75
|
+
response.should have_selector("a[rel=prev]")
|
32
76
|
end
|
33
77
|
end
|
34
78
|
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
2
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-us" lang="en-us">
|
3
|
+
<head>
|
4
|
+
<title>Fresh Merb App</title>
|
5
|
+
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
6
|
+
<link rel="stylesheet" href="/stylesheets/master.css" type="text/css" media="screen" charset="utf-8"/>
|
7
|
+
</head>
|
8
|
+
<body>
|
9
|
+
<%= catch_content :for_layout %>
|
10
|
+
</body>
|
11
|
+
</html>
|
@@ -0,0 +1,13 @@
|
|
1
|
+
Merb::Router.prepare do |r|
|
2
|
+
# RESTful routes
|
3
|
+
# r.resources :posts
|
4
|
+
|
5
|
+
# This is the default route for /:controller/:action/:id
|
6
|
+
# This is fine for most cases. If you're heavily using resource-based
|
7
|
+
# routes, you may want to comment/remove this line to prevent
|
8
|
+
# clients from calling your create or destroy actions with a GET
|
9
|
+
r.default_routes
|
10
|
+
|
11
|
+
# Change this for your home page to be available at /
|
12
|
+
# r.match('/').to(:controller => 'whatever', :action =>'index')
|
13
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1 +1,41 @@
|
|
1
1
|
$:.push File.join(File.dirname(__FILE__), '..', 'lib')
|
2
|
+
require 'rubygems'
|
3
|
+
require 'spec'
|
4
|
+
require 'merb-core'
|
5
|
+
require 'merb-helpers'
|
6
|
+
require 'merb-assets'
|
7
|
+
require 'dm-core'
|
8
|
+
require 'dm-pagination/paginatable'
|
9
|
+
require 'dm-pagination/pagination_builder'
|
10
|
+
require 'dm-aggregates'
|
11
|
+
|
12
|
+
default_options = {
|
13
|
+
:environment => 'test',
|
14
|
+
:adapter => 'runner',
|
15
|
+
:merb_root => File.dirname(__FILE__) / 'fixture',
|
16
|
+
:log_file => File.dirname(__FILE__) / "merb_test.log"
|
17
|
+
}
|
18
|
+
options = default_options.merge($START_OPTIONS || {})
|
19
|
+
DataMapper::Model.append_extensions DmPagination::Paginatable
|
20
|
+
module Merb
|
21
|
+
module GlobalHelpers
|
22
|
+
def paginate(pagination, *args, &block)
|
23
|
+
DmPagination::PaginationBuilder.new(self, pagination, *args, &block)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
Merb.disable(:initfile)
|
29
|
+
Merb.start_environment(options)
|
30
|
+
|
31
|
+
Spec::Runner.configure do |config|
|
32
|
+
config.include Merb::Test::RequestHelper
|
33
|
+
config.include Webrat::Matchers
|
34
|
+
config.include Webrat::HaveTagMatcher
|
35
|
+
|
36
|
+
def with_level(level)
|
37
|
+
Merb.logger = Merb::Logger.new(StringIO.new, level)
|
38
|
+
yield
|
39
|
+
Merb.logger
|
40
|
+
end
|
41
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: genki-dm-pagination
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Genki Takiuchi
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-01-
|
12
|
+
date: 2009-01-15 00:00:00 -08:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -38,8 +38,25 @@ files:
|
|
38
38
|
- TODO
|
39
39
|
- lib/dm-pagination
|
40
40
|
- lib/dm-pagination/merbtasks.rb
|
41
|
+
- lib/dm-pagination/paginatable.rb
|
42
|
+
- lib/dm-pagination/pagination.rb
|
43
|
+
- lib/dm-pagination/pagination_builder.rb
|
41
44
|
- lib/dm-pagination.rb
|
42
45
|
- spec/dm-pagination_spec.rb
|
46
|
+
- spec/fixture
|
47
|
+
- spec/fixture/app
|
48
|
+
- spec/fixture/app/controllers
|
49
|
+
- spec/fixture/app/controllers/pagination_builder.rb
|
50
|
+
- spec/fixture/app/models
|
51
|
+
- spec/fixture/app/models/post.rb
|
52
|
+
- spec/fixture/app/views
|
53
|
+
- spec/fixture/app/views/layout
|
54
|
+
- spec/fixture/app/views/layout/application.html.erb
|
55
|
+
- spec/fixture/app/views/pagination_builder
|
56
|
+
- spec/fixture/app/views/pagination_builder/simple.html.erb
|
57
|
+
- spec/fixture/config
|
58
|
+
- spec/fixture/config/router.rb
|
59
|
+
- spec/merb_test.log
|
43
60
|
- spec/spec_helper.rb
|
44
61
|
has_rdoc: true
|
45
62
|
homepage: http://blog.s21g.com/genki
|