Skip to content

Commit

Permalink
JSON:API specifications
Browse files Browse the repository at this point in the history
  • Loading branch information
ddnexus committed Jan 7, 2024
1 parent 9f93dd2 commit 92dc92e
Show file tree
Hide file tree
Showing 14 changed files with 237 additions and 85 deletions.
55 changes: 28 additions & 27 deletions docs/api/pagy.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,8 @@ Experimental: Its only function in the `Pagy` class is supporting the API of var
==- `label_for(page)`

Experimental: Its only function in the `Pagy` class is supporting the API of various frontend methods that require labelling for `Pagy::Calendar` instances. It returns the page label that will get displayed in the helpers/templates.
===

===

## Variables

Expand All @@ -125,39 +125,40 @@ They are all integers:

### Other Variables

| Variable | Description | Default |
|:--------------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:-------------------|
| `:size` | The size of the page links to show: array of initial pages, before current page, after current page, final pages. _(see also [How to control the page links](/docs/how-to.md#control-the-page-links))_ | `[1,4,4,1]` |
| `:page_param` | The name of the page param name used in the url. _(see [How to customize the page param](/docs/how-to.md#customize-the-page-param))_ | `:page` |
| `:params` | It can be a `Hash` of params to add to the URL, or a `Proc` that can edit/add/delete the request params _(see [How to customize the params](/docs/how-to.md#customize-the-params))_ | `{}` |
| `:fragment` | The arbitrary fragment string (including the "#") to add to the url. _(see [How to customize the params](/docs/how-to.md#customize-the-params))_ | `""` |
| `:link_extra` | The extra attributes string (formatted as a valid HTML attribute/value pairs) added to the page links _(see [How to customize the link attributes](/docs/how-to.md#customize-the-link-attributes))_ | `""` |
| `:i18n_key` | The i18n key to lookup the `item_name` that gets interpolated in a few helper outputs (see [How to customize the item name](/docs/how-to.md#customize-the-item-name)) | `"pagy.item_name"` |
| `:cycle` | Enable cycling/circular/infinite pagination: `true` sets `next` to `1` when the current page is the last page | `false` |
| `:request_path` | Allows overriding the request path for pagination links. If left blank, helpers will use `request.path`. NB: Do not pass in a full URL, but the path: For example, given `https://ddnexus.github.io/pagy/docs/api/pagy/` the path to be passed in is: `pagy/docs/api/pagy/`. (See: [Customize the request path](/docs/how-to.md#customize-the-request-path) )| `request.path` |
| Variable | Description | Default |
|:----------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:-------------------|
| `:size` | The size of the page links to show: array of initial pages, before current page, after current page, final pages. _(see also [How to control the page links](/docs/how-to.md#control-the-page-links))_ | `[1,4,4,1]` |
| `:page_param` | The name of the page param name used in the url. _(see [How to customize the page param](/docs/how-to.md#customize-the-page-param))_ | `:page` |
| `:params` | It can be a `Hash` of params to add to the URL, or a `Proc` that can edit/add/delete the request params _(see [How to customize the params](/docs/how-to.md#customize-the-params))_ | `{}` |
| `:fragment` | The arbitrary fragment string (including the "#") to add to the url. _(see [How to customize the params](/docs/how-to.md#customize-the-params))_ | `""` |
| `:link_extra` | The extra attributes string (formatted as a valid HTML attribute/value pairs) added to the page links _(see [How to customize the link attributes](/docs/how-to.md#customize-the-link-attributes))_ | `""` |
| `:i18n_key` | The i18n key to lookup the `item_name` that gets interpolated in a few helper outputs (see [How to customize the item name](/docs/how-to.md#customize-the-item-name)) | `"pagy.item_name"` |
| `:cycle` | Enable cycling/circular/infinite pagination: `true` sets `next` to `1` when the current page is the last page | `false` |
| `:request_path` | Allows overriding the request path for pagination links. If left blank, helpers will use `request.path`. NB: Do not pass in a full URL, but the path: For example, given `https://ddnexus.github.io/pagy/docs/api/pagy/` the path to be passed in is: `pagy/docs/api/pagy/`. (See: [Customize the request path](/docs/how-to.md#customize-the-request-path) ) | `request.path` |
| `jsonapi` | Enable `jsonapi` compliance of the pagy query params | `false` |

There is no specific validation for non-instance variables.

### Attribute Readers

Pagy exposes all the instance variables needed for the pagination through a few attribute readers. They all return integers (or `nil`), except the `vars` hash:

| Reader | Description |
|:---------|:-------------------------------------------------------------------------------------------------------------------|
| `count` | The collection `:count` |
| `page` | The current page number |
| `items` | The requested number of items for the page |
| `pages` | The number of total pages in the collection (same as `last` but with cardinal meaning) |
| `in` | The number of the items in the page |
| `last` | The number of the last page in the collection (same as `pages` but with ordinal meaning) |
| `offset` | The number of items skipped from the collection in order to get the start of the current page (`:outset` included) |
| `from` | The collection-position of the first item in the page (`:outset` excluded) |
| `to` | The collection-position of the last item in the page (`:outset` excluded) |
| `prev` | The previous page number or `nil` if there is no previous page |
| `next` | The next page number or `nil` if there is no next page |
| `vars` | The variables hash |
| `params` | The `:params` variable (`Hash` or `Proc`) |
| `request_path` | The request path used for pagination helpers. If blank, helpers will use `request.path` |
| Reader | Description |
|:---------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `count` | The collection `:count` |
| `page` | The current page number |
| `items` | The requested number of items for the page |
| `pages` | The number of total pages in the collection (same as `last` but with cardinal meaning) |
| `in` | The number of the items in the page |
| `last` | The number of the last page in the collection (same as `pages` but with ordinal meaning) |
| `offset` | The number of items skipped from the collection in order to get the start of the current page (`:outset` included) |
| `from` | The collection-position of the first item in the page (`:outset` excluded) |
| `to` | The collection-position of the last item in the page (`:outset` excluded) |
| `prev` | The previous page number or `nil` if there is no previous page |
| `next` | The next page number or `nil` if there is no next page |
| `vars` | The variables hash |
| `params` | The `:params` variable (`Hash` or `Proc`) |
| `request_path` | The request path used for pagination helpers. If blank, helpers will use `request.path` |

### Lowest limit analysis

Expand Down
26 changes: 17 additions & 9 deletions docs/extras/items.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,36 +13,44 @@ It works also with the [countless](countless.md), [searchkick](searchkick.md), [

## Synopsis

### Default usage

||| pagy.rb (initializer)
```ruby
require 'pagy/extras/items' # works without further configuration
```
|||


||| Controller
```ruby
# enabled by default
@pagy, @records = pagy(collection)
# you can disable it explicitly for specific requests
@pagy, @records = pagy(Product.all, items_extra: false)

# or see below:
@pagy, @records = pagy(collection, items_extra: false)
```
|||

### Custom usage

||| pagy.rb (initializer)
```ruby
# disable it by default (opt-in)
Pagy::DEFAULT[:items_extra] = false # default true
# in this case you have to enable it explicitly when you want it
@pagy, @records = pagy(Product.all, items_extra: true)

# optionally disable it by default
Pagy::DEFAULT[:items_extra] = false # default true
# customize the defaults if you need to
Pagy::DEFAULT[:items_param] = :custom_param # default :items
Pagy::DEFAULT[:max_items] = 200 # default 100
```
|||

||| Controller
```ruby
# disabled by default by the above Pagy::DEFAULT[:items_extras] = false
@pagy, @records = pagy(collection)
# explicitly enable it for specific requests
@pagy, @records = pagy(collection, items_extra: true)
```
|||

See [Javascript](/docs/api/javascript.md) (only if you use the `pagy_items_selector_js` UI)

## Files
Expand Down
77 changes: 77 additions & 0 deletions docs/extras/jsonapi.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
---
title: Jsonapi
categories:
- Feature
- Extra
---

# Jsonapi Extra

Implements `JSON:API` specifications for pagination.

When enabled, the query params used in the pagy URLs are nested under the `page` param, as specified by the [Query Parameter Family](https://jsonapi.org/format/#query-parameters-families) e.g. `https://example.com/products?page[page]=2&page[items]=30`.

It works also with the [countless](countless.md), [searchkick](searchkick.md), [elasticsearch_rails](elasticsearch_rails.md) and [meilisearch](/docs/extras/meilisearch.md) extras.

It does not make sense (and doesn't work) with the [Calendar](countless.md) extra.

## Synopsis

### Default usage

||| pagy.rb (initializer)
```ruby
require 'pagy/extras/jsonapi' # works without further configuration
```
|||

||| Controller
```ruby
# enabled by default
@pagy, @records = pagy(collection)
# you can disable it explicitly for specific requests
@pagy, @records = pagy(collection, jsonapi: false)
```
|||

### Custom usage

||| pagy.rb (initializer)
```ruby
# optionally require other jsonapi-useful extras
require 'pagy/extras/items'
# jsonapi must be required AFTER other extras
require 'pagy/extras/jsonapi'
# optionally disable it by default (opt-in)
Pagy::DEFAULT[:jsonapi] = false # default true
```
|||

||| Controller
```ruby
# disabled by default by the above Pagy::DEFAULT[:jsonapi] = false
@pagy, @records = pagy(collection)
# explicitly enable it for specific requests
@pagy, @records = pagy(collection, jsonapi: true)
# optional/custom setup
@pagy, @records = pagy(collection, jsonapi: true, # enable the jsonapi specifications
items_extra: true, # enable the items extra
page_param: :number, # use page[number] param name instead of page[page]
items_params: :size) # use page[size] param name instead of page[items]
# get the links URL hash
links_hash = pagy_jsonapi_links(@pagy)
#=> {first: 'https://example.com/products?page[number]=1&page[size]=50&...',
# last: 'https://example.com/products?page[number]=32&page[size]=50&...',
# prev: 'https://example.com/products?page[number]=31&page[size]=50&...',
# next: 'https://example.com/products?page[number]=33&page[size]=50&...'}
```
|||

## Interaction with extras

If you want to allow your JSON:API app to allow the client to request a specific number of items per page and capping the request to a max number you can use the [items extra](/docs/extras/items.md).

The [metadata extra]((/docs/extras/metadata.md)) implements also the `pagy_jsonapi_links` method returning the link hash (https://jsonapi.org/format/#fetching-pagination)

An app that implements a JSON:API, if wants to allow the client to request a specific number of items per page, also capping the max number requested by the client.

Loading

0 comments on commit 92dc92e

Please sign in to comment.