shale
Version, currently 0.2.48 versions
github.com/c910335/shale
Paginator for Amber Framework
9 stars
0 dependents
License: MIT
Installation
# Add this to your shard.yml
dependencies:
shale:
github: c910335/shale
version: ~> 0.2.4Then run:
shards installshard.yml
- Crystal
0.34.0- License
- MIT
- Author
- Tatsiujin Chin <c910335@gmail.com>
Dependencies
Development Dependencies
README
# Shale
[](https://travis-ci.com/c910335/shale)
[](https://github.com/c910335/shale/releases)
[](https://github.com/c910335/shale/blob/master/LICENSE)
Paginator for [Amber Framework](https://github.com/amberframework/amber)
## Installation
Add this to your application's `shard.yml`:
```yaml
dependencies:
shale:
github: c910335/shale
```
## Usage
Note: Shale only supports [Granite](https://github.com/amberframework/granite) and PostgreSQL currently.
```crystal
# 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](https://tools.ietf.org/html/rfc5988)
```
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
```crystal
# 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.
```crystal
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`.
```crystal
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))`.
```crystal
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](https://github.com/c910335) Tatsiujin Chin - creator, maintainer
Documentation
Built from the current release. The first visit to a release nobody has asked for starts its build.
Links
This release
- Version
0.2.4- Tagged
- Apr 13, 2020
- Commit
b8a146399a42- Crystal
0.34.0- Indexed
- yes
Dependents
No indexed shard depends on this one yet.
Repository
github.com/c910335/shale
Metadata
- Created
- Aug 12, 2026
- Updated
- Aug 13, 2026
- Synced
- Aug 13, 2026
- Versions
- 8