cry_paginator
cry_paginator
A simple, flexible, and high-performance pagination library for Crystal inspired by Ruby's Pagy gem.
Features
- Lightweight and fast
- Configurable pagination options
- Support for SQL queries with
crystal-db
- Dynamic pagination window with gaps
- Methods for checking first/last page and navigating between pages
- Type-safe Crystal implementation
Installation
Add the shard to your shard.yml
:
dependencies:
cry_paginator:
github: dcalixto/cry_paginator
Then, run shards install.
Usage
-
Include Paginator in Your Model
-
To enable pagination on a model, include the Paginator module in your model class:
# src/models/post.cr
require "cry_paginator"
class Post
include DB::Serializable
include Paginator
include Paginator::Model
end
Paginate Your Data
Use the paginate method to fetch paginated records:
# Access pagination data
paginator.items # Current page items
paginator.total # Total number of items
paginator.total_pages # Total number of pages
paginator.current_page # Current page number
paginator.next_page # Next page number or nil
paginator.prev_page # Previous page number or nil
# Custom Page Window
paginator.page_window(7) # Example output: [1, :gap, 5, 6, 7, 8, :gap, 20]
Configuration
Override the defaults globally in your app:
Paginator.config = {
per_page: 20,
window_gap: true,
window_size: 2
order_by: "created_at DESC"
}
Or override them for individual calls:
Page.paginate(page: 2, per_page: 20, order_by: "created_at DESC")
Dynamic Pagination Window
You can now use the pagination with or without window gaps:
# Without window gap (default)
posts = Post.paginate(db, page: 1)
# With window gap
posts = Post.paginate(db, page: 1, window_gap: true)
# With custom window size
posts = Post.paginate(db, page: 1, window_gap: true, window_size: 3)
Controller Setup
The controller retrieves paginated data from the database using the Paginator shard.
Example: ArticlesController (Kemal Framework)
# src/controllers/posts_controller.cr
class PostsController
include Paginator::Backend
include Paginator::ViewHelper
def index
page = (env.params.query["page"]? || "1").to_i
per_page = 12
paginator = Post.paginate(
page: page,
per_page: per_page,
order: "created_at DESC"
)
posts = paginator.items
render "src/views/posts/index.ecr"
end
end
Integration in Views
Use the data provided by the controller to render paginated content and navigation links.
Example Usage in a Kemal View (index.ecr)
<div class="posts">
<% posts.each do |post| %>
<article>
<h2><%= post.title %></h2>
<p><%= post.content %></p>
</article>
<% end %>
</div>
<%= pagination_info(paginator, "posts") if paginator %>
<%= pagination_nav(paginator) if posts %>
Example Output Navigation Links
#TODO
Info
<div class="pagination-info">
Showing 11-20 of 100 articles.
</div>
Styles for Pagination
Add some simple CSS to style the pagination links.
/* public/css/pagination.css */
.pagination-nav {
display: flex;
gap: 0.5rem;
list-style: none;
margin-bottom: 13rem;
}
.pagination ul li {
list-style: none;
}
.pagination ul > li {
display: inline-block;
/* You can also add some margins here to make it look prettier */
}
.pagination-link {
text-decoration: none;
}
.pagination-link:hover {
text-decoration: underline;
}
.is-current {
font-weight: bold;
}
.is-disabled {
color: #aaa;
pointer-events: none;
}
.pagination-gap {
display: inline-block;
padding: 0.5rem;
color: #666;
}
.pagination {
display: flex;
align-items: center;
justify-content: center;
gap: 0.5rem;
}
.pagination-list {
display: flex;
list-style: none;
margin: 0;
padding: 0;
gap: 0.25rem;
}
.pagination-link.is-disabled {
opacity: 0.5;
pointer-events: none;
}
Testing
Use spectator to write tests:
spec/paginator_spec.cr
require "spec"
require "../src/paginator"
describe Paginator do
it "returns paginated data" do
# Test logic here
end
end
Run the tests:
crystal spec
Contributing
- Fork it (https://github.com/dcalixto/cry_paginator/fork)
- Create your feature branch (git checkout -b my-new-feature)
- Commit your changes (git commit -am 'Add some feature')
- Push to the branch (git push origin my-new-feature)
- Create a new Pull Request
License
This shard is available as open source under the terms of the MIT License.
cry_paginator
- 1
- 0
- 0
- 0
- 3
- about 2 hours ago
- December 3, 2024
Sun, 22 Dec 2024 01:03:57 GMT