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 6, 2024
1 parent 9f93dd2 commit 1bcb05f
Show file tree
Hide file tree
Showing 8 changed files with 154 additions and 63 deletions.
47 changes: 47 additions & 0 deletions docs/api/jsonapi.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
---
title: JSON:API
image: null
---

# JSON:API

Pagy can be `JSON:API` compliant by just setting the `:jsonapi` variable to true. 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`.

## Synopsis

||| pagy.rb (initializer)
```ruby
require 'pagy/extras/jsonapi'
# optionally disable it by default (opt-in)
Pagy::DEFAULT[:jsonapi] = false
# optional but useful extras
require 'pagy/extras/items'
require 'pagy/extras/metadata'
```
|||

||| Controller
```ruby
# enable/disable on single object
@pagy, @items = pagy(collection, jsonapi: true)
# optionl/custom setup
@pagy, @items = 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]
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.

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
17 changes: 9 additions & 8 deletions lib/config/pagy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,16 @@

# Other Variables
# See https://ddnexus.github.io/pagy/docs/api/pagy#other-variables
# Pagy::DEFAULT[:size] = [1,4,4,1] # default
# Pagy::DEFAULT[:page_param] = :page # default
# Pagy::DEFAULT[:size] = [1,4,4,1] # default
# Pagy::DEFAULT[:page_param] = :page # default
# The :params can be also set as a lambda e.g ->(params){ params.exclude('useless').merge!('custom' => 'useful') }
# Pagy::DEFAULT[:params] = {} # default
# Pagy::DEFAULT[:fragment] = '#fragment' # example
# Pagy::DEFAULT[:link_extra] = 'data-remote="true"' # example
# Pagy::DEFAULT[:i18n_key] = 'pagy.item_name' # default
# Pagy::DEFAULT[:cycle] = true # example
# Pagy::DEFAULT[:request_path] = "/foo" # example
# Pagy::DEFAULT[:params] = {} # default
# Pagy::DEFAULT[:fragment] = '#fragment' # example
# Pagy::DEFAULT[:link_extra] = 'data-remote="true"' # example
# Pagy::DEFAULT[:i18n_key] = 'pagy.item_name' # default
# Pagy::DEFAULT[:cycle] = true # example
# Pagy::DEFAULT[:request_path] = "/foo" # example
# Pagy::DEFAULT[:jsonapi] = true # example


# Extras
Expand Down
Loading

0 comments on commit 1bcb05f

Please sign in to comment.