diff --git a/kaminari.gemspec b/kaminari.gemspec
index 98e6366..3236be7 100644
--- a/kaminari.gemspec
+++ b/kaminari.gemspec
@@ -21,9 +21,14 @@ Gem::Specification.new do |s|
s.licenses = ['MIT']
- s.add_dependency 'railties', ['>= 3.0.0']
+ %w{ activesupport actionpack railties }.each do |gem|
+ s.add_dependency gem, ['>= 3.0.0']
+ end
s.add_development_dependency 'bundler', ['>= 1.0.0']
s.add_development_dependency 'sqlite3', ['>= 0']
+ %w{ activerecord activemodel }.each do |gem|
+ s.add_development_dependency gem, ['>= 3.0.0']
+ end
s.add_development_dependency 'mongoid', ['>= 2']
s.add_development_dependency 'mongo_mapper', ['>= 0.9']
s.add_development_dependency 'dm-core', ['>= 1.1.0']
diff --git a/lib/kaminari.rb b/lib/kaminari.rb
index 727b227..82bcedb 100644
--- a/lib/kaminari.rb
+++ b/lib/kaminari.rb
@@ -1,2 +1,52 @@
-require 'kaminari/railtie'
-require 'kaminari/engine'
+module Kaminari
+
+ def self.frameworks
+ frameworks = []
+ case
+ when defined?(::Rails) then frameworks << 'rails'
+ when defined?(::Sinatra) then frameworks << 'sinatra/base'
+ end
+ frameworks
+ end
+
+ def self.load_framework!
+ raise "No framework specified!" if frameworks.empty?
+ frameworks.each do |framework|
+ begin
+ require framework
+ rescue NameError => e
+ raise "can\'t load framework #{framework.inspect}. Have you added it to Gemfile?"
+ end
+ end
+ end
+
+
+ def self.load_kaminari!
+ require 'kaminari/config'
+ require 'kaminari/helpers/action_view_extension'
+ require 'kaminari/helpers/paginator'
+ require 'kaminari/models/page_scope_methods'
+ require 'kaminari/models/configuration_methods'
+ end
+
+ def self.hook!
+ load_framework!
+ load_kaminari!
+ require 'kaminari/hooks'
+ if defined?(::Rails)
+ require 'kaminari/railtie'
+ require 'kaminari/engine'
+ elsif defined?(::Sinatra)
+ require 'kaminari/sinatra'
+ else
+ Kaminari::Hooks.init!
+ end
+ end
+
+ def self.load!
+ hook!
+ end
+
+end
+
+Kaminari.load!
diff --git a/lib/kaminari/helpers/paginator.rb b/lib/kaminari/helpers/paginator.rb
index dc8a912..5232b3c 100644
--- a/lib/kaminari/helpers/paginator.rb
+++ b/lib/kaminari/helpers/paginator.rb
@@ -1,5 +1,8 @@
-require 'kaminari/helpers/tags'
+require 'active_support/inflector'
+require 'action_view'
+require 'action_view/log_subscriber'
require 'action_view/context'
+require 'kaminari/helpers/tags'
module Kaminari
module Helpers
diff --git a/lib/kaminari/helpers/sinatra_helper.rb b/lib/kaminari/helpers/sinatra_helper.rb
new file mode 100644
index 0000000..a36d951
--- /dev/null
+++ b/lib/kaminari/helpers/sinatra_helper.rb
@@ -0,0 +1,126 @@
+require 'active_support/core_ext/object'
+require 'active_support/core_ext/string'
+
+begin
+
+require 'padrino-helpers'
+module Kaminari::Helpers
+ module SinatraHelper
+ class << self
+ def registered(app)
+ app.register Padrino::Helpers
+ app.helpers HelperMethods
+ end
+
+ alias included registered
+ end
+
+ class ActionViewTemplateProxy
+ def initialize(opts={})
+ @current_path = opts[:current_path]
+ @param_name = (opts[:param_name] || :page).to_sym
+ @current_params = opts[:current_params]
+ @current_params.delete(@param_name)
+ end
+
+ def render(*args)
+ base = ActionView::Base.new.tap do |a|
+ a.view_paths << File.expand_path('../../../../app/views', __FILE__)
+ end
+ base.render(*args)
+ end
+
+ def url_for(params)
+ extra_params = {}
+ if page = params[@param_name] and page != 1
+ extra_params[@param_name] = page
+ end
+ query = @current_params.merge(extra_params)
+ @current_path + (query.empty? ? '' : "?#{query.to_query}")
+ end
+
+ def params
+ @current_params
+ end
+ end
+
+ module HelperMethods
+ # A quick backport from Rails' link_to_unless helper
+ def link_to_unless(condition, *args, &blk)
+ unless condition
+ link_to *args
+ else
+ block_given? ? blk.call : nil
+ end
+ end
+
+ # A helper that renders the pagination links - for Sinatra.
+ #
+ # <%= paginate @articles %>
+ #
+ # ==== Options
+ # * :window - The "inner window" size (4 by default).
+ # * :outer_window - The "outer window" size (0 by default).
+ # * :left - The "left outer window" size (0 by default).
+ # * :right - The "right outer window" size (0 by default).
+ # * :params - url_for parameters for the links (:controller, :action, etc.)
+ # * :param_name - parameter name for page number in the links (:page by default)
+ # * :remote - Ajax? (false by default)
+ # * :ANY_OTHER_VALUES - Any other hash key & values would be directly passed into each tag as :locals value.
+ def paginate(scope, options = {}, &block)
+ current_path = env['PATH_INFO'] rescue nil
+ current_params = Rack::Utils.parse_query(env['QUERY_STRING']).symbolize_keys rescue {}
+ paginator = Kaminari::Helpers::Paginator.new(
+ ActionViewTemplateProxy.new(:current_params => current_params, :current_path => current_path, :param_name => options[:param_name] || Kaminari.config.param_name),
+ options.reverse_merge(:current_page => scope.current_page, :num_pages => scope.num_pages, :per_page => scope.limit_value, :param_name => Kaminari.config.param_name, :remote => false)
+ )
+ paginator.to_s
+ end
+
+ # A simple "Twitter like" pagination link that creates a link to the next page.
+ # Works on Sinatra.
+ #
+ # ==== Examples
+ # Basic usage:
+ #
+ # <%= link_to_next_page @items, 'Next Page' %>
+ #
+ # Ajax:
+ #
+ # <%= link_to_next_page @items, 'Next Page', :remote => true %>
+ #
+ # By default, it renders nothing if there are no more results on the next page.
+ # You can customize this output by passing a block.
+ #
+ # <%= link_to_next_page @users, 'Next Page' do %>
+ # No More Pages
+ # <% end %>
+ def link_to_next_page(scope, name, options = {}, &block)
+ params = options.delete(:params) || (Rack::Utils.parse_query(env['QUERY_STRING']).symbolize_keys rescue {})
+ param_name = options.delete(:param_name) || Kaminari.config.param_name
+ query = params.merge(param_name => (scope.current_page + 1))
+ link_to_unless scope.last_page?, name, env['PATH_INFO'] + (query.empty? ? '' : "?#{query.to_query}"), options.merge(:rel => 'next') do
+ block.call; nil if block
+ end
+ end
+ end
+ end
+end
+
+if defined? I18n
+ I18n.load_path += Dir.glob(File.expand_path('../../../../config/locales/*.yml', __FILE__))
+end
+
+rescue LoadError
+
+$stderr.puts "[!]You shold install `padrino-helpers' gem if you want to use kaminari's pagination helpers with Sinatra."
+$stderr.puts "[!]Kaminari::Helpers::SinatraHelper does nothing now..."
+
+module Kaminari::Helpers
+ module SinatraHelper
+ def self.registered(*)
+ end
+ end
+end
+
+end
diff --git a/lib/kaminari/hooks.rb b/lib/kaminari/hooks.rb
new file mode 100644
index 0000000..2a1a1f4
--- /dev/null
+++ b/lib/kaminari/hooks.rb
@@ -0,0 +1,37 @@
+module Kaminari
+ class Hooks
+ def self.init!
+ ActiveSupport.on_load(:active_record) do
+ require 'kaminari/models/active_record_extension'
+ ::ActiveRecord::Base.send :include, Kaminari::ActiveRecordExtension
+ end
+
+ if defined? ::Mongoid
+ require 'kaminari/models/mongoid_extension'
+ ::Mongoid::Document.send :include, Kaminari::MongoidExtension::Document
+ ::Mongoid::Criteria.send :include, Kaminari::MongoidExtension::Criteria
+ end
+
+ ActiveSupport.on_load(:mongo_mapper) do
+ require 'kaminari/models/mongo_mapper_extension'
+ ::MongoMapper::Document.send :include, Kaminari::MongoMapperExtension::Document
+ ::Plucky::Query.send :include, Kaminari::PluckyCriteriaMethods
+ ::Plucky::Query.send :include, Kaminari::PageScopeMethods
+ end
+
+ if defined? ::DataMapper
+ require 'kaminari/models/data_mapper_extension'
+ ::DataMapper::Collection.send :include, Kaminari::DataMapperExtension::Collection
+ ::DataMapper::Model.append_extensions Kaminari::DataMapperExtension::Model
+ # ::DataMapper::Model.send :extend, Kaminari::DataMapperExtension::Model
+ end
+ require 'kaminari/models/array_extension'
+
+ require File.join(File.dirname(__FILE__), 'models/array_extension')
+
+ ActiveSupport.on_load(:action_view) do
+ ::ActionView::Base.send :include, Kaminari::ActionViewExtension
+ end
+ end
+ end
+end
diff --git a/lib/kaminari/models/array_extension.rb b/lib/kaminari/models/array_extension.rb
index 58f3d20..5454da0 100644
--- a/lib/kaminari/models/array_extension.rb
+++ b/lib/kaminari/models/array_extension.rb
@@ -1,3 +1,4 @@
+require 'active_support/core_ext/module'
module Kaminari
# Kind of Array that can paginate
class PaginatableArray < Array
diff --git a/lib/kaminari/railtie.rb b/lib/kaminari/railtie.rb
index 240ab90..a5d908a 100644
--- a/lib/kaminari/railtie.rb
+++ b/lib/kaminari/railtie.rb
@@ -1,49 +1,7 @@
-require 'rails'
-# ensure ORMs are loaded *before* initializing Kaminari
-begin; require 'mongoid'; rescue LoadError; end
-begin; require 'mongo_mapper'; rescue LoadError; end
-begin; require 'dm-core'; require 'dm-aggregates'; rescue LoadError; end
-
-require 'kaminari/config'
-require 'kaminari/helpers/action_view_extension'
-require 'kaminari/helpers/paginator'
-require 'kaminari/models/page_scope_methods'
-require 'kaminari/models/configuration_methods'
-
module Kaminari
class Railtie < ::Rails::Railtie #:nodoc:
initializer 'kaminari' do |app|
- ActiveSupport.on_load(:active_record) do
- require 'kaminari/models/active_record_extension'
- ::ActiveRecord::Base.send :include, Kaminari::ActiveRecordExtension
- end
-
- if defined? ::Mongoid
- require 'kaminari/models/mongoid_extension'
- ::Mongoid::Document.send :include, Kaminari::MongoidExtension::Document
- ::Mongoid::Criteria.send :include, Kaminari::MongoidExtension::Criteria
- end
-
- ActiveSupport.on_load(:mongo_mapper) do
- require 'kaminari/models/mongo_mapper_extension'
- ::MongoMapper::Document.send :include, Kaminari::MongoMapperExtension::Document
- ::Plucky::Query.send :include, Kaminari::PluckyCriteriaMethods
- ::Plucky::Query.send :include, Kaminari::PageScopeMethods
- end
-
- if defined? ::DataMapper
- require 'kaminari/models/data_mapper_extension'
- ::DataMapper::Collection.send :include, Kaminari::DataMapperExtension::Collection
- ::DataMapper::Model.append_extensions Kaminari::DataMapperExtension::Model
-# ::DataMapper::Model.send :extend, Kaminari::DataMapperExtension::Model
- end
- require 'kaminari/models/array_extension'
-
- require File.join(File.dirname(__FILE__), 'models/array_extension')
-
- ActiveSupport.on_load(:action_view) do
- ::ActionView::Base.send :include, Kaminari::ActionViewExtension
- end
+ Kaminari::Hooks.init!
end
end
end
diff --git a/lib/kaminari/sinatra.rb b/lib/kaminari/sinatra.rb
new file mode 100644
index 0000000..37623f6
--- /dev/null
+++ b/lib/kaminari/sinatra.rb
@@ -0,0 +1,8 @@
+require 'kaminari'
+module Kaminari
+ module Helpers
+ autoload :SinatraHelper, 'kaminari/helpers/sinatra_helper'
+ end
+end
+Kaminari::Hooks.init!
+