diff --git a/.github/.env b/.github/.env
deleted file mode 100644
index ddaef4fd4..000000000
--- a/.github/.env
+++ /dev/null
@@ -1,2 +0,0 @@
-GEM=pagy
-VERSION=7.0.11
diff --git a/.github/ISSUE_TEMPLATE/Code.yml b/.github/ISSUE_TEMPLATE/Code.yml
index fb48d1013..4cdb06d37 100644
--- a/.github/ISSUE_TEMPLATE/Code.yml
+++ b/.github/ISSUE_TEMPLATE/Code.yml
@@ -7,32 +7,19 @@ body:
- type: markdown
attributes:
value: >
- Thanks for taking the time to fill out this bug report!
-
-
- ### IMPORTANT
-
-
- _Code Issues are reserved for real, reproducible pagy bugs.
- If you are not sure that your problem is a bug, please ask for solutions in the
- [Q&A](https://github.com/ddnexus/pagy/discussions/categories/q-a) support area._
-
-
- ### PREREQUISITE
-
-
- **We need running code to reproduce the problem with a single click or command!**
-
-
- Please, understand that we cannot write the code that fails for you,
- so ONLY pick and provide your preferred support from the list below...
+ ### Thank you for your bug report!
+
+ Please, understand that code issues are reserved for real, reproducible pagy bugs.
+
+ _If you are not sure that your problem is actually a bug,
+ please ask for [support](https://github.com/ddnexus/pagy/discussions/categories/q-a) instead._
- type: checkboxes
id: prereq
attributes:
label: Before submitting...
options:
- - label: I upgraded to the latest version of pagy
+ - label: I upgraded to pagy version 8.0.0
required: true
- label: I searched through the [Documentation](https://ddnexus.github.io/pagy/)
required: true
@@ -41,34 +28,46 @@ body:
- label: I searched through the [Q&A](https://github.com/ddnexus/pagy/discussions/categories/q-a)
required: true
+ - type: markdown
+ attributes:
+ value: >
+ ### IMPORTANT!
+
+ **The issue MUST provide a code file confirming the bug AND complying with the list below
+ OR it will be automatically closed!**
+
+
+ #### Valid code files
+
+
+ - Edited copy of a single-file APP from the [Pagy Playground](https://ddnexus.github.io/pagy/playground)
+
+ - Link to a pagy fork containing an added test file
+
+ - A plain ruby file that can run as a single command `ruby issue_123.rb`
+ _(without any other setup step, installation or guessing, and with no or minimal interaction required)_
+
+
+ _If anything is unclear to you, please ask for [support](https://github.com/ddnexus/pagy/discussions/categories/q-a).
+ We will be happy to help._
+
- type: checkboxes
id: support
attributes:
- label: I am providing...
- description: |
- ...at least one of the following code supports reproducing the issue:
+ label: REQUIREMENTS
options:
- - label: >
- Simple snippet that would work **"as-is" in vanilla IRB (no rails console) without invoking
- any external/non-pagy code or gem!** (You may find the
- [Pagy::Console](https://ddnexus.github.io/pagy/docs/api/console) helpful)
- - label: Plain ruby file that can run as `ruby my-problem.rb`
- - label: >
- Edited copy of the single file
- [pagy_standalone.ru](https://github.com/ddnexus/pagy/blob/master/apps/pagy_standalone.ru)
- - label: >
- Edited copy of the single file
- [pagy_bare_rails.rb](https://github.com/ddnexus/pagy/blob/master/apps/pagy_bare_rails.rb)
- - label: Link of my own branch forked from pagy, which contains an added test file
- - label: >
- Link of my own branch forked from
- [any of the rails apps listed here.](https://github.com/stars/benkoshy/lists/rails-demo-apps-for-pagy)
- - label: A `docker-compose` file that uses only docker images and no local context and runs with `docker-compose up`
+ - label: I am providing a code file that confirms the bug
+ required: true
+ - label: I am aware that this issue will be automatically closed if the code file is missing or invalid
+ required: true
- type: textarea
id: description
attributes:
label: Description
- placeholder: Please, describe the issue...
+ placeholder: >
+ 1. Describe what actually happens
+
+ 2. Describe what should happen instead
validations:
required: true
diff --git a/.github/latest_release_body.md b/.github/latest_release_body.md
new file mode 100644
index 000000000..61922d0c4
--- /dev/null
+++ b/.github/latest_release_body.md
@@ -0,0 +1,12 @@
+## ⚠ WARNING
+
+We may drop pagy's less used CSS extras.
+
+If you wish to keep your favorites alive, please, [vote here](https://github.com/ddnexus/pagy/discussions/categories/survey)
+
+### ✴ What's new in 8.0.0 ✴
+
+- Better frontend helpers
+- New [Pagy Playground](https://ddnexus.github.io/pagy/playground/) to showcase, clone and develop pagy APPs without any setup on
+ your side (try the [pagy demo](https://ddnexus.github.io/pagy/playground.md#3-demo-app))
+- See the [Changelog](https://ddnexus.github.io/pagy/changelog) for possible breaking changes
diff --git a/.github/workflows/create-release.yml b/.github/workflows/create-release.yml
new file mode 100644
index 000000000..983bcb33e
--- /dev/null
+++ b/.github/workflows/create-release.yml
@@ -0,0 +1,28 @@
+name: Create Release
+
+on:
+ push:
+ tags:
+ - "[0-9]+.[0-9]+.[0-9]+"
+
+jobs:
+ build:
+ name: Create Release
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v4.1.2
+ - name: Create Release
+ id: create_release
+ uses: comnoco/create-release-action@v2.0.5
+ env:
+ # This token is provided by Actions, you do not need to create your own token
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ with:
+ tag_name: ${{ github.ref_name }}
+ release_name: Version ${{ github.ref_name }}
+ body_path: .github/latest_release_body.md
+ draft: false
+ prerelease: false
+ owner: ddnexus
+ repo: pagy
diff --git a/.idea/runConfigurations/Calendar.xml b/.idea/runConfigurations/Calendar.xml
index 6d0d36019..37a2ac510 100644
--- a/.idea/runConfigurations/Calendar.xml
+++ b/.idea/runConfigurations/Calendar.xml
@@ -2,7 +2,7 @@
-
+
@@ -24,8 +24,8 @@
-
-
+
+
\ No newline at end of file
diff --git a/.idea/runConfigurations/Standalone.xml b/.idea/runConfigurations/Demo.xml
similarity index 78%
rename from .idea/runConfigurations/Standalone.xml
rename to .idea/runConfigurations/Demo.xml
index 0bde99444..a4d4b980e 100644
--- a/.idea/runConfigurations/Standalone.xml
+++ b/.idea/runConfigurations/Demo.xml
@@ -1,8 +1,8 @@
-
+
-
+
@@ -24,8 +24,8 @@
-
-
+
+
\ No newline at end of file
diff --git a/.idea/runConfigurations/Rails.xml b/.idea/runConfigurations/Rails.xml
new file mode 100644
index 000000000..a1fbcf0ab
--- /dev/null
+++ b/.idea/runConfigurations/Rails.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/runConfigurations/Repro.xml b/.idea/runConfigurations/Repro.xml
new file mode 100644
index 000000000..c1d48dddf
--- /dev/null
+++ b/.idea/runConfigurations/Repro.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/runConfigurations/Safe_Release.xml b/.idea/runConfigurations/Rubygem_Release.xml
similarity index 87%
rename from .idea/runConfigurations/Safe_Release.xml
rename to .idea/runConfigurations/Rubygem_Release.xml
index 54b250995..36461529d 100644
--- a/.idea/runConfigurations/Safe_Release.xml
+++ b/.idea/runConfigurations/Rubygem_Release.xml
@@ -1,5 +1,5 @@
-
+
@@ -14,7 +14,7 @@
-
+
@@ -23,4 +23,4 @@
-
+
\ No newline at end of file
diff --git a/.rubocop.yml b/.rubocop.yml
index 4346bc38f..bccf6bedd 100644
--- a/.rubocop.yml
+++ b/.rubocop.yml
@@ -16,6 +16,7 @@ AllCops:
# "Unable to find gem panolint; is the gem installed? Gem::MissingSpecError" in all ruby versions
- vendor/bundle/**/*
- pnpm/**/*
+ - lib/optimist.rb
Layout/LineLength:
Max: 130
@@ -29,6 +30,7 @@ Layout/ExtraSpacing:
Enabled: true
Exclude:
- test/**/*
+ - lib/bin/pagy
Layout/EmptyLines:
Exclude:
@@ -53,6 +55,9 @@ Metrics:
Naming/VariableNumber:
CheckSymbols: false
+Naming/MethodParameterName:
+ Enabled: false
+
# not cool
Style/CommentedKeyword:
Enabled: false
@@ -61,6 +66,7 @@ Style/EmptyCaseCondition:
Style/LambdaCall:
Enabled: false
+
# cannot inline the disabling in the file because rubocop complains anyway
Style/RedundantInitialize:
Exclude:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f31bbbe41..91ef6f43e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,11 +4,19 @@ icon: versions-24
# CHANGELOG
+## ⚠ WARNING
+
+We may drop pagy's less used CSS extras.
+
+If you wish to keep them alive, please, [vote here](https://github.
+com/ddnexus/pagy/discussions/categories/survey).
+
## Breaking Changes
-If you upgrade from version `< 7.0.0` see the following:
+If you upgrade from version `< 8.0.0` see the following:
-- [Breaking changes in version 7.0.0](#version-700)
+- [Breaking changes in version 8.0.0](#version-800)
+- [Breaking changes in version 7.0.0](CHANGELOG_LEGACY.md#version-700)
- [Breaking changes in version 6.0.0](CHANGELOG_LEGACY.md#version-600)
- [Breaking changes in version 5.0.0](CHANGELOG_LEGACY.md#version-500)
- [Breaking changes in version 4.0.0](CHANGELOG_LEGACY.md#version-400)
@@ -18,148 +26,63 @@ If you upgrade from version `< 7.0.0` see the following:
## Deprecations
-- The "pagination" CSS class for the `pagy_nav`, `pagy_nav_js` and `pagy_combo_nav_js` has been deprecated and will be removed in
- version 8. Replace it with the new "pagy" CSS class added also to the `pagy-items-selector-js`.
-
+None
-## Version 7.0.11
-
-- Fix jsonapi prev and next keys for unavailable links (#665)
-- Docs fixes
-
-## Version 7.0.10
-
-- Added name attribute to combo and items input tags; removed pagy_marked_link and refactored js input action
-
-## Version 7.0.9
-
-- Improve all pagy apps
-- Normalized bootstrap, bulma, foundation, navs extra
-
-## Version 7.0.8
-
-- Update gems and fix a rubocop bug
-- Add all styles to pagy_styles.ru
-- Better pagy stylesheets
-- Fix for uikit extra prev and next link duplicating chevrons
-- Change aria_Label to aria_label for Arabic locale (#657)
-
-## Version 7.0.7
-
-- Fix for retype exluding linked files and showing category images
-- Fix for first *nav_js page not active with trim (introduced with the #656 fix 7e2f118)
-- Normalize pagy apps; implement pagy_styles.ru
-
-## Version 7.0.6
-
-- Internal renaming of frontend constants
-- Fix for disabled links and missing or extra ARIA attributes in frontend extras
-- Boostrap fix for current page link; pagy.js fix for trim of current page (closes #656)
-
-## Version 7.0.5
-
-- Updated gems, npm modules, contributors
-- Added the pagy stylesheets to the gem, updated apps, docs and manifest
-- Added note for the metrics and compacted the chart section (closes #652)
-- Docs: fix formatting, grammar in README.md (#654)
-- Add note about PR base branches to readme (#653)
-
-## Version 7.0.4
-
-- Tailwind styles integrated with the pagy-items-selector-js (#646)
-- Deprecated the "pagination" CSS class, use the "pagy" CSS class that has been added to all the interactive pagy helper outputs
-- Fix indentation of cs locale (#648); add "pagy.aria_label.nav.few" entry, duplicating the "other" pluralization
-- Update cs translations (#648)
-- Expand/Correct changes about `pagy.prev` and `pagy.next` (#649)
-
-## Version 7.0.3
-
-- Remove extra space in `pagy_nav`, `pagy_nav_js` and `.pagy-combo-input`
-- Refactor of tailwind styles and docs (closes #646)
-- Add `pagy_tailwind_app.ru` (#646)
-- Add missing CSS breaking change to the CHANGELOG (#646)
-
-## Version 7.0.2
-
-- Fix for missing to fetch count_args default (close #645)
-- Non-code improvements
-
-## Version 7.0.1
-
-- Updates ckb translations to be complaint with ARIA in v7.x.x (#643)
-
-## Version 7.0.0
+## Version 8.0.0
### Breaking changes
-- Dropped old rubies support: Pagy follows the [ruby end-of-life](https://endoflife.date/ruby) supported rubies now.
-- Renamed `:i18n_key` > `:item_i18n_key`
-- Refactored `support` extra
- - Renamed `pagy_prev_link` to `pagy_prev_html` to avoid confusion with pagy_prev_link_tag
- - Removed `pagy_next_link` to `pagy_next_html` to avoid confusion with pagy_next_link_tag
-- Rack 3 breaking changes:
- - The `headers` extra produces all lowercase headers, regardless how you set
- them [see rack issue](https://github.com/rack/rack/issues/1592)
- - Removed `:escaped_html` option from `pagy_url_for` (only breaking if you override the method or use the option directly)
-- Dictionary structure changes: (affects only app with custom helper/templates/dictionary entries)
- - The `nav` entry has been flattened: `pagy.nav.*` entries are now `pagy.*`:
- - If you have custom helpers/templates: search the keys that contain `'.nav.'` and replace them with `'.'`
- - If you have custom dictionary entries (overrides): remove the `'nav:'` line and unindent its block
- - A few labels used as `aria-label` have been added: you may want to add/use them to your custom helper/templates/dictionaries
- for ARIA compliance.
- - `pagy.aria_label.nav` Pluralized entry: used in the `nav` element
- - `pagy.aria_label.prev`, `pagy.aria_label.next` Single entry: used in the prev/next `a` link elements
-
-### Default changes (possibly breaking test/views)
-
-- Changed `Pagy::DEFAULT[:size]` variable defaults from `[1, 4, 4, 1]` to `7`. You can explicitly set/restore it in the
- initializer, if your app was relying on it.
-- Added sensible `:size` defaults in Calendar Unit subclasses. You can explicitly set it in the initializer, if your app was
- relying on it.
- - `Pagy::Calendar::Day::DEFAULT[:size]` `31`
- - `Pagy::Calendar::Month::DEFAULT[:size]` `12`
- - `Pagy::Calendar::Quarter::DEFAULT[:size]` `4`
- - `Pagy::Calendar::Year::DEFAULT[:size]` `10`
-- Changed a few `format` defaults in Calendar Unit subclasses. You can explicitly set it in the initializer, if your app was
- relying on it.
- - `Pagy::Calendar::Day::DEFAULT[:format]` from `'%Y-%m-%d'` to `'%d'`
- - `Pagy::Calendar::Month::DEFAULT[:format]` from `'%Y-%m'` to `'%b'`
- - `Pagy::Calendar::Quartr::DEFAULT[:format]` from `'%Y-Q%q'` to `'Q%q'`
-
-### Visual changes (possibly breaking test/views)
-
-- The ARIA label compliance required the refactoring of all the nav helpers that might look slightly different now:
-- The text for `"Prev"` and `"Next"` is now used for the `aria-label` (actually as `"Previous"` and `"Next"`) and has been
- replaced in the UI as `<` and `>`. You can edit the dictionary entries `pagy.prev` and `pagy.next` if you want to revert it to
- the previous default (`‹ Prev` and `Next ›`)
-
-### CSS changes (possibly looking different/broken)
-
-- The HTML of the current page in `pagy_nav` and `pagy_nav_js` has been changed from simple text (e.g. `5`) to a
- disabled link (e.g. `5`). That affects your CSS rules and
- the old tailwind examples targeting the page links, now overreaching the current page.
- - You may fix eventual problems either by replacing the affected `a` rules with narrower `a[href]` selectors however if you use
- Tailwind we recommend to use the [improved tailwind style](https://ddnexus.github.io/pagy/docs/extras/tailwind/), that you can
- adapt in no time to anything you need.
-- The extra spaces added between pages of `pagy_nav` and `pagy_nav_js` have been removed
-- The `pagy-combo-nav-js .pagy-combo-input` internal element x-margins have been removed
-
-### Internal renaming of private methods (unlikely to break anything)
-
-You should not have used any of the private methods, but if you did so, you will get a `NoMethodError`
-(undefined method...) very easy to fix by simply renaming, because there are no changes in the logic.
+- Renamed/removed the following arguments for all the helpers:
+ - Search `pagy_id:`, replace with `id:`
+ - Search `nav_aria_label:`, replace with`aria_label:`
+ - The `nav_i18n_key` has been removed: pass the interpolated/pluralized value as the `aria_label:` argument
+ - The `item_i18n_key` has been removed: pass the interpolated/pluralized value as the `item_name:` argument
+ - The `link_extra:` has been removed: its cumulative mechanism was confusing and error prone. The `:anchor_string` pagy
+ variable substitutes it, however it's not an helper argument anymore, so you can assign it as the `DEFAULT[:anchor_string]`
+ and/or pass it as any other pagy variable at object construction. (See [customize the link attributes](https://ddnexus.github.io/pagy/docs/how-to/#customize-the-link-attributes))
+- HTML structure, classes and internal methods have been changed: they may break your views if you used custom stylesheets,
+ templates or helper overrides. See the complete changes below if you notice any cosmetic changes or get some exception.
+- The `navs` and `support` extras has been merged into the new [pagy extra](https://ddnexus.github.io/pagy/docs/extras/pagy).
+ Search for `"extra/navs"` and
+ `"extras/support"` and replace with `"extras/pagy"` (remove the duplicate if you used both)
### Changes
-- Added `:count_args` variable passed to the `collection.count(...)` statement (avoids overriding of `pagy-gets-vars` and
- expands count capabilities)
-- [ARIA compliance](https://ddnexus.github.io/pagy/docs/api/aria/)
-- Removed the pagy templates: they were a burden for maintenance with very limited usage,
- still [you can use them](http://ddnexus.github.io/pagy/docs/how-to/#using-your-pagination-templates)
-- Added a simpler and faster nav without gaps (just pass an integer to the `:size`)
-- Internal renaming of private frontend methods
-- Updated code and tests for latest gem and npm module versions
-- Internal improvements of automation scripts
+- Streamlined HTML and CSS helper structure. You may want to look at the actual output by running the [pagy demo](https://ddnexus.github.io/pagy/playground.md#3-demo-app)
+ - The `pagy_nav` and `pagy_nav_js` helpers output a series of `a` tags inside a wrapper `nav` tag (nothing else)
+ - The disabled links are so because they are missing the `href` attributes. (They also have the `role="link"` and `aria-disabled="true"` attributes)
+ - The `current` and `gap` classes are assigned to the specific `a` tags
+ - HTML changes
+ - All the pagy helper root classes have been changed according to the following rule. For example:
+ - `"pagy-nav"` > `"pagy nav"`
+ - `"pagy-bootstrap-nav-js"` > `"pagy-bootstrap nav-js"`
+ - and so on for all the helpers
+ - The `active` class of the `*nav`/`*nav_js` links as been renamed as `current`
+ - The `disabled`, `prev`, `next` and `pagy-combo-input` link classes have been removed (see the [stylesheets](https://ddnexus.github.io/pagy/docs/api/stylesheets/#pagy-scss) for details)
+ - The `rel="prev"` and `rel="next"` attributes have been dropped (they are obsolete)
+ - The `` and ``/`` wrappers in the dictionary files have been removed
+- The `pagy_link_proc` method (only used internally or in your custom overriding) has been renamed to `pagy_anchor`and it works
+ slighty differently:
+ - The `link_extra:` key argument has been removed
+ - The `extra` positional argument of the returned lambda has been removed
+ - The `classes:` and `aria_label:` keyword arguments have been added to the returned lambda
+- The `nav_aria_label_attr` method has been renamed as `nav_aria_label`
+- The internal `prev_aria_label_attr` and `next_aria_label_attr` methods have been removed
+- The `gap` in the nav bars is a disabled anchor element (`a` tag without a `href` attribute`)
+- The `pagy_prev_html` and `pagy_next_html` have been renamed as `pagy_prev_a` and `pagy_next_a`
+- The `pagy_prev_link_tag` and `pagy_next_link_tag` have been renamed as `pagy_prev_link` and `pagy_next_link`
+- The `*combo_nav_js` and `pagy_items_selector_js` helpers use a more efficient code
+- The `src/pagy.ts` and relative built javascript files have been adapted to the above changes
+- The [stylesheets](https://ddnexus.github.io/pagy/docs/api/stylesheets/) are a lot simpler as a consequence of the changes above
+- All the `*combo-nav_js` of the framework extras use simpler structure and improve the look and feel consistently with their
+ respective frameworks
+- All the frontend extra have been normalized and are totally consistent with each other; a few may add the `classes:`
+ argument to a few components, when the framework allows it.
+- Created the [pagy playground](https://ddnexus.github.io/pagy/playground) system of apps working with the `pagy` executable.
+- Internal renaming `FrontendHelpers` > `JSTools`
+- Fix broken link of pagy.rb in docs (closes #668, #669)
+- Docs Improvements
+- Better code issue template
[LEGACY CHANGELOG >>>](CHANGELOG_LEGACY.md)
diff --git a/CHANGELOG_LEGACY.md b/CHANGELOG_LEGACY.md
index 0411b0e56..1d0a3410c 100644
--- a/CHANGELOG_LEGACY.md
+++ b/CHANGELOG_LEGACY.md
@@ -6,6 +6,145 @@ visibility: hidden
# LEGACY CHANGELOG
+## Version 7.0.11
+
+- Fix jsonapi prev and next keys for unavailable links (#665)
+- Docs fixes
+
+## Version 7.0.10
+
+- Added name attribute to combo and items input tags; removed pagy_marked_link and refactored js input action
+
+## Version 7.0.9
+
+- Improve all pagy apps
+- Normalized bootstrap, bulma, foundation, navs extra
+
+## Version 7.0.8
+
+- Update gems and fix a rubocop bug
+- Add all styles to pagy_styles.ru
+- Better pagy stylesheets
+- Fix for uikit extra prev and next link duplicating chevrons
+- Change aria_Label to aria_label for Arabic locale (#657)
+
+## Version 7.0.7
+
+- Fix for retype exluding linked files and showing category images
+- Fix for first *nav_js page not active with trim (introduced with the #656 fix 7e2f118)
+- Normalize pagy apps; implement pagy_styles.ru
+
+## Version 7.0.6
+
+- Internal renaming of frontend constants
+- Fix for disabled links and missing or extra ARIA attributes in frontend extras
+- Boostrap fix for current page link; pagy.js fix for trim of current page (closes #656)
+
+## Version 7.0.5
+
+- Updated gems, npm modules, contributors
+- Added the pagy stylesheets to the gem, updated apps, docs and manifest
+- Added note for the metrics and compacted the chart section (closes #652)
+- Docs: fix formatting, grammar in README.md (#654)
+- Add note about PR base branches to readme (#653)
+
+## Version 7.0.4
+
+- Tailwind styles integrated with the pagy-items-selector-js (#646)
+- Deprecated the "pagination" CSS class, use the "pagy" CSS class that has been added to all the interactive pagy helper outputs
+- Fix indentation of cs locale (#648); add "pagy.aria_label.nav.few" entry, duplicating the "other" pluralization
+- Update cs translations (#648)
+- Expand/Correct changes about `pagy.prev` and `pagy.next` (#649)
+
+## Version 7.0.3
+
+- Remove extra space in `pagy_nav`, `pagy_nav_js` and `.pagy-combo-input`
+- Refactor of tailwind styles and docs (closes #646)
+- Add `pagy_tailwind_app.ru` (#646)
+- Add missing CSS breaking change to the CHANGELOG (#646)
+
+## Version 7.0.2
+
+- Fix for missing to fetch count_args default (close #645)
+- Non-code improvements
+
+## Version 7.0.1
+
+- Updates ckb translations to be complaint with ARIA in v7.x.x (#643)
+
+## Version 7.0.0
+
+### Breaking changes
+
+- Dropped old rubies support: Pagy follows the [ruby end-of-life](https://endoflife.date/ruby) supported rubies now.
+- Renamed `:i18n_key` > `:item_i18n_key`
+- Refactored `support` extra
+ - Renamed `pagy_prev_link` to `pagy_prev_html` to avoid confusion with pagy_prev_link_tag
+ - Removed `pagy_next_link` to `pagy_next_html` to avoid confusion with pagy_next_link_tag
+- Rack 3 breaking changes:
+ - The `headers` extra produces all lowercase headers, regardless how you set
+ them [see rack issue](https://github.com/rack/rack/issues/1592)
+ - Removed `:escaped_html` option from `pagy_url_for` (only breaking if you override the method or use the option directly)
+- Dictionary structure changes: (affects only app with custom helper/templates/dictionary entries)
+ - The `nav` entry has been flattened: `pagy.nav.*` entries are now `pagy.*`:
+ - If you have custom helpers/templates: search the keys that contain `'.nav.'` and replace them with `'.'`
+ - If you have custom dictionary entries (overrides): remove the `'nav:'` line and unindent its block
+ - A few labels used as `aria-label` have been added: you may want to add/use them to your custom helper/templates/dictionaries
+ for ARIA compliance.
+ - `pagy.aria_label.nav` Pluralized entry: used in the `nav` element
+ - `pagy.aria_label.prev`, `pagy.aria_label.next` Single entry: used in the prev/next `a` link elements
+
+### Default changes (possibly breaking test/views)
+
+- Changed `Pagy::DEFAULT[:size]` variable defaults from `[1, 4, 4, 1]` to `7`. You can explicitly set/restore it in the
+ initializer, if your app was relying on it.
+- Added sensible `:size` defaults in Calendar Unit subclasses. You can explicitly set it in the initializer, if your app was
+ relying on it.
+ - `Pagy::Calendar::Day::DEFAULT[:size]` `31`
+ - `Pagy::Calendar::Month::DEFAULT[:size]` `12`
+ - `Pagy::Calendar::Quarter::DEFAULT[:size]` `4`
+ - `Pagy::Calendar::Year::DEFAULT[:size]` `10`
+- Changed a few `format` defaults in Calendar Unit subclasses. You can explicitly set it in the initializer, if your app was
+ relying on it.
+ - `Pagy::Calendar::Day::DEFAULT[:format]` from `'%Y-%m-%d'` to `'%d'`
+ - `Pagy::Calendar::Month::DEFAULT[:format]` from `'%Y-%m'` to `'%b'`
+ - `Pagy::Calendar::Quartr::DEFAULT[:format]` from `'%Y-Q%q'` to `'Q%q'`
+
+### Visual changes (possibly breaking test/views)
+
+- The ARIA label compliance required the refactoring of all the nav helpers that might look slightly different now:
+- The text for `"Prev"` and `"Next"` is now used for the `aria-label` (actually as `"Previous"` and `"Next"`) and has been
+ replaced in the UI as `<` and `>`. You can edit the dictionary entries `pagy.prev` and `pagy.next` if you want to revert it to
+ the previous default (`‹ Prev` and `Next ›`)
+
+### CSS changes (possibly looking different/broken)
+
+- The HTML of the current page in `pagy_nav` and `pagy_nav_js` has been changed from simple text (e.g. `5`) to a
+ disabled link (e.g. `5`). That affects your CSS rules and
+ the old tailwind examples targeting the page links, now overreaching the current page.
+ - You may fix eventual problems either by replacing the affected `a` rules with narrower `a[href]` selectors however if you use
+ Tailwind we recommend to use the [improved tailwind style](https://ddnexus.github.io/pagy/docs/extras/tailwind/), that you can
+ adapt in no time to anything you need.
+- The extra spaces added between pages of `pagy_nav` and `pagy_nav_js` have been removed
+- The `pagy-combo-nav-js .pagy-combo-input` internal element x-margins have been removed
+
+### Internal renaming of private methods (unlikely to break anything)
+
+You should not have used any of the private methods, but if you did so, you will get a `NoMethodError`
+(undefined method...) very easy to fix by simply renaming, because there are no changes in the logic.
+
+### Changes
+
+- Added `:count_args` variable passed to the `collection.count(...)` statement (avoids overriding of `pagy-gets-vars` and
+ expands count capabilities)
+- [ARIA compliance](https://ddnexus.github.io/pagy/docs/api/aria/)
+- Removed the pagy templates: they were a burden for maintenance with very limited usage,
+ still [you can use them](http://ddnexus.github.io/pagy/docs/how-to/#using-your-pagination-templates)
+- Added a simpler and faster nav without gaps (just pass an integer to the `:size`)
+- Internal renaming of private frontend methods
+- Updated code and tests for latest gem and npm module versions
+- Internal improvements of automation scripts
+
## Version 6.5.0
- Add ckb: "pagination" entry (#641)
@@ -512,7 +651,7 @@ FYI: Here is the list of the deprecations that are not supported anymore:
The following optional positional arguments are passed with keywords arguments in all the pagy helpers:
-- The `id` html attribute string with the `pagy_id` keyword
+- The `id` html attribute string with the `id` keyword
- The `url|absolute` flag with the `absolute` keyword
- The `item_name` string with the `item_name` keyword
- The `extra|link_extra` string with the `link_extra` keyword
@@ -758,11 +897,11 @@ FYI: The `@pagy.items` is now always equal to `@pagy.vars[:items]` (i.e. the req
- Passing positional arguments (besides `@pagy`) to all the helpers is deprecated and it will be supported only until pagy 5.0
- All the helpers accept more optional keyword arguments variables, for example:
- - `pagy*_nav(@pagy, pagy_id: 'my-id', link-extra: '...')`
- - `pagy*_nav_js(@pagy, pagy_id: 'my-id', link-extra: '...', steps: {...})`
- - `pagy*_combo_nav_js(@pagy, pagy_id: 'my-id', link-extra: '...')`
- - `pagy_items_selector_js(pagy, pagy_id: 'my-id', item_name: '...', i18n_key: '...', link_extra: '...')`
- - `pagy_info(@pagy, pagy_id: 'my-id', item_name: '...', i18n_key: '...')`
+ - `pagy*_nav(@pagy, id: 'my-id', link-extra: '...')`
+ - `pagy*_nav_js(@pagy, id: 'my-id', link-extra: '...', steps: {...})`
+ - `pagy*_combo_nav_js(@pagy, id: 'my-id', link-extra: '...')`
+ - `pagy_items_selector_js(pagy, id: 'my-id', item_name: '...', i18n_key: '...', link_extra: '...')`
+ - `pagy_info(@pagy, id: 'my-id', item_name: '...', i18n_key: '...')`
- `pagy_prev_link(@pagy, text: '...', link_extra: '...')`
- `pagy_next_link(@pagy, text: '...', link_extra: '...')`
- `pagy_link_proc(@pagy, link_extra: '...')`
@@ -789,7 +928,7 @@ FYI: The `@pagy.items` is now always equal to `@pagy.vars[:items]` (i.e. the req
- [627a0dc](http://github.com/ddnexus/pagy/commit/627a0dc): also pagy_link_proc uses keyword arguments
- [8ff2665](http://github.com/ddnexus/pagy/commit/8ff2665): completed args conversion also for pagy_url_for and pagy_metadata
- [6a8fbb4](http://github.com/ddnexus/pagy/commit/6a8fbb4): added "pagy-info" and "pagy-items-selector-js" classes to helpers output
-- [ad350e1](http://github.com/ddnexus/pagy/commit/ad350e1): pagy_info wrapped into span tag, and added pagy_id keyword arg
+- [ad350e1](http://github.com/ddnexus/pagy/commit/ad350e1): pagy_info wrapped into span tag, and added id keyword arg
- [2faca63](http://github.com/ddnexus/pagy/commit/2faca63): small improvement to pagy_url_for
- [2acbac6](http://github.com/ddnexus/pagy/commit/2acbac6): added "pagy-njs" class to all pagy*_nav_js helpers
- [670f5a5](http://github.com/ddnexus/pagy/commit/670f5a5): updated documentation
@@ -798,7 +937,7 @@ FYI: The `@pagy.items` is now always equal to `@pagy.vars[:items]` (i.e. the req
- [d2891fb](http://github.com/ddnexus/pagy/commit/d2891fb): refactoring and additions of tests
- [1538f24](http://github.com/ddnexus/pagy/commit/1538f24): updated tests with keyword arguments
- [6ce0c1d](http://github.com/ddnexus/pagy/commit/6ce0c1d): helpers: deprecated positional id argument and added keyword arguments
-- [9fd7930](http://github.com/ddnexus/pagy/commit/9fd7930): removed pagy_id method and added id arg to the pagy*_nav helpers
+- [9fd7930](http://github.com/ddnexus/pagy/commit/9fd7930): removed id method and added id arg to the pagy*_nav helpers
- [ec74e4f](http://github.com/ddnexus/pagy/commit/ec74e4f): removed the mandatory id arg passed to pagy_json_tag; updated tests; simplified pagy.js using previousSibling
- [3f13014](http://github.com/ddnexus/pagy/commit/3f13014): added resource post and relative link [skip ci]
- [7927f37](http://github.com/ddnexus/pagy/commit/7927f37): added manifest:check to CI for master and dev and to the default rake task
diff --git a/Gemfile b/Gemfile
index 139fbcdd0..64bd3726d 100644
--- a/Gemfile
+++ b/Gemfile
@@ -33,6 +33,7 @@ group :apps do
gem 'rouge'
gem 'sinatra'
gem 'sinatra-contrib'
+ gem 'slop'
end
group :performance do
diff --git a/Gemfile.lock b/Gemfile.lock
index 96c0f1e59..ce01a7db3 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -17,7 +17,7 @@ GEM
ast (2.4.2)
base64 (0.2.0)
benchmark-ips (2.13.0)
- bigdecimal (3.1.6)
+ bigdecimal (3.1.7)
builder (3.2.4)
concurrent-ruby (1.2.3)
connection_pool (2.4.1)
@@ -25,8 +25,8 @@ GEM
domain_name (0.6.20240107)
drb (2.2.1)
ffi (1.16.3)
- ffi-compiler (1.0.1)
- ffi (>= 1.0.0)
+ ffi-compiler (1.3.2)
+ ffi (>= 1.15.5)
rake
http (5.2.0)
addressable (~> 2.8)
@@ -37,7 +37,7 @@ GEM
http-cookie (1.0.5)
domain_name (~> 0.5)
http-form_data (2.3.0)
- i18n (1.14.1)
+ i18n (1.14.4)
concurrent-ruby (~> 1.0)
json (2.7.1)
kalibera (0.1.2)
@@ -52,7 +52,7 @@ GEM
rake (~> 13.0)
memoist (0.16.2)
memory_profiler (1.0.1)
- minitest (5.22.2)
+ minitest (5.22.3)
minitest-reporters (1.6.1)
ansi
builder
@@ -62,19 +62,18 @@ GEM
mustermann (3.0.0)
ruby2_keywords (~> 0.0.1)
mutex_m (0.2.0)
- nio4r (2.7.0)
+ nio4r (2.7.1)
oj (3.16.3)
bigdecimal (>= 3.0)
parallel (1.24.0)
parser (3.3.0.5)
ast (~> 2.4.1)
racc
- prism (0.24.0)
public_suffix (5.0.4)
puma (6.4.2)
nio4r (~> 2.0)
racc (1.7.3)
- rack (3.0.9.1)
+ rack (3.0.10)
rack-protection (4.0.0)
base64 (>= 0.1.0)
rack (>= 3.0.0, < 4)
@@ -96,8 +95,8 @@ GEM
rerun (0.14.0)
listen (~> 3.0)
rexml (3.2.6)
- rouge (4.2.0)
- rubocop (1.61.0)
+ rouge (4.2.1)
+ rubocop (1.62.1)
json (~> 2.3)
language_server-protocol (>= 3.17.0)
parallel (~> 1.10)
@@ -105,15 +104,14 @@ GEM
rainbow (>= 2.2.2, < 4.0)
regexp_parser (>= 1.8, < 3.0)
rexml (>= 3.2.5, < 4.0)
- rubocop-ast (>= 1.30.0, < 2.0)
+ rubocop-ast (>= 1.31.1, < 2.0)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 2.4.0, < 3.0)
- rubocop-ast (1.31.0)
+ rubocop-ast (1.31.2)
parser (>= 3.3.0.4)
- prism (>= 0.24.0)
- rubocop-minitest (0.34.5)
- rubocop (>= 1.39, < 2.0)
- rubocop-ast (>= 1.30.0, < 2.0)
+ rubocop-minitest (0.35.0)
+ rubocop (>= 1.61, < 2.0)
+ rubocop-ast (>= 1.31.1, < 2.0)
rubocop-packaging (0.5.2)
rubocop (>= 1.33, < 2.0)
rubocop-performance (1.20.2)
@@ -141,6 +139,7 @@ GEM
rack-protection (= 4.0.0)
sinatra (= 4.0.0)
tilt (~> 2.0)
+ slop (4.10.1)
tilt (2.3.0)
tzinfo (2.0.6)
concurrent-ruby (~> 1.0)
@@ -177,6 +176,7 @@ DEPENDENCIES
simplecov
sinatra
sinatra-contrib
+ slop
BUNDLED WITH
2.5.3
diff --git a/README.md b/README.md
index 80fb76a51..a7c2fb201 100644
--- a/README.md
+++ b/README.md
@@ -15,12 +15,12 @@
---
-### ✴ What's new in 7.0+ ✴
+### ✴ What's new in 8.0+ ✴
-- [JSON:API support](https://ddnexus.github.io/pagy/docs/extras/jsonapi/)
-- [ARIA compliance](https://ddnexus.github.io/pagy/docs/api/aria/) and refactoring of dictionary files
-- Added a simpler and faster nav without gaps (just pass an integer to the `:size`)
-- Pagy follows the [ruby end-of-life](https://endoflife.date/ruby) supported rubies now (3.1+)
+- **WARNING**: We may drop pagy's less used CSS extras. If you wish to keep them alive, please, [vote here](https://github.com/ddnexus/pagy/discussions/categories/survey)
+- Better frontend helpers
+- New [Pagy Playground](https://ddnexus.github.io/pagy/playground/) to showcase, clone and develop pagy APPs without any setup on
+ your side (try the [pagy demo](https://ddnexus.github.io/pagy/playground.md#3-demo-app))
- See the [Changelog](https://ddnexus.github.io/pagy/changelog) for possible breaking changes
---
@@ -43,7 +43,7 @@ and `kaminari v1.1.1`.
While it's not up-to-date, you can expect roughly similar results with the latest versions, maybe a bit less dramatic in
performance due to the multiple features added to pagy since v3 (e.g. customizable and translated aria-labels). However, consider
that the difference become A LOT bigger in favor of pagy if you use `*nav_js` helpers, `Pagy::Countless` or JSON and client side
-pagination that the other gems don't offer and are not part of the comparison.
+pagination that are not part of the comparison because missing in the other gems.
See the [Detailed Gems Comparison](http://ddnexus.github.io/pagination-comparison/gems.html) for full details.
@@ -60,9 +60,23 @@ See the [Detailed Gems Comparison](http://ddnexus.github.io/pagination-compariso
gem, [elasticsearch_rails](https://ddnexus.github.io/pagy/docs/extras/elasticsearch_rails), [meilisearch](https://ddnexus.github.io/pagy/docs/extras/meilisearch), [searchkick](https://ddnexus.github.io/pagy/docs/extras/searchkick), `ransack`,
and just about any list, even if you cannot count it
- **It supports all kinds of pagination**
- [calendar](https://ddnexus.github.io/pagy/docs/extras/calendar "paginates by dates, rather than numbers"), [countless](https://ddnexus.github.io/pagy/docs/extras/countless "skips an extra 'count' query"), [geared](https://ddnexus.github.io/pagy/docs/extras/gearbox "varies the items fetched depending on the page number e.g. page 1: x items, but page 2: y items etc."), [incremental, auto-incremental, infinite](https://ddnexus.github.io/pagy/docs/extras/support), [headers](https://ddnexus.github.io/pagy/docs/extras/headers "useful for API pagination"), [JSON](https://ddnexus.github.io/pagy/docs/extras/metadata "provides pagination metadata - especially useful with frameworks like Vue, React etc. and you want to render your own pagination links"), [cursor](https://github.com/Uysim/pagy-cursor "Useful with large data sets, where performance becomes a concern (separate repository)")
-- **It supports all kinds of CSS Frameworks**
- [bootstrap](https://ddnexus.github.io/pagy/docs/extras/bootstrap), [bulma](https://ddnexus.github.io/pagy/docs/extras/bulma), [foundation](https://ddnexus.github.io/pagy/docs/extras/foundation), [materialize](https://ddnexus.github.io/pagy/docs/extras/materialize), [semantic](https://ddnexus.github.io/pagy/docs/extras/semantic), [uikit](https://ddnexus.github.io/pagy/docs/extras/uikit), [tailwind](https://ddnexus.github.io/pagy/docs/extras/tailwind)
+ [calendar](https://ddnexus.github.io/pagy/docs/extras/calendar "paginates by dates, rather than numbers"),
+ [countless](https://ddnexus.github.io/pagy/docs/extras/countless "skips an extra 'count' query"),
+ [geared](https://ddnexus.github.io/pagy/docs/extras/gearbox "varies the items fetched depending on the page number e.g. page 1: x items, but page 2: y items etc."),
+ [incremental, auto-incremental, infinite](https://ddnexus.github.io/pagy/docs/extras/pagy),
+ [headers](https://ddnexus.github.io/pagy/docs/extras/headers "useful for API pagination"),
+ [JSON](https://ddnexus.github.io/pagy/docs/extras/metadata "provides pagination metadata - especially useful with frameworks like Vue, React etc. and you want to render your own pagination links"),
+ [cursor](https://github.com/Uysim/pagy-cursor "Useful with large data sets, where performance becomes a concern (separate
+ repository)")
+- **It supports all kinds of CSS Frameworks and APIs**
+ [bootstrap](https://ddnexus.github.io/pagy/docs/extras/bootstrap),
+ [bulma](https://ddnexus.github.io/pagy/docs/extras/bulma),
+ [foundation](https://ddnexus.github.io/pagy/docs/extras/foundation),
+ [materialize](https://ddnexus.github.io/pagy/docs/extras/materialize),
+ [semantic](https://ddnexus.github.io/pagy/docs/extras/semantic),
+ [uikit](https://ddnexus.github.io/pagy/docs/extras/uikit),
+ [tailwind](https://ddnexus.github.io/pagy/docs/extras/tailwind),
+ [JSON:API](https://ddnexus.github.io/pagy/docs/extras/jsonapi/)
- **It supports faster client-side rendering**
With classic or innovative UI components (see [Javascript Components](https://ddnexus.github.io/pagy/docs/api/javascript/)) or
by
@@ -272,7 +286,9 @@ requiring them (and optionally overriding some default).
Foundation [pagination component](https://foundation.zurb.com/sites/docs/pagination.html)
- [materialize](https://ddnexus.github.io/pagy/docs/extras/materialize): Add nav helpers for the Materialize
CSS [pagination component](https://materializecss.com/pagination.html)
-- [navs](https://ddnexus.github.io/pagy/docs/extras/navs): Adds the unstyled versions of the javascript-powered nav helpers.
+- [pagy](https://ddnexus.github.io/pagy/docs/extras/pagy): Adds the pagy styled versions of the javascript-powered nav helpers and
+ other components to support countless or navless pagination (incremental,
+ auto-incremental, infinite pagination).
- [semantic](https://ddnexus.github.io/pagy/docs/extras/semantic): Add nav helpers for the Semantic UI
CSS [pagination component](https://semantic-ui.com/collections/menu.html)
- [tailwind](https://ddnexus.github.io/pagy/docs/extras/tailwind): Ready to use style snippet
@@ -292,8 +308,6 @@ requiring them (and optionally overriding some default).
- [overflow](https://ddnexus.github.io/pagy/docs/extras/overflow): Allow easy handling of overflowing pages
- [standalone](https://ddnexus.github.io/pagy/docs/extras/standalone): Use pagy without any request object, nor Rack
environment/gem, nor any defined `params` method
-- [support](https://ddnexus.github.io/pagy/docs/extras/support): Add support for countless or navless pagination (incremental,
- auto-incremental, infinite pagination).
- [trim](https://ddnexus.github.io/pagy/docs/extras/trim): Remove the `page=1` param from the first page link
@@ -357,7 +371,7 @@ See also the [How To Page](https://ddnexus.github.io/pagy/docs/how-to)
## Top 💯 Contributors
-[](https://github.com/ddnexus)[](https://github.com/benkoshy)[](https://github.com/dependabot[bot])[](https://github.com/grosser)[](https://github.com/workgena)[](https://github.com/bquorning)[](https://github.com/molfar)[](https://github.com/sunny)[](https://github.com/enzinia)[](https://github.com/espen)[](https://github.com/Earlopain)[](https://github.com/berniechiu)[](https://github.com/renshuki)[](https://github.com/wimdavies)[](https://github.com/tiagotex)[](https://github.com/gamafranco)[](https://github.com/thomasklemm)[](https://github.com/tersor)[](https://github.com/simonneutert)[](https://github.com/rainerborene)[](https://github.com/petergoldstein)[](https://github.com/sabljak)[](https://github.com/cseelus)[](https://github.com/ashmaroli)[](https://github.com/747)[](https://github.com/WilliamHorel)[](https://github.com/okuramasafumi)[](https://github.com/olleolleolle)[](https://github.com/pedrocarmona)[](https://github.com/rafaeelaudibert)[](https://github.com/rafaelmontas)[](https://github.com/yenshirak)[](https://github.com/Tolchi)[](https://github.com/serghost)[](https://github.com/sliminas)[](https://github.com/artplan1)[](https://github.com/woller)[](https://github.com/sk8higher)[](https://github.com/muhammadnawzad)[](https://github.com/ronald)[](https://github.com/achmiral)[](https://github.com/mauro-ni)[](https://github.com/borama)[](https://github.com/creativetags)[](https://github.com/mcary)[](https://github.com/marckohlbrugge)[](https://github.com/tr4b4nt)[](https://github.com/tiejianluo)[](https://github.com/szTheory)[](https://github.com/smoothdvd)[](https://github.com/rhodes-david)[](https://github.com/radinreth)[](https://github.com/okliv)[](https://github.com/nedimdz)[](https://github.com/msdundar)[](https://github.com/m-abdurrehman)[](https://github.com/dwieringa)[](https://github.com/jyuvaraj03)[](https://github.com/YutoYasunaga)[](https://github.com/iamyujinwon)[](https://github.com/yhk1038)[](https://github.com/ya-s-u)[](https://github.com/yshmarov)[](https://github.com/thattimc)[](https://github.com/thomaschauffour)[](https://github.com/snkashis)[](https://github.com/fluser)[](https://github.com/tulak)[](https://github.com/Federico-G)[](https://github.com/egimenos)[](https://github.com/elliotlarson)[](https://github.com/hungdiep97)[](https://github.com/djpremier)[](https://github.com/davidwessman)[](https://github.com/david-a-wheeler)[](https://github.com/MrMoins)[](https://github.com/excid3)[](https://github.com/cellvinchung)[](https://github.com/brunoocasali)[](https://github.com/BrandonKlotz)[](https://github.com/Atul9)[](https://github.com/amenon)[](https://github.com/artinboghosian)[](https://github.com/antonzaharia)[](https://github.com/andrew)[](https://github.com/AliOsm)[](https://github.com/AbelToy)[](https://github.com/maful)[](https://github.com/loed-idzinga)[](https://github.com/epeirce)[](https://github.com/kobusjoubert)[](https://github.com/KevinColemanInc)[](https://github.com/neontuna)[](https://github.com/xuanxu)[](https://github.com/jpgarritano)[](https://github.com/archonic)[](https://github.com/jonasMirendo)[](https://github.com/lostapathy)[](https://github.com/jivko-chobanov)[](https://github.com/whithajess)
+[](https://github.com/ddnexus)[](https://github.com/benkoshy)[](https://github.com/dependabot[bot])[](https://github.com/grosser)[](https://github.com/workgena)[](https://github.com/bquorning)[](https://github.com/molfar)[](https://github.com/sunny)[](https://github.com/enzinia)[](https://github.com/espen)[](https://github.com/Earlopain)[](https://github.com/berniechiu)[](https://github.com/renshuki)[](https://github.com/wimdavies)[](https://github.com/tiagotex)[](https://github.com/gamafranco)[](https://github.com/thomasklemm)[](https://github.com/tersor)[](https://github.com/simonneutert)[](https://github.com/rainerborene)[](https://github.com/petergoldstein)[](https://github.com/sabljak)[](https://github.com/cseelus)[](https://github.com/ashmaroli)[](https://github.com/747)[](https://github.com/WilliamHorel)[](https://github.com/okuramasafumi)[](https://github.com/olleolleolle)[](https://github.com/pedrocarmona)[](https://github.com/rafaeelaudibert)[](https://github.com/rafaelmontas)[](https://github.com/yenshirak)[](https://github.com/Tolchi)[](https://github.com/serghost)[](https://github.com/sliminas)[](https://github.com/artplan1)[](https://github.com/woller)[](https://github.com/sk8higher)[](https://github.com/muhammadnawzad)[](https://github.com/ronald)[](https://github.com/achmiral)[](https://github.com/mauro-ni)[](https://github.com/borama)[](https://github.com/creativetags)[](https://github.com/mcary)[](https://github.com/marckohlbrugge)[](https://github.com/tr4b4nt)[](https://github.com/tiejianluo)[](https://github.com/szTheory)[](https://github.com/smoothdvd)[](https://github.com/rhodes-david)[](https://github.com/radinreth)[](https://github.com/okliv)[](https://github.com/nedimdz)[](https://github.com/msdundar)[](https://github.com/m-abdurrehman)[](https://github.com/dwieringa)[](https://github.com/jyuvaraj03)[](https://github.com/YutoYasunaga)[](https://github.com/iamyujinwon)[](https://github.com/yhk1038)[](https://github.com/ya-s-u)[](https://github.com/yshmarov)[](https://github.com/thattimc)[](https://github.com/thomaschauffour)[](https://github.com/snkashis)[](https://github.com/fluser)[](https://github.com/tulak)[](https://github.com/Federico-G)[](https://github.com/egimenos)[](https://github.com/elliotlarson)[](https://github.com/hungdiep97)[](https://github.com/djpremier)[](https://github.com/davidwessman)[](https://github.com/david-a-wheeler)[](https://github.com/MrMoins)[](https://github.com/excid3)[](https://github.com/cellvinchung)[](https://github.com/brunoocasali)[](https://github.com/BrandonKlotz)[](https://github.com/Atul9)[](https://github.com/amenon)[](https://github.com/artinboghosian)[](https://github.com/antonzaharia)[](https://github.com/andrew)[](https://github.com/AliOsm)[](https://github.com/AbelToy)[](https://github.com/maful)[](https://github.com/loed-idzinga)[](https://github.com/epeirce)[](https://github.com/kobusjoubert)[](https://github.com/KevinColemanInc)[](https://github.com/neontuna)[](https://github.com/xuanxu)[](https://github.com/jpgarritano)[](https://github.com/archonic)[](https://github.com/jonasMirendo)[](https://github.com/lostapathy)[](https://github.com/jivko-chobanov)[](https://github.com/whithajess)
@@ -384,9 +398,9 @@ Many thanks to:
- Pull Requests are welcome!
- Please base your PR against the master branch.
-- For simple contribution you can quickly check your changes with
- the [Pagy::Console](https://ddnexus.github.io/pagy/docs/api/console/) or with the single
- file [pagy_standalone.ru](https://github.com/ddnexus/pagy/blob/master/apps/pagy_standalone.ru).
+- For simple contribution you can quickly check your changes with one of the apps in
+ the [Pagy Playground](https://ddnexus.github.io/pagy/playground) and/or
+ the [Pagy::Console](https://ddnexus.github.io/pagy/docs/api/console/).
- If you Create A Pull Request, please ensure that the "All checks have passed" indicator gets green light on the Pull Request
page (if it's not enabled, a maintainer will enable it for you).
@@ -418,9 +432,7 @@ Many thanks to:
## 💞 Related Projects
-- [pagy-cursor](https://github.com/Uysim/pagy-cursor) An early stage project that implements cursor pagination for AR
-- [grape-pagy](https://github.com/bsm/grape-pagy) Pagy pagination for the [grape](https://github.com/ruby-grape/grape) API
- framework
+[Search rubygems.org](https://rubygems.org/search?query=pagy)
## 📃 License
diff --git a/apps/README.md b/apps/README.md
deleted file mode 100644
index 9b3d07c24..000000000
--- a/apps/README.md
+++ /dev/null
@@ -1,7 +0,0 @@
-# Pagy Apps
-
-Each file in this dir is a minimal self-contained working applications (Sinatra/Rails) that you can just run on your computer without any external configuration.
-
-The only requirement is ruby 3.1+ installed in your environment.
-
-If you need a full featured Rails app with different ready to use configurations, please take a look at the [Pagy Rails App](https://github.com/benkoshy/pagy-rails).
diff --git a/apps/pagy_bare_rails.rb b/apps/pagy_bare_rails.rb
deleted file mode 100644
index 5746df74b..000000000
--- a/apps/pagy_bare_rails.rb
+++ /dev/null
@@ -1,184 +0,0 @@
-# frozen_string_literal: true
-
-# Basic Rails app to: (i) reproduce errors, (ii) experiment pagy.
-
-## Setup
-# 1. Install SqLite3 (an in-memory DB) e.g.
-## sudo apt install sqlite3
-# 2. Optional: If using external services e.g. Meilisearch
-## docker pull getmeili/meilisearch:latest # Fetch latest Meilisearch image from Docker Hub
-## docker run -it --rm -p 7700:7700 getmeili/meilisearch:latest ./meilisearch -master-key=password
-# 4. Run script in separate terminal window:
-# ruby pagy_bare_rails.rb
-
-# NOTICE: if you get any installation error(s) with the following setup
-# temporarily remove `pagy/Gemfile` and `pagy/Gemfile.lock` from the repository
-# because they may interfere with the bundler/inline.
-
-require 'bundler/inline'
-
-gemfile(true) do
- source 'https://rubygems.org'
-
- # Debuggers
- gem 'debug'
- # gem 'debase'
- # gem 'ruby-debug-ide'
-
- # gem 'pagy' # <--install from rubygems
- gem 'pagy', path: '../' # <-- use the local repo
-
- # gem "rails", github: "rails/rails", branch: "main"
- gem 'rails', '~> 6.1'
- gem 'actionpack'
- gem 'railties'
- gem 'sqlite3'
-
- ## Optional: Meilisearch example
- # gem 'meilisearch-rails'
-end
-
-require 'debug'
-
-## Pagy Set-up
-# https://ddnexus.github.io/pagy/docs/extras
-# https://ddnexus.github.io/pagy/docs/api/backend
-require 'pagy/extras/meilisearch'
-require 'pagy/extras/metadata'
-require 'pagy/extras/overflow'
-require 'pagy/extras/trim'
-
-Pagy::DEFAULT[:trim_extra] = false
-Pagy::DEFAULT[:items] = 20
-Pagy::DEFAULT[:metadata] = %i[first_url last_url]
-Pagy::DEFAULT[:overflow] = :empty_page
-
-# Rails set up:
-require 'action_controller/railtie'
-require 'active_record'
-require 'minitest/autorun' # runs tests automatically
-
-class TestApp < Rails::Application # :nodoc:
- config.root = __dir__
- config.hosts << 'www.example.com'
- config.hosts << 'example.org'
- config.session_store :cookie_store, key: 'cookie_store_key'
- secrets.secret_key_base = 'secret_key_base'
-
- config.logger = Logger.new($stdout)
- Rails.logger = config.logger
-
- routes.draw do
- get '/' => 'test#index', as: 'test'
- end
-
- ## Optional: Meilisearch example
- # MeiliSearch::Rails.configuration = {
- # meilisearch_host: 'http://localhost:7700',
- # meilisearch_api_key: 'password' }
-end
-
-ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: ':memory:')
-ActiveRecord::Base.connection.create_table(:authors) do |t|
- t.text :name
-end
-
-ActiveRecord::Base.connection.create_table(:books) do |t|
- t.text :name
- t.references :author, foreign_key: true
-end
-
-ActiveRecord::Base.logger = Logger.new($stdout)
-
-class Author < ActiveRecord::Base # :nodoc:
- has_many :books
-
- ## Optional: Meilisearch example
- # include MeiliSearch::Rails
- # extend Pagy::Meilisearch
- #
- # meilisearch do
- # attribute :name
- # end
-end # :nodoc:
-
-class Book < ActiveRecord::Base # :nodoc:
- belongs_to :author
-
- ## Optional: Meilisearch example
- # include MeiliSearch::Rails
- # extend Pagy::Meilisearch
- # meilisearch do
- # attribute :name
- # end
-end # :nodoc:
-
-1.upto(11) do |i|
- Author.create(name: i)
-end
-
-Author.all.each_with_index do |_author, _i|
- Book.create(:author, :name)
-end
-
-## Optional: Meilisearch example
-# Book.reindex!
-
-class TestController < ActionController::Base # :nodoc:
- include Rails.application.routes.url_helpers
- include Pagy::Backend
-
- def index
- meta, @books = pagy(Book.all, items: 10)
-
- ## Optional: Meilisearch example
- # books = Book.includes(:author).pagy_search('*')
- # @pagy, @books = pagy_meilisearch(books, items: 10)
- # @books.each(&:author)
-
- render json: { data: @books, meta: pagy_metadata(meta) }
- end
-
- ## override pagy methods if you need to here:
- # def pagy_get_items(collection, pagy)
- # collection.limit(1)
- # end
-end
-
-class TestControllerTest < ActionDispatch::IntegrationTest # :nodoc:
- # Request helpers: https://api.rubyonrails.org/v6.1.4/classes/ActionDispatch/Integration/RequestHelpers.html
- # Available assertions: https://guides.rubyonrails.org/testing.html#available-assertions
- # Rails assertions: https://guides.rubyonrails.org/testing.html#rails-specific-assertions
-
- test 'pagy json output - example' do
- get '/'
- assert_equal response.parsed_body, { 'data' => Book.first(10).as_json, 'meta' =>
- { 'first_url' => '/?page=1', 'last_url' => '/?page=1' } }
- end
-
- def test_my_pagy_problem_here
- assert false
- end
-
- private
-
- def app
- Rails.application
- end
-end
-
-## or use rack to test:
-# class BugTest < Minitest::Test # :nodoc:
-# include Rack::Test::Methods
-#
-# # def test_my_pagy_problem_again
-# # get '/'
-# # assert last_response.ok?
-# # end
-#
-# private
-#
-# def app
-# Rails.application
-# end
-# end
diff --git a/apps/pagy_calendar.ru b/apps/pagy_calendar.ru
deleted file mode 100644
index 7fd1b7e33..000000000
--- a/apps/pagy_calendar.ru
+++ /dev/null
@@ -1,141 +0,0 @@
-# frozen_string_literal: true
-
-# Sinatra app usable to play with the pagy calendar extra (https://ddnexus.github.io/pagy/docs/extras/calendar)
-
-# IMPORTANT #
-# This app uses mock collections from the repo, so you should run it from the cloned repo dir:
-
-# INSTALL
-# git clone --depth 1 https://github.com/ddnexus/pagy
-
-# USAGE
-# rackup -o 0.0.0.0 -p 8080 apps/pagy_calendar.ru
-
-# DEV USAGE (with automatic app reload if you edit it)
-# gem install rerun
-# rerun -- rackup -o 0.0.0.0 -p 8080 pagy_calendar.ru
-
-# Point your browser to http://0.0.0.0:8080
-
-# Read the comments below to edit this app
-
-require 'bundler'
-Bundler.require(:default, :apps)
-require 'oj' # require false in Gemfile
-$LOAD_PATH.unshift File.expand_path('../lib', __dir__)
-require 'pagy'
-
-# Edit this section adding/removing the extras and DEFAULT as needed
-# pagy initializer
-require 'pagy/extras/calendar'
-require 'pagy/extras/bootstrap'
-
-Pagy::DEFAULT.freeze
-
-# Simple array-based collection that acts as standard DB collection
-require_relative '../test/mock_helpers/collection'
-
-require 'sinatra/base'
-# Sinatra application
-class PagyCalendar < Sinatra::Base
- configure do
- enable :inline_templates
- end
- include Pagy::Backend
-
- # Edit this section adding your own helpers as needed
- helpers do
- include Pagy::Frontend
- end
-
- # This method must be implemented by the application.
- # It must return the starting and ending local Time objects array defining the calendar :period
- def pagy_calendar_period(collection)
- collection.minmax.map(&:in_time_zone)
- end
-
- # This method must be implemented by the application.
- # It receives the main collection and must return a filtered version of it.
- # The filter logic must be equivalent to {storage_time >= from && storage_time < to}
- def pagy_calendar_filter(collection, from, to)
- collection.select_page_of_records(from.utc, to.utc) # storage in UTC
- end
-
- # Controller action
- get '/' do
- Time.zone = 'EST' # convert the UTC storage time to time with zone 'EST'
- collection = MockCollection::Calendar.new
- # Default calendar
- # The conf Hash defines the pagy objects variables keyed by calendar unit and the final pagy standard object
- # The :skip is an optional and arbitrarily named param that skips the calendar pagination and uses only the pagy
- # object to paginate the unfiltered collection. (It's active by default even without a :skip param).
- # You way want to invert the logic (also in the view) with something like `active: params[:active]`,
- # which would be inactive by default and only active on demand.
- @calendar, @pagy, @records = pagy_calendar(collection, year: {},
- month: {},
- day: {},
- active: !params[:skip])
- Time.now.to_s
- erb :pagy_demo # template available in the __END__ section as @@ pagy_demo
- end
-end
-
-run PagyCalendar
-
-__END__
-
-@@ layout
-
-
-
-
-
- <%= yield %>
-
-
-
-@@ pagy_demo
-
-
-
Pagy Calendar Application
-
Self-contained, standalone Sinatra app implementing nested calendar pagination for year and month units.
diff --git a/docs/api/ARIA.md b/docs/api/ARIA.md
index d48bafdb5..06e34ac05 100644
--- a/docs/api/ARIA.md
+++ b/docs/api/ARIA.md
@@ -10,34 +10,29 @@ Since version `7.0.0` pagy has introduced a consistent set of ARIA compliant att
+++ Nav helpers
-Pagy provides the instance-customizable `aria-label` for the root element of its helpers. It is usually a `nav` element, but for
+Pagy provides the customizable `aria-label` for the root element of its helpers. It is usually a `nav` element, but for
the few helper styles that use a different root element, pagy adds a `role="navigation"` attribute to it.
-The default string for the `aria-label` of the root element is "Page" / "Pages" (translated and pluralized according to the
-total page number). It's arguably a better description of the nav content than just "Pagination" (also difficult to
-translate in certain languages).
+The default string for the `aria-label` of the root element is "Page" / "Pages" (translated and pluralized according to the total
+page number). It's arguably a better description of the nav content than just "Pagination" (also difficult to translate in certain
+languages).
-!!!warning Help us with your languages!
+!!!success Help us with your languages!
Please, check the `pagy.aria_label.nav` in the [locale files](https://github.com/ddnexus/pagy/tree/master/lib/locales)
used by your app to be already correctly translated and pluralized. If it's not, please, post your translation in the issue linked
in the file itself. Thank you!
!!!
!!!danger Validation
-Since the `nav` or `role="navigation"` elements of a HTML document are considered `landmark roles`, they should be uniquely
-aria-identified in the page.
+Since the `nav` or `role="navigation"` elements of a HTML document are considered `landmark roles`, they
+should be uniquely aria-identified in the page.
-If you use more than one pagy helper in the same page, you should not rely on the default (that would
-otherwise generate a non-valid document), instead, you should pass either your own (possibly translated and
-pluralized) `aria-label` string or an i18n-key that locates the translated and pluralized string in your dictionary file. For
-example:
+If you use more than one pagy helper in the same page, you should not rely on the default (that would otherwise generate a
+non-valid document), instead, you should pass your own (possibly translated and pluralized) `aria-label` string. For example:
```erb
-<%# Explicitly set the nav_aria_label string %>
-<%== pagy_nav(@pagy, nav_aria_label: 'Search result pages') %>
-
-<%# Pass an i18n key in a dictionary file (pluralized entry) %>
-<%== pagy_nav(@pagy, nav_i18n_key: 'my.aria_label.nav') %>
+<%# Explicitly set the aria_label string %>
+<%== pagy_nav(@pagy, aria_label: 'Search result pages') %>
```
!!!
diff --git a/docs/api/backend.md b/docs/api/backend.md
index 56159a97f..62fb703cc 100644
--- a/docs/api/backend.md
+++ b/docs/api/backend.md
@@ -28,9 +28,7 @@ and [meilisearch](/docs/extras/meilisearch.md) extras for specific backend custo
## Synopsis
-||| Controller
-
-```ruby
+```ruby Controller
include Pagy::Backend
# optional overriding of some sub-method
@@ -44,8 +42,6 @@ def index
end
```
-|||
-
## Methods
All the methods in this module are prefixed with the `"pagy_"` string, to avoid any possible conflict with your own methods when
@@ -75,7 +71,7 @@ self contained custom `pagy` method. (see [Writing your own Pagy methods](#writi
Sub-method called only by the `pagy` method, it returns the hash of variables used to initialize the Pagy object.
-Override it if you need to add or change some variable. For example you may want to add the `:item_i18n_key` in order to customize
+Override it if you need to add or change some variable. For example you may want to add the `:item_name` in order to customize
the output _(see [How to customize the item name](/docs/how-to.md#customize-the-item-name))_, or even cache the `count`.
!!!warning Don't remove `:count` and `:page`
@@ -122,9 +118,7 @@ In that case you can define a number of `pagy_*` custom methods specific for eac
For example: here is a `pagy` method that doesn't call any sub-method, that may be enough for your needs:
-||| Controller
-
-```ruby
+```ruby Controller
def pagy_custom(collection, vars = {})
pagy = Pagy.new(count: collection.count(*vars[:count_args]), page: params[:page], **vars)
@@ -132,8 +126,6 @@ def pagy_custom(collection, vars = {})
end
```
-|||
-
You can easily write a `pagy` method for _any possible_ environment: please read how
to [Paginate Any Collection](/docs/how-to.md#paginate-any-collection) for details.
diff --git a/docs/api/frontend.md b/docs/api/frontend.md
index 8ff45bfcd..4e5da783e 100644
--- a/docs/api/frontend.md
+++ b/docs/api/frontend.md
@@ -15,8 +15,7 @@ You can extend this module with a few more nav helpers _(see the [extras](/categ
## Synopsis
-||| View Helper
-```ruby
+```ruby View Helper
include Pagy::Frontend
# optional overriding of some sub-method
@@ -24,15 +23,11 @@ def pagy_nav(...)
...
end
```
-|||
-
-||| View
-```erb
+```erb View
<%== pagy_nav(@pagy, **vars) %>
<%== pagy_info(@pagy, **vars) %>
```
-|||
## Methods
@@ -44,22 +39,17 @@ Please, keep in mind that overriding any method is very easy with Pagy. Indeed y
This method takes the Pagy object and returns the HTML string with the pagination links, which are wrapped in a `nav` tag and are ready to use in your view. For example:
-||| View
-```erb
+```erb View
<%== pagy_nav(@pagy, **vars) %>
```
-|||
The method accepts also a few optional keyword arguments variables:
-- `:pagy_id`: the `id` HTML attribute to the `nav` tag (omitted by default)
-- `:link_extra`: the verbatim string added to the `a` tag (e.g. `'data-remote="true"'`)
-- `:nav_aria_label`: an already pluralized string for the `aria-label` attribute of the `nav`, that will be used in place of
+- `:id`: the `id` HTML attribute to the `nav` tag (omitted by default)
+- `:aria_label`: an already pluralized string for the `aria-label` attribute of the `nav`, that will be used in place of
the default `pagy.aria_label.nav`
-- `:nav_i18n_key`: the i18n dictionary key to lookup the default `pagy.aria_label.nav` pluralized value (ignored if
- `nav_aria_label` is
defined)
-- `:size` which use the passed size Array instead of the `:size` variable of the instance
+- `:size` which use the passed value instead of the `:size` variable of the instance
See also [ARIA Attributes](ARIA.md).
@@ -77,18 +67,12 @@ Will produce something like:
The method accepts also a few optional keyword arguments variables:
-- `:pagy_id`: the `id` HTML attribute to the `span` tag wrapping the info
+- `:id`: the `id` HTML attribute to the `span` tag wrapping the info
- `:item_name` an already pluralized string that will be used in place of the default `item/items`
-- `:item_i18n_key` the key to lookup in a dictionary
-
-Notice the `:item_i18n_key` can be passed also to the constructor or be a global variable (i.e. `Pagy::DEFAULT[:item_i18n_key]`
-||| View
-```erb
+```erb View
<%== pagy_info(@pagy, item_name: 'Product'.pluralize(@pagy.count)) %>
-<%== pagy_info(@pagy, item_i18n_key: 'activerecord.model.product' %>
```
-|||
Displaying Products 476-500 of 1000 in total
@@ -100,105 +84,59 @@ This method is called internally in order to produce the url of a page by passin
See also [How to customize the URL](/docs/how-to.md#customize-the-url) and [How to customize the params](/docs/how-to.md#customize-the-params).
-==- `pagy_link_proc(pagy, link_extra='')`
+==- `pagy_anchor(pagy)`
-This method is called internally to get a very specialized and fast proc that produce the HTML links for the pages.
+This method is called internally to get a very specialized and fast proc that produce the HTML anchor elements (i.e. `a` tags) for the pages.
For standard usage you may just need to read [How to customize the link attributes](/docs/how-to.md#customize-the-link-attributes), for advanced usage see below.
-===
-## Advanced Usage
+### Advanced Usage
-You need this section only if you are going to override a `pagy_nav*` helper AND you need to customize the HTML attributes of the link tags.
+You need this section only if you are going to override a `pagy_nav*` helper AND you need to customize the HTML attributes of the
+link tags.
!!! primary
-This method is not intended to be overridden, however you could just replace it in your overridden `pagy_nav*` helpers with some generic helper like the rails `link_to`. If you intend to do so, be sure to have a very good reason, since using `pagy_link_proc` is a lot faster than the rails `link_to` (benchmarked at ~22x faster using ~18x less memory on a 20 links nav).
+This method is not intended to be overridden, however you could just replace it in your overridden `pagy_nav*` helpers with some
+generic helper like the rails `link_to`. If you intend to do so, be sure to have a very good reason, since using `pagy_anchor` is
+a lot faster than the rails `link_to` (benchmarked at ~22x faster using ~18x less memory on a 20 links nav).
!!!
-This method returns a specialized proc that you call to produce the page links. The reason it is a two steps process instead of a single method call is performance. Indeed the method calls the potentially expensive `pagy_url_for` only once and generates the proc, then calling the proc will just interpolates the strings passed to it.
+This method returns a specialized proc that you call to produce the page `a` tags. The reason it is a two steps process instead of
+a single method call is performance. Indeed the method calls the potentially expensive `pagy_url_for` only once and generates the
+proc, then calling the proc will just interpolates the strings passed to it.
Here is how you should use it: in your helper call the method to get the proc (just once):
```ruby
-link = pagy_link_proc( pagy [, extra_attributes_string ] )
+a = pagy_anchor(pagy)
```
-Then call the `"link"` proc to get the links (multiple times):
+Then call the `a` proc to get the links (multiple times):
```ruby
-link.call( page_number [, text [, extra_attributes_string ] ] )
+my_link = a.(page_number, text, classes:, aria_label:)
```
-### Extra attribute strings
+#### The anchor_string variable
-If you need to add some HTML attribute to the page links, you can pass some extra attribute string at many levels, depending on the scope you want your attributes to be added.
+If you need to add some HTML attribute to ALL the page links, you can set the `:anchor_string` variable.
-!!!primary Attributes Must be Valid HTML
-For performance reasons, the extra attributes strings must be formatted as valid HTML attribute/value pairs. _All_ the strings passed at any level will get inserted *verbatim* in the HTML of the link.
+!!!warning Attributes Must be Valid HTML
+For performance reasons, the `:anchor_string` string must be formatted as valid HTML attribute/value pairs because it will get
+inserted *verbatim* in the HTML of the `a` tag.
!!!
-1. For all pagy objects: set the global variable `:link_extra`:
-
- ||| pagy.rb (initializer)
- ```ruby
- Pagy::DEFAULT[:link_extra] = 'data-remote="true"'
- |||
-
- ||| View
- ```ruby
- link = pagy_link_proc(pagy)
- link.call(2)
- #=> 2
- ```
- |||
-
-2. For one Pagy object: pass the `:link_extra` variable to a Pagy constructor (`Pagy.new` or `pagy` controller method):
-
- ||| Controller
- ```ruby
- @pagy, @records = pagy(my_scope, link_extra: 'data-remote="true"')
- ```
- |||
-
- ||| View
- ```ruby
- link = pagy_link_proc(pagy)
- link.call(2)
- #=> 2
- ```
-
-3. For all the `link.call`: pass an extra attributes string to the `pagy_link_proc`:
-
- ||| View
- ```ruby
- link = pagy_link_proc(pagy, 'class="page-link"')
- link.call(2)
- #=> 2
- link.call(3)
- #=> 3
- ```
- |||
-
-4. For a single `link.call`: pass an extra attributes string when you call the proc:
-
- ||| View
- ```ruby
- link.call(page_number, 'aria-label="my-label"')
- #=> 2
- ```
- |||
-
-#### CAVEATS
-
-We use only strings for performance, so the attribute strings get concatenated level after level, but not merged!
-
-!!! warning Do Not Pass Atributes Multiple Times
-Be careful not to pass the same attribute at different levels multiple times. That would generate a duplicated HTML attribute which is illegal html (although handled by all mayor browsers by ignoring all the duplicates but the first).
-!!!
+!!! warning Do Not Pass Attributes Already Present
+Be careful not to pass some attribute that is already added by the helper. That would generate a duplicate HTML attribute which
+is invalid html (although handled by all mayor browsers by ignoring all the duplicates but the first).
-!!!warning Do not add `class` attribute for `*js` helpers
-Specifically do not add a `class` attribute that will end up in the `pagy_bootstrap_nav_js`, `pagy_semantic_nav_js` and `pagy_semantic_combo_nav_js`, which define already their own.
+!!!success Easily check the native component attributes:
+```sh
+pagy demo
+# or: bundle exec pagy demo
+# ...and point your browser at http://0.0.0.0:8000
+```
!!!
==- `pagy_t(key, vars={})`
diff --git a/docs/api/i18n.md b/docs/api/i18n.md
index 1fec097a3..dba7a291b 100644
--- a/docs/api/i18n.md
+++ b/docs/api/i18n.md
@@ -39,9 +39,7 @@ you can do it all by passing a few arguments to the `Pagy::I18n.load` method.
### Synopsis
-||| pagy.rb (initializer)
-
-```ruby
+```ruby pagy.rb (initializer)
# load the "de" built-in locale:
Pagy::I18n.load(locale: 'de')
@@ -63,8 +61,6 @@ Pagy::I18n.load({ locale: 'en' },
pluralize: lambda { |count| ... } })
```
-|||
-
!!!warning Use one load statement
Use only one load statement or you will get a FrozenError exception
!!!
@@ -83,14 +79,10 @@ When you configure multiple locales (i.e. this does not apply to single locale a
request. You usually do that in the application controller, by checking the `:locale` param. For example, in a rails app you
should do something like:
-||| Controller
-
-```ruby
+```ruby Controller
before_action { @pagy_locale = params[:locale] }
```
-|||
-
If the `@pagy_locale` is `nil` or missing pagy will serve the first locale you set in the configuration.
## Adding the model translations
diff --git a/docs/api/javascript/ajax.md b/docs/api/javascript/ajax.md
index ac8ff3458..f72db8ecb 100644
--- a/docs/api/javascript/ajax.md
+++ b/docs/api/javascript/ajax.md
@@ -9,44 +9,27 @@ order: 1
If you AJAX-render any of the javascript helpers mentioned above, you should also execute `Pagy.init(container_element);` in the
javascript template. Here is an example for an AJAX-rendered `pagy_bootstrap_nav_js`:
-||| Controller
-
-```ruby
-
+```ruby Controller
def pagy_remote_nav_js
- # notice the link_extra to enable Ajax
- @pagy, @products = pagy(collection, link_extra: 'data-remote="true"')
+ # notice the anchor_string to enable Ajax
+ @pagy, @products = pagy(collection, anchor_string: 'data-remote="true"')
end
```
-|||
-
-||| `pagy_remote_nav_js.html.erb` - non-AJAX render (first page-load):
-
-```erb
+```erb "pagy_remote_nav_js.html.erb" - non-AJAX render (first page-load)
<%= render partial: 'nav_js' %>
```
-|||
-
-||| `_nav_js.html.erb` partial - AJAX and non-AJAX rendering:
-
-```erb
+```erb "_nav_js.html.erb" partial - AJAX and non-AJAX rendering
<%== pagy_bootstrap_nav_js(@pagy) %>
```
-|||
-
-||| `pagy_remote_nav_js.js.erb`template - AJAX rendering:
-
-```js
+```js "pagy_remote_nav_js.js.erb" template - AJAX rendering
document.getElementById('container').innerHTML = "<%= j(render 'nav_js')%>";
Pagy.init(document.getElementById('container'));
-````
-
-|||
+```
!!!warning Don't forget to re-initialize!
diff --git a/docs/api/javascript/combo-navs.md b/docs/api/javascript/combo-navs.md
index cf431ad94..3da994ab1 100644
--- a/docs/api/javascript/combo-navs.md
+++ b/docs/api/javascript/combo-navs.md
@@ -23,28 +23,24 @@ Here is a screenshot (from the `bootstrap` extra):
![bootstrap_combo_nav_js](/docs/assets/images/bootstrap_combo_nav_js.png)
+[!button corners="pill" variant="success" text=":icon-play: Try it now!"](/playground.md#3-demo-app)
+
## Synopsis
See [Setup Javascript](setup.md).
-||| pagy.rb (initializer)
-
-```ruby
+```ruby pagy.rb (initializer)
# you only need one of the following extras
require 'pagy/extras/bootstrap'
require 'pagy/extras/bulma'
require 'pagy/extras/foundation'
require 'pagy/extras/materialize'
-require 'pagy/extras/navs'
+require 'pagy/extras/pagy'
require 'pagy/extras/semantic'
require 'pagy/extras/uikit'
```
-|||
-
-||| Any View
-
-```erb
+```erb Any View
<%== pagy_combo_nav_js(@pagy, **vars) %>
<%== pagy_bootstrap_combo_nav_js(@pagy, **vars) %>
@@ -54,8 +50,6 @@ require 'pagy/extras/uikit'
<%== pagy_semantic_combo_nav_js(@pagy, **vars) %>
```
-|||
-
## Methods
==- `pagy*_combo_nav_js(pagy, **vars)`
@@ -63,8 +57,4 @@ require 'pagy/extras/uikit'
The method accepts also the same optional keyword arguments variables of
the [pagy_nav(pagy, **vars)](/docs/api/frontend.md#pagy-nav-pagy-vars)
-!!!warning
-The `pagy_semantic_combo_nav_js` assigns a class attribute to its links, so do not add another class attribute with
-the `:link_extra`. That would be illegal HTML and ignored by most browsers.
-!!!
===
diff --git a/docs/api/javascript/navs.md b/docs/api/javascript/navs.md
index 90109e163..f61a3a607 100644
--- a/docs/api/javascript/navs.md
+++ b/docs/api/javascript/navs.md
@@ -25,28 +25,24 @@ Here is a screenshot (from the `bootstrap`extra) showing responsiveness at diffe
![bootstrap_nav_js](/docs/assets/images/bootstrap_nav_js.png)
+[!button corners="pill" variant="success" text=":icon-play: Try it now!"](/playground.md#3-demo-app)
+
## Synopsis
See [Setup Javascript](setup).
-||| pagy.rb (initializer)
-
-```ruby
+```ruby pagy.rb (initializer)
# Use just one:
require 'pagy/extras/bootstrap'
require 'pagy/extras/bulma'
require 'pagy/extras/foundation'
require 'pagy/extras/materialize'
-require 'pagy/extras/navs'
+require 'pagy/extras/pagy'
require 'pagy/extras/semantic'
require 'pagy/extras/uikit'
```
-|||
-
-||| Any View
-
-```erb
+```erb Any View
<%== pagy_nav_js(@pagy) %>
<%== pagy_bootstrap_nav_js(@pagy) %>
@@ -56,8 +52,6 @@ require 'pagy/extras/uikit'
<%== pagy_semantic_nav_js(@pagy) %>
```
-|||
-
## Variables
| Variable | Description | Default |
@@ -78,18 +72,12 @@ pass it to the `pagy*_nav_js` helper as an optional keyword argument.
For example:
-||| pagy.rb (initializer)
-
-```ruby
+```ruby pagy.rb (initializer)
# globally
Pagy::DEFAULT[:steps] = { 0 => 5, 540 => [3, 5, 5, 3], 720 => [5, 7, 7, 5] }
```
-|||
-
-||| Controller
-
-```ruby
+```ruby Controller
# or for a single instance
pagy, records = pagy(collection, steps: { 0 => 5, 540 => [3, 5, 5, 3], 720 => [5, 7, 7, 5] })
@@ -97,8 +85,6 @@ pagy, records = pagy(collection, steps: { 0 => 5, 540 => [3, 5, 5, 3], 720 => [5
pagy, records = pagy(collection, steps: false)
```
-|||
-
```erb
or pass it to the helper
<%== pagy_nav_js(@pagy, steps: {...}) %>
@@ -151,9 +137,4 @@ document.getElementById('my-pagy-nav-js').render();
The method accepts also the same optional keyword arguments variables of
the [pagy_nav(pagy, **vars)](/docs/api/frontend#pagy-nav-pagy-vars)
-!!!warning
-The `pagy_bootstrap_nav_js` and `pagy_semantic_nav_js` assign a class attribute to their links, so do not add another class
-attribute with the `:link_extra`. That would be illegal HTML and ignored by most browsers.
-!!!
-
===
diff --git a/docs/api/javascript/setup.md b/docs/api/javascript/setup.md
index d39bebcc4..c562bec77 100644
--- a/docs/api/javascript/setup.md
+++ b/docs/api/javascript/setup.md
@@ -7,7 +7,7 @@ order: 4
# Javascript Setup
!!!info Notice
-A javascript setup is required only for the `pagy*_js` helpers. Just using `'data-remote="true"'` in any other helper works out of
+A javascript setup is required only for the `pagy*_js` helpers. Just using something like `anchor_string: 'data-remote="true"'` in any other helper works out of
the box.
!!!
@@ -114,63 +114,35 @@ Depending on your environment you have a few ways of configuring your app:
In older versions of Rails, you can configure the app to look into the installed pagy gem javascript files:
+++ Sprockets
-||| pagy.rb (initializer)
-
-```ruby
+```ruby pagy.rb (initializer)
Rails.application.config.assets.paths << Pagy.root.join('javascripts') # uncomment.
```
-|||
-
-||| manifest.js (or `application.js` for old sprocket sprockets):
-
-```js
+```js manifest.js (or "application.js" for old sprocket sprockets):
//= require pagy
```
-|||
-
+++ Importmaps
-||| pagy.rb (initializer)
-
-```ruby
+```ruby pagy.rb (initializer)
Rails.application.config.assets.paths << Pagy.root.join('javascripts') #uncomment
```
-|||
-
-||| app/assets/config/manifest.js
-
-```js
+```js app/assets/config/manifest.js
//= link pagy-module.js
```
-|||
-
-||| config/importmap.rb
-
-```ruby
+```ruby config/importmap.rb
pin 'pagy-module'
```
-|||
-
+++ Propshaft
-||| pagy.rb (initializer)
-
-```ruby
+```ruby pagy.rb (initializer)
Rails.application.config.assets.paths << Pagy.root.join('javascripts')
```
-|||
-
-||| application.html.erb
-
-```erb
+```erb application.html.erb
<%= javascript_include_tag "pagy" %>
```
-
-|||
+++
#### Builders
@@ -182,9 +154,7 @@ javascript path:
You can create a symlink or a copy of the `pagy-module.js` file (available in the pagy gem) into an app compiled dir and use it as
a regular app file. That way any builder will pick it up. For example:
-||| config/initializers/pagy.rb
-
-```ruby
+```ruby config/initializers/pagy.rb
# Create/refresh the `app/javascript/pagy-module.js` symlink/copy every time
# the app restarts (unless in production), ensuring syncing when pagy is updated.
# Replace the FileUtils.ln_sf with FileUtils.cp if your OS doesn't support file linking.
@@ -192,35 +162,23 @@ FileUtils.ln_sf(Pagy.root.join('javascripts', 'pagy-module.js'), Rails.root.join
unless Rails.env.production?
```
-|||
-
+++ esbuild
Prepend the `NODE_PATH` environment variable to the `scripts.build` command:
-||| package.json
-
-```json
+```json package.json
{
"build": "NODE_PATH=\"$(bundle show 'pagy')/lib/javascripts\" "
}
```
-|||
-
+++ Webpack
Prepend the `NODE_PATH` environment variable to the `scripts.build` command:
-||| package.json
-
-```json
+```json package.json
{
"build": "NODE_PATH=\"$(bundle show 'pagy')/lib/javascripts\" "
}
```
-|||
-
-||| webpack.confg.js
-
-```js
+```js webpack.confg.js
module.exports = {
..., // your original config
resolve: { // add resolve.modules
@@ -232,8 +190,6 @@ module.exports = {
}
```
-|||
-
#### Legacy way
Ensure that the `erb` loader is installed:
@@ -243,41 +199,28 @@ bundle exec rails webpacker:install:erb
```
Generate a local pagy javascript file using `erb` with webpacker:
-||| app/javascript/packs/pagy.js.erb
-
-```erb
+```erb app/javascript/packs/pagy.js.erb
<%= Pagy.root.join('javascripts', 'pagy.js').read %>
window.addEventListener(YOUR_EVENT_LISTENER, Pagy.init)
```
-
-|||
_where `YOUR_EVENT_LISTENER` is the load event that works with your app (
e.g. `"turbo:load"`, `"turbolinks:load"`, `"load"`, ...)._
-||| app/javascript/application.js
-
-```js
+```js app/javascript/application.js
import './pagy.js.erb'
```
-|||
-
+++ Rollup
Prepend the `NODE_PATH` environment variable to the `scripts.build` command:
-||| package.json
-
-```json
+```json package.json
{
"build": "NODE_PATH=\"$(bundle show 'pagy')/lib/javascripts\" "
}
```
-|||
-
-||| rollup.confg.js
Configure the `plugins[resolve]`:
-```js
+```js rollup.confg.js
export default {
..., // your original config
plugins: [
@@ -290,8 +233,6 @@ export default {
]
}
```
-
-|||
+++
#### Non-Rails apps
@@ -303,9 +244,7 @@ export default {
After the helper is loaded you have to initialize `Pagy` to make it work:
+++ Stimulus JS
-||| pagy_initializer_controller.js
-
-```js
+```js pagy_initializer_controller.js
import {Controller} from "@hotwired/stimulus"
import Pagy from "pagy-module" // if using sprockets, you can remove above line, but make sure you have the appropriate directive if your manifest.js file.
@@ -316,30 +255,20 @@ export default class extends Controller {
}
```
-|||
-
-||| View
-
-```erb
+```erb View
<%== pagy_nav_js(@pagy) %>
```
-|||
-
+++ jsbundling-rails
Import and use the pagy module:
-||| app/javascript/application.js
-
-```js
+```js app/javascript/application.js
import Pagy from "pagy-module";
window.addEventListener("turbo:load", Pagy.init);
```
-|||
-
+++ Others
```js
diff --git a/docs/api/pagy.md b/docs/api/pagy.md
index 9c77211d7..7df9ef9cb 100644
--- a/docs/api/pagy.md
+++ b/docs/api/pagy.md
@@ -14,9 +14,7 @@ memory ([source](https://github.com/ddnexus/pagy/blob/master/lib/pagy.rb)).
## Synopsis
-||| pagy.rb (initializer)
-
-```ruby
+```ruby pagy.rb (initializer)
# set global defaults and extra variables
# they will get merged with every new Pagy instance
Pagy::DEFAULT[:items] = 25
@@ -43,8 +41,6 @@ pagy.series
#=> [1, 2, "3", 4, 5, 6, 7, :gap, 40]
```
-|||
-
## Global Default
The `Pagy::DEFAULT` is a globally available hash used to set defaults variables. It is a constant for easy access, but it is
@@ -54,17 +50,13 @@ variables passed with the `new` method every times a `Pagy` instance gets create
You will typically use it in a `pagy.rb` initializer file to pass defaults values. For example:
-||| pagy.rb (initializer)
-
-```ruby
+```ruby pagy.rb (initializer)
Pagy::DEFAULT[:items] = 25
Pagy::DEFAULT[:my_option] = 'my option'
...
Pagy::DEFAULT.freeze
```
-|||
-
## Methods
==- `Pagy.root`
@@ -150,19 +142,17 @@ They are all integers:
### Other Variables
-| Variable | Description | Default |
-|:-----------------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:------------------------|
-| `:size` | The size of the page links to show: can be an array of initial pages, before current page, after current page, final pages or the total page size. _(see also [How to control the page links](/docs/how-to.md#control-the-page-links))_ | `7` |
-| `: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))_ | `''` |
-| `:item_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'` |
-| `:nav_i18n_key` | The i18n key to lookup the `aria-label` for the `pagy*_nav` helpers | `'pagy.aria_label.nav'` |
-| `: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. Pass the path only (not the absolute url). _(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` |
-| `count_args` | The arguments passed to the `collection.count`. You may want to set it to `[]` in ORMs different than ActiveRecord | [:all] |
+| Variable | Description | Default |
+|:-----------------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:--------|
+| `:size` | The size of the page links to show: can be an array of initial pages, before current page, after current page, final pages or the total page size. _(see also [How to control the page links](/docs/how-to.md#control-the-page-links))_ | `7` |
+| `: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))_ | `''` |
+| `:anchor_string` | 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))_ | `nil` |
+| `: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. Pass the path only (not the absolute url). _(see [Customize the request path](/docs/how-to.md#customize-the-request-path))_ | `nil` |
+| `jsonapi` | Enable `jsonapi` compliance of the pagy query params | `false` |
+| `count_args` | The arguments passed to the `collection.count`. You may want to set it to `[]` in ORMs different than ActiveRecord | [:all] |
There is no specific validation for non-instance variables.
@@ -186,7 +176,7 @@ or `nil`), except the `vars` hash:
| `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` |
+| `request_path` | The request path used for pagination helpers. If nil, helpers will use `request.path` |
### Lowest limit analysis
@@ -214,6 +204,8 @@ Which means:
With `size: []` the `series` method returns `[]`
- `in`, `from` and `to` of an empty page are all `0`
- `prev` and `next` of a single page (not necessary an empty one) are both `nil` (i.e. there is no other page)
+
+===
## Exceptions
diff --git a/docs/api/stylesheets.md b/docs/api/stylesheets.md
index f16408111..b318ab56a 100644
--- a/docs/api/stylesheets.md
+++ b/docs/api/stylesheets.md
@@ -7,18 +7,40 @@ image: none
+## Overview
+
For all its own interactive helpers shown above, the pagy gem includes a few stylesheets files that you can download, link or
copy.
!!!warning
-You don't need any stylesheet if you use a frontend extra
-like: [bootstrap](/docs/extras/bootstrap), [bulma](/docs/extras/bulma), [foundation](/docs/extras/foundation), [materialize](/docs/extras/materialize), [semantic](/docs/extras/semantic), [uikit](/docs/extras/uikit)
+You don't need any stylesheet if you use a frontend extra like:
+[bootstrap](/docs/extras/bootstrap), [bulma](/docs/extras/bulma), [foundation](/docs/extras/foundation),
+[materialize](/docs/extras/materialize), [semantic](/docs/extras/semantic), [uikit](/docs/extras/uikit)
!!!
-!!!success
-You can adapt the stylesheets below to anything you need by just editing the content inside the curly brackets, usually leaving
-the rest
-untouched.
+### HTML Structure
+
+In order to ensure a minimalistic valid output, still complete with all the ARIA attributes, we use a single line with the minimum
+number of tags and class attributes that can identify all the parts of the nav bars:
+
+- The output of `pagy_nav` and `pagy_nav_js` are a series of `a` tags inside a wrapper `nav` tag
+- The disabled links are so because they are missing the `href` attributes
+- The `pagy nav` and `pagy nav-js` classes are assigned to the `nav` tag
+- The `current`, `gap` classes are assigned to the specific `a` tags
+
+!!! Notice
+
+- The stylesheets target the disabled `a` tags by using the `pagy a:not([href])` selector
+- You can make the `gap` look like the other pages by removing the `:not(.gap)`
+- You can target the previous and next links by using `pagy a:first-child` and `pagy a:last-child` pseudo classes
+
+!!!
+
+!!!success
+You can totally transform the stylesheets below by just editing the content inside the curly brackets, usually leaving
+the rest untouched.
+
+!!!warning The order of the selectors is important!
!!!
+++ pagy.scss
@@ -41,19 +63,16 @@ stylesheet_path = Pagy.root.join('stylesheets', 'pagy.css')
:::code source="/lib/stylesheets/pagy.css" :::
-+++ pagy.tailwind.scss
++++ pagy.tailwind.css
-[!file](/lib/stylesheets/pagy.tailwind.scss)
+[!file](/lib/stylesheets/pagy.tailwind.css)
```ruby
-stylesheet_path = Pagy.root.join('stylesheets', 'pagy.tailwind.scss')
+stylesheet_path = Pagy.root.join('stylesheets', 'pagy.tailwind.css')
```
-:::code source="/lib/stylesheets/pagy.tailwind.scss" :::
+:::code source="/lib/stylesheets/pagy.tailwind.css" :::
+++
-!!!
-You can also quickly check and interact with all the pagy and extra styles (including the `pagy` and `tailwind` stylesheets above)
-by running the single-file self-contaied app [!file](/apps/pagy_styles.ru)
-!!!
+[!button corners="pill" variant="success" text=":icon-play: Try it now!"](/playground.md#3-demo-app)
diff --git a/docs/assets/nav.html b/docs/assets/nav.html
new file mode 100644
index 000000000..0b149287d
--- /dev/null
+++ b/docs/assets/nav.html
@@ -0,0 +1,11 @@
+
diff --git a/docs/assets/nav.html.erb b/docs/assets/nav.html.erb
index ed497b627..34fddd30c 100644
--- a/docs/assets/nav.html.erb
+++ b/docs/assets/nav.html.erb
@@ -1,41 +1,29 @@
-<%#
- The link variable is set to a proc that returns the link tag (complete with rel and aria-current)
- Usage: link.call( page_number [, text [, extra_attributes_string ]])
--%>
-<% link = pagy_link_proc(pagy) -%>
-