Giter Site home page Giter Site logo

shale's Introduction

Shale

Build Status GitHub releases GitHub license

Paginator for Amber Framework

Installation

Add this to your application's shard.yml:

dependencies:
  shale:
    github: c910335/shale

Usage

Note: Shale only supports Granite and PostgreSQL currently.

# config/initializers/paginator.cr
require "shale/amber" # for page helper
require "shale/granite" # for granite adapter
Shale.base_url = "https://base.url"

# src/controllers/application_controller.cr
class ApplicationController < Amber::Controller::Base
  include Shale::Amber::PageHelper(Shale::Granite::Adapter)
end

# src/controller/sample_controller
class SampleController < ApplicationController
  def index
    samples = paginate Sample
    # render your view with samples
  end
end

Shale::Amber::PageHelper#paginate reads parameters from params and path from request.path and adds links to response.headers, then returns the paginated data.

Parameters

name type required default value
page number false 1
per_page number false 8
sort string false id must be one of the columns
direction string false desc asc or desc

Response Header

reference: RFC 5988 - Web Linking

Link: <https://base.url/samples?page=2&per_page=3&sort=id&direction=desc>; rel="prev",
  <https://base.url/samples?page=4&per_page=3&sort=id&direction=desc>; rel="next",
  <https://base.url/samples?page=1&per_page=3&sort=id&direction=desc>; rel="first",
  <https://base.url/samples?page=8&per_page=3&sort=id&direction=desc>; rel="last"

Default Values

# Global
Shale.base_url = "https://base.url" # required
Shale.path = "/path"
Shale.page = 1
Shale.per = 8
Shale.order = :id
Shale.direction = :desc

# Scoped
class SomeController
  include Shale::Amber::PageHelper(Shale::Granite::Adapter)

  shale_base_url = "https://base.url"
  shale_path = "/path"
  shale_page = 1
  shale_per = 8
  shale_order = :id
  shale_direction = :desc
end

Customization

Paginator

This is what Shale::Amber::PageHelper looks like.

require "shale"

module Shale::Amber::PageHelper(Adapter)
  include Shale::Paginator(Adapter)

  def paginate(model)
    paginate model do |p|
      p.path request.path
      p.page params["page"].to_i if params["page"]?
      p.per params["per_page"].to_i if params["per_page"]?
      p.order params["sort"] if params["sort"]?
      p.direction params["direction"] if params["direction"]?
      p.headers response.headers
    end
  end
end

You can change the source of path or parameters by building your own paginator.

Adapter

  • inherits Shale::BaseAdapter
  • implements #count(model) and #select(model) with #page, #per, #order and #direction

For example, this is an ArrayAdapter.

require "shale"

class ArrayAdapter < Shale::BaseAdapter
  def count(array)
    array.size
  end

  def select(array)
    sorted = if direction.to_s == "desc"
               array.sort { |a, b| b[order] <=> a[order] }
             else
               array.sort { |a, b| a[order] <=> b[order] }
             end
    sorted[(page - 1) * per, per]
  end
end

Which is useful to paginate Array(Hash(Symbol, Int32)).

class ArrayPaginator
  include Shale::Paginator(ArrayAdapter)
end

array = Array.new(10) do |i|
  {:number => 10 - i}
end

paginated = ArrayPaginator.new.paginate array do |p|
  p.page 2
  p.per 3
  p.order :number
  p.direction :asc
end

pp paginated # => [{:number => 4}, {:number => 5}, {:number => 6}]

Development

Since Shale depends on PostgreSQL, we run specs with Docker.

$ docker-compose build
$ docker-compose run migrate
$ docker-compose run spec

Contributing

  1. Fork it (https://github.com/c910335/shale/fork)
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create a new Pull Request

Contributors

  • c910335 Tatsiujin Chin - creator, maintainer

shale's People

Contributors

c910335 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

shale's Issues

logo proposal

I am a graphic designer. I have a logo proposal for you. Do you have an idea? What do you say?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.