├── test ├── limit │ ├── _posts │ ├── _includes │ ├── _config.yml │ ├── index.html │ └── _expected │ │ └── posts │ │ ├── index.html │ │ └── page2 │ │ └── index.html ├── multilingual │ ├── _posts │ ├── _includes │ ├── _config.yml │ ├── index.html │ ├── index-de.html │ └── _expected │ │ ├── de │ │ └── posts │ │ │ ├── page2 │ │ │ └── index.html │ │ │ └── index.html │ │ └── en │ │ └── posts │ │ ├── page2 │ │ └── index.html │ │ └── index.html ├── no-limit │ ├── _posts │ ├── _includes │ ├── _config.yml │ ├── index.html │ └── _expected │ │ └── posts │ │ ├── index.html │ │ ├── page6 │ │ └── index.html │ │ ├── page2 │ │ └── index.html │ │ ├── page3 │ │ └── index.html │ │ ├── page4 │ │ └── index.html │ │ └── page5 │ │ └── index.html ├── site-config │ ├── _posts │ ├── _config.yml │ ├── index.html │ └── _includes │ │ └── paginator_data.html ├── standard │ ├── _posts │ ├── _includes │ ├── _config.yml │ ├── index.html │ └── _expected │ │ └── posts │ │ ├── page2 │ │ └── index.html │ │ └── index.html ├── filter-category │ ├── _posts │ ├── _config.yml │ ├── index.html │ ├── _expected │ │ └── posts │ │ │ ├── index.html │ │ │ └── page2 │ │ │ └── index.html │ └── _includes │ │ └── paginator_data.html ├── collection │ ├── _penguins │ │ ├── adelie.html │ │ ├── african.html │ │ ├── emperor.html │ │ ├── gentoo.html │ │ ├── chinstrap.html │ │ ├── galapagos.html │ │ ├── macaroni.html │ │ └── rock-hopper.html │ ├── _config.yml │ ├── _expected │ │ └── penguins │ │ │ ├── index.html │ │ │ └── page2 │ │ │ └── index.html │ └── index.html ├── _posts │ ├── 2015-01-02-test-post-number-2.markdown │ ├── 2015-01-04-test-post-number-4.markdown │ ├── 2015-01-07-test-post-number-7.markdown │ ├── 2015-01-09-test-post-number-9.markdown │ ├── 2015-01-11-test-post-number-11.markdown │ ├── 2015-01-12-test-post-number-12.markdown │ ├── 2015-01-01-test-post-number-1.markdown │ ├── 2015-01-03-test-post-number-3.markdown │ ├── 2015-01-05-test-post-number-5.markdown │ ├── 2015-01-06-test-post-number-6.markdown │ ├── 2015-01-08-test-post-number-8.markdown │ └── 2015-01-10-test-post-number-10.markdown ├── _includes │ └── paginator_data.html └── _clash.yml ├── Rakefile ├── lib ├── octopress-paginate │ ├── version.rb │ └── hooks.rb └── octopress-paginate.rb ├── .travis.yml ├── .gitignore ├── Gemfile ├── CHANGELOG.md ├── octopress-paginate.gemspec ├── LICENSE.txt └── README.md /test/limit/_posts: -------------------------------------------------------------------------------- 1 | ../_posts -------------------------------------------------------------------------------- /test/limit/_includes: -------------------------------------------------------------------------------- 1 | ../_includes -------------------------------------------------------------------------------- /test/multilingual/_posts: -------------------------------------------------------------------------------- 1 | ../_posts -------------------------------------------------------------------------------- /test/no-limit/_posts: -------------------------------------------------------------------------------- 1 | ../_posts -------------------------------------------------------------------------------- /test/site-config/_posts: -------------------------------------------------------------------------------- 1 | ../_posts/ -------------------------------------------------------------------------------- /test/standard/_posts: -------------------------------------------------------------------------------- 1 | ../_posts -------------------------------------------------------------------------------- /test/filter-category/_posts: -------------------------------------------------------------------------------- 1 | ../_posts -------------------------------------------------------------------------------- /test/no-limit/_includes: -------------------------------------------------------------------------------- 1 | ../_includes -------------------------------------------------------------------------------- /test/standard/_includes: -------------------------------------------------------------------------------- 1 | ../_includes -------------------------------------------------------------------------------- /test/multilingual/_includes: -------------------------------------------------------------------------------- 1 | ../_includes -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require "bundler/gem_tasks" 2 | 3 | -------------------------------------------------------------------------------- /test/collection/_penguins/adelie.html: -------------------------------------------------------------------------------- 1 | --- 2 | title: Adelie 3 | --- 4 | -------------------------------------------------------------------------------- /test/collection/_penguins/african.html: -------------------------------------------------------------------------------- 1 | --- 2 | title: African 3 | --- 4 | -------------------------------------------------------------------------------- /test/collection/_penguins/emperor.html: -------------------------------------------------------------------------------- 1 | --- 2 | title: Emperor 3 | --- 4 | -------------------------------------------------------------------------------- /test/collection/_penguins/gentoo.html: -------------------------------------------------------------------------------- 1 | --- 2 | title: Gentoo 3 | --- 4 | -------------------------------------------------------------------------------- /test/collection/_penguins/chinstrap.html: -------------------------------------------------------------------------------- 1 | --- 2 | title: Chinstrap 3 | --- 4 | -------------------------------------------------------------------------------- /test/collection/_penguins/galapagos.html: -------------------------------------------------------------------------------- 1 | --- 2 | title: Galapagos 3 | --- 4 | -------------------------------------------------------------------------------- /test/collection/_penguins/macaroni.html: -------------------------------------------------------------------------------- 1 | --- 2 | title: Macaroni 3 | --- 4 | -------------------------------------------------------------------------------- /test/collection/_penguins/rock-hopper.html: -------------------------------------------------------------------------------- 1 | --- 2 | title: Rock Hopper 3 | --- 4 | -------------------------------------------------------------------------------- /lib/octopress-paginate/version.rb: -------------------------------------------------------------------------------- 1 | module Octopress 2 | module Paginate 3 | VERSION = "1.2.0" 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /test/limit/_config.yml: -------------------------------------------------------------------------------- 1 | name: Test site 2 | gems: 3 | - octopress-paginate 4 | timezone: UTC 5 | markdown: redcarpet 6 | -------------------------------------------------------------------------------- /test/_posts/2015-01-02-test-post-number-2.markdown: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Test post number 2" 3 | lang: en 4 | --- 5 | 6 | Post 2 7 | -------------------------------------------------------------------------------- /test/_posts/2015-01-04-test-post-number-4.markdown: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Test post number 4" 3 | lang: en 4 | --- 5 | 6 | Post 4 7 | -------------------------------------------------------------------------------- /test/_posts/2015-01-07-test-post-number-7.markdown: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Test post number 7" 3 | lang: de 4 | --- 5 | 6 | Post 7 7 | -------------------------------------------------------------------------------- /test/_posts/2015-01-09-test-post-number-9.markdown: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Test post number 9" 3 | lang: de 4 | --- 5 | 6 | Post 8 7 | -------------------------------------------------------------------------------- /test/no-limit/_config.yml: -------------------------------------------------------------------------------- 1 | name: Test site 2 | gems: 3 | - octopress-paginate 4 | timezone: UTC 5 | markdown: redcarpet 6 | -------------------------------------------------------------------------------- /test/standard/_config.yml: -------------------------------------------------------------------------------- 1 | name: Test site 2 | gems: 3 | - octopress-paginate 4 | timezone: UTC 5 | markdown: redcarpet 6 | -------------------------------------------------------------------------------- /test/_posts/2015-01-11-test-post-number-11.markdown: -------------------------------------------------------------------------------- 1 | --- 2 | Title: "Test post number 11" 3 | lang: de 4 | --- 5 | 6 | Post 11 7 | -------------------------------------------------------------------------------- /test/_posts/2015-01-12-test-post-number-12.markdown: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Test post number 12" 3 | lang: en 4 | --- 5 | 6 | Post 12 7 | -------------------------------------------------------------------------------- /test/filter-category/_config.yml: -------------------------------------------------------------------------------- 1 | name: Test site 2 | gems: 3 | - octopress-paginate 4 | timezone: UTC 5 | markdown: redcarpet 6 | -------------------------------------------------------------------------------- /test/_posts/2015-01-01-test-post-number-1.markdown: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Test post number 1" 3 | lang: de 4 | category: awesome 5 | --- 6 | 7 | Post 1 8 | -------------------------------------------------------------------------------- /test/_posts/2015-01-03-test-post-number-3.markdown: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Test post number 3" 3 | lang: de 4 | category: awesome 5 | --- 6 | 7 | Post 3 8 | -------------------------------------------------------------------------------- /test/_posts/2015-01-05-test-post-number-5.markdown: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Test post number 5" 3 | lang: de 4 | category: awesome 5 | --- 6 | 7 | Post 5 8 | -------------------------------------------------------------------------------- /test/_posts/2015-01-06-test-post-number-6.markdown: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Test post number 6" 3 | lang: en 4 | category: awesome 5 | --- 6 | 7 | Post 6 8 | -------------------------------------------------------------------------------- /test/_posts/2015-01-08-test-post-number-8.markdown: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Test post number 8" 3 | lang: en 4 | category: awesome 5 | --- 6 | 7 | Post 9 8 | -------------------------------------------------------------------------------- /test/_posts/2015-01-10-test-post-number-10.markdown: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Test post number 10" 3 | lang: en 4 | category: awesome 5 | --- 6 | 7 | Post 10 8 | -------------------------------------------------------------------------------- /test/collection/_config.yml: -------------------------------------------------------------------------------- 1 | name: Test site 2 | gems: 3 | - octopress-paginate 4 | collections: 5 | - penguins 6 | timezone: UTC 7 | markdown: redcarpet 8 | -------------------------------------------------------------------------------- /test/multilingual/_config.yml: -------------------------------------------------------------------------------- 1 | lang: en 2 | name: Test site 3 | gems: 4 | - octopress-paginate 5 | - octopress-multilingual 6 | timezone: UTC 7 | markdown: redcarpet 8 | -------------------------------------------------------------------------------- /test/site-config/_config.yml: -------------------------------------------------------------------------------- 1 | name: Test site 2 | gems: 3 | - octopress-paginate 4 | timezone: UTC 5 | markdown: redcarpet 6 | pagination: 7 | per_page: 2 8 | limit: false 9 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | cache: bundler 2 | 3 | language: ruby 4 | 5 | sudo: false 6 | 7 | rvm: 8 | - 2.3.0 9 | - 2.2.0 10 | - 2.0.0 11 | 12 | script: bundle exec clash test 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /.bundle/ 2 | /.yardoc 3 | /Gemfile.lock 4 | /_yardoc/ 5 | /coverage/ 6 | /doc/ 7 | /pkg/ 8 | /spec/reports/ 9 | /tmp/ 10 | *.bundle 11 | *.so 12 | *.o 13 | *.a 14 | mkmf.log 15 | _site 16 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | 3 | gemspec :name => "octopress-paginate" 4 | 5 | gem "rake", "~> 11.0" 6 | 7 | group :development do 8 | gem "clash" 9 | gem "octopress" 10 | gem "octopress-multilingual" 11 | gem "pry-byebug" 12 | end 13 | -------------------------------------------------------------------------------- /test/site-config/index.html: -------------------------------------------------------------------------------- 1 | --- 2 | title: Posts 3 | permalink: /posts/ 4 | paginate: true 5 | --- 6 | {{ page.title }} 7 | 8 | Posts: 9 | 10 | {% for post in paginator.posts %} 11 | {{ post.title }}{% endfor %} 12 | 13 | {% include paginator_data.html %} 14 | -------------------------------------------------------------------------------- /test/standard/index.html: -------------------------------------------------------------------------------- 1 | --- 2 | title: Posts 3 | permalink: /posts/ 4 | paginate: true 5 | --- 6 | {{ page.title }} 7 | 8 | Posts: 9 | 10 | {% for post in paginator.posts %} 11 | {{ post.title }}{% endfor %} 12 | 13 | {% include paginator_data.html %} 14 | -------------------------------------------------------------------------------- /test/limit/index.html: -------------------------------------------------------------------------------- 1 | --- 2 | title: Posts 3 | permalink: /posts/ 4 | paginate: 5 | limit: 2 6 | per_page: 2 7 | --- 8 | {{ page.title }} 9 | 10 | Posts: 11 | 12 | {% for post in paginator.posts %} 13 | {{ post.title }}{% endfor %} 14 | 15 | {% include paginator_data.html %} 16 | -------------------------------------------------------------------------------- /test/no-limit/index.html: -------------------------------------------------------------------------------- 1 | --- 2 | title: Posts 3 | permalink: /posts/ 4 | paginate: 5 | limit: false 6 | per_page: 2 7 | --- 8 | {{ page.title }} 9 | 10 | Posts: 11 | 12 | {% for post in paginator.posts %} 13 | {{ post.title }}{% endfor %} 14 | 15 | {% include paginator_data.html %} 16 | -------------------------------------------------------------------------------- /test/multilingual/index.html: -------------------------------------------------------------------------------- 1 | --- 2 | title: Posts 3 | permalink: /:lang/posts/ 4 | lang: en 5 | paginate: 6 | per_page: 5 7 | --- 8 | {{ page.title }} 9 | 10 | Posts: 11 | 12 | {% for post in paginator.posts %} 13 | {{ post.title }}{% endfor %} 14 | 15 | {% include paginator_data.html %} 16 | -------------------------------------------------------------------------------- /test/multilingual/index-de.html: -------------------------------------------------------------------------------- 1 | --- 2 | title: Posts 3 | permalink: /:lang/posts/ 4 | lang: de 5 | paginate: 6 | per_page: 5 7 | --- 8 | {{ page.title }} 9 | 10 | Posts: 11 | 12 | {% for post in paginator.posts %} 13 | {{ post.title }}{% endfor %} 14 | 15 | {% include paginator_data.html %} 16 | -------------------------------------------------------------------------------- /test/filter-category/index.html: -------------------------------------------------------------------------------- 1 | --- 2 | title: Posts 3 | permalink: /posts/ 4 | paginate: 5 | category: awesome 6 | per_page: 3 7 | --- 8 | {{ page.title }} 9 | 10 | Posts: 11 | 12 | {% for post in paginator.posts %} 13 | {{ post.title }}{% endfor %} 14 | 15 | {% include paginator_data.html %} 16 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ### 1.2.0 (2016-09-24) 4 | 5 | - Fix deprecation warnings with Jekyll 3. 6 | - Add `reverse` capability. 7 | 8 | ### 1.1.1 (2015-02-27) 9 | 10 | - Fix: Typo caused paginated collections to fail. 11 | 12 | ### 1.1.0 (2015-02-11) 13 | 14 | - New: Configure site-wide defaults in \_config.yml 15 | 16 | ### 1.0.0 (2015-02-10) 17 | 18 | - Initial release 19 | -------------------------------------------------------------------------------- /test/multilingual/_expected/de/posts/page2/index.html: -------------------------------------------------------------------------------- 1 | Posts - page 2 2 | 3 | Posts: 4 | 5 | 6 | Test post number 1 7 | 8 | total_pages: 2 9 | total_post: 6 10 | per_page: 5 11 | limit: 5 12 | 13 | current_page_num: 2 14 | previous_page: 1 15 | previous_page_path: /de/posts/ 16 | next_page: 17 | next_page_path: 18 | 19 | -------------------------------------------------------------------------------- /test/multilingual/_expected/en/posts/page2/index.html: -------------------------------------------------------------------------------- 1 | Posts - page 2 2 | 3 | Posts: 4 | 5 | 6 | Test post number 2 7 | 8 | total_pages: 2 9 | total_post: 6 10 | per_page: 5 11 | limit: 5 12 | 13 | current_page_num: 2 14 | previous_page: 1 15 | previous_page_path: /en/posts/ 16 | next_page: 17 | next_page_path: 18 | 19 | -------------------------------------------------------------------------------- /test/limit/_expected/posts/index.html: -------------------------------------------------------------------------------- 1 | Posts 2 | 3 | Posts: 4 | 5 | 6 | Test post number 12 7 | Test Post Number 11 8 | 9 | total_pages: 2 10 | total_post: 12 11 | per_page: 2 12 | limit: 2 13 | 14 | current_page_num: 1 15 | previous_page: 16 | previous_page_path: 17 | next_page: 2 18 | next_page_path: /posts/page2/ 19 | 20 | -------------------------------------------------------------------------------- /test/limit/_expected/posts/page2/index.html: -------------------------------------------------------------------------------- 1 | Posts - page 2 2 | 3 | Posts: 4 | 5 | 6 | Test post number 10 7 | Test post number 9 8 | 9 | total_pages: 2 10 | total_post: 12 11 | per_page: 2 12 | limit: 2 13 | 14 | current_page_num: 2 15 | previous_page: 1 16 | previous_page_path: /posts/ 17 | next_page: 18 | next_page_path: 19 | 20 | -------------------------------------------------------------------------------- /test/no-limit/_expected/posts/index.html: -------------------------------------------------------------------------------- 1 | Posts 2 | 3 | Posts: 4 | 5 | 6 | Test post number 12 7 | Test Post Number 11 8 | 9 | total_pages: 6 10 | total_post: 12 11 | per_page: 2 12 | limit: false 13 | 14 | current_page_num: 1 15 | previous_page: 16 | previous_page_path: 17 | next_page: 2 18 | next_page_path: /posts/page2/ 19 | 20 | -------------------------------------------------------------------------------- /test/collection/_expected/penguins/index.html: -------------------------------------------------------------------------------- 1 | Penguins 2 | 3 | Penguins: 4 | 5 | 6 | Adelie 7 | African 8 | Chinstrap 9 | Emperor 10 | 11 | total_pages: 2 12 | total_penguins: 8 13 | per_page: 4 14 | limit: 5 15 | 16 | current_page_num: 1 17 | previous_page: 18 | previous_page_path: 19 | next_page: 2 20 | next_page_path: /penguins/page2/ 21 | -------------------------------------------------------------------------------- /test/standard/_expected/posts/page2/index.html: -------------------------------------------------------------------------------- 1 | Posts - page 2 2 | 3 | Posts: 4 | 5 | 6 | Test post number 2 7 | Test post number 1 8 | 9 | total_pages: 2 10 | total_post: 12 11 | per_page: 10 12 | limit: 5 13 | 14 | current_page_num: 2 15 | previous_page: 1 16 | previous_page_path: /posts/ 17 | next_page: 18 | next_page_path: 19 | 20 | -------------------------------------------------------------------------------- /test/no-limit/_expected/posts/page6/index.html: -------------------------------------------------------------------------------- 1 | Posts - page 6 2 | 3 | Posts: 4 | 5 | 6 | Test post number 2 7 | Test post number 1 8 | 9 | total_pages: 6 10 | total_post: 12 11 | per_page: 2 12 | limit: false 13 | 14 | current_page_num: 6 15 | previous_page: 5 16 | previous_page_path: /posts/page5/ 17 | next_page: 18 | next_page_path: 19 | 20 | -------------------------------------------------------------------------------- /test/collection/_expected/penguins/page2/index.html: -------------------------------------------------------------------------------- 1 | Penguins - page 2 2 | 3 | Penguins: 4 | 5 | 6 | Galapagos 7 | Gentoo 8 | Macaroni 9 | Rock Hopper 10 | 11 | total_pages: 2 12 | total_penguins: 8 13 | per_page: 4 14 | limit: 5 15 | 16 | current_page_num: 2 17 | previous_page: 1 18 | previous_page_path: /penguins/ 19 | next_page: 20 | next_page_path: 21 | -------------------------------------------------------------------------------- /test/no-limit/_expected/posts/page2/index.html: -------------------------------------------------------------------------------- 1 | Posts - page 2 2 | 3 | Posts: 4 | 5 | 6 | Test post number 10 7 | Test post number 9 8 | 9 | total_pages: 6 10 | total_post: 12 11 | per_page: 2 12 | limit: false 13 | 14 | current_page_num: 2 15 | previous_page: 1 16 | previous_page_path: /posts/ 17 | next_page: 3 18 | next_page_path: /posts/page3/ 19 | 20 | -------------------------------------------------------------------------------- /test/filter-category/_expected/posts/index.html: -------------------------------------------------------------------------------- 1 | Posts 2 | 3 | Posts: 4 | 5 | 6 | Test post number 10 7 | Test post number 8 8 | Test post number 6 9 | 10 | total_pages: 2 11 | total_post: 6 12 | per_page: 3 13 | limit: 5 14 | 15 | current_page_num: 1 16 | previous_page: 17 | previous_page_path: 18 | next_page: 2 19 | next_page_path: /posts/page2/ 20 | 21 | -------------------------------------------------------------------------------- /test/no-limit/_expected/posts/page3/index.html: -------------------------------------------------------------------------------- 1 | Posts - page 3 2 | 3 | Posts: 4 | 5 | 6 | Test post number 8 7 | Test post number 7 8 | 9 | total_pages: 6 10 | total_post: 12 11 | per_page: 2 12 | limit: false 13 | 14 | current_page_num: 3 15 | previous_page: 2 16 | previous_page_path: /posts/page2/ 17 | next_page: 4 18 | next_page_path: /posts/page4/ 19 | 20 | -------------------------------------------------------------------------------- /test/no-limit/_expected/posts/page4/index.html: -------------------------------------------------------------------------------- 1 | Posts - page 4 2 | 3 | Posts: 4 | 5 | 6 | Test post number 6 7 | Test post number 5 8 | 9 | total_pages: 6 10 | total_post: 12 11 | per_page: 2 12 | limit: false 13 | 14 | current_page_num: 4 15 | previous_page: 3 16 | previous_page_path: /posts/page3/ 17 | next_page: 5 18 | next_page_path: /posts/page5/ 19 | 20 | -------------------------------------------------------------------------------- /test/no-limit/_expected/posts/page5/index.html: -------------------------------------------------------------------------------- 1 | Posts - page 5 2 | 3 | Posts: 4 | 5 | 6 | Test post number 4 7 | Test post number 3 8 | 9 | total_pages: 6 10 | total_post: 12 11 | per_page: 2 12 | limit: false 13 | 14 | current_page_num: 5 15 | previous_page: 4 16 | previous_page_path: /posts/page4/ 17 | next_page: 6 18 | next_page_path: /posts/page6/ 19 | 20 | -------------------------------------------------------------------------------- /test/filter-category/_expected/posts/page2/index.html: -------------------------------------------------------------------------------- 1 | Posts - page 2 2 | 3 | Posts: 4 | 5 | 6 | Test post number 5 7 | Test post number 3 8 | Test post number 1 9 | 10 | total_pages: 2 11 | total_post: 6 12 | per_page: 3 13 | limit: 5 14 | 15 | current_page_num: 2 16 | previous_page: 1 17 | previous_page_path: /posts/ 18 | next_page: 19 | next_page_path: 20 | 21 | -------------------------------------------------------------------------------- /test/multilingual/_expected/de/posts/index.html: -------------------------------------------------------------------------------- 1 | Posts 2 | 3 | Posts: 4 | 5 | 6 | Test Post Number 11 7 | Test post number 9 8 | Test post number 7 9 | Test post number 5 10 | Test post number 3 11 | 12 | total_pages: 2 13 | total_post: 6 14 | per_page: 5 15 | limit: 5 16 | 17 | current_page_num: 1 18 | previous_page: 19 | previous_page_path: 20 | next_page: 2 21 | next_page_path: /de/posts/page2/ 22 | 23 | -------------------------------------------------------------------------------- /test/multilingual/_expected/en/posts/index.html: -------------------------------------------------------------------------------- 1 | Posts 2 | 3 | Posts: 4 | 5 | 6 | Test post number 12 7 | Test post number 10 8 | Test post number 8 9 | Test post number 6 10 | Test post number 4 11 | 12 | total_pages: 2 13 | total_post: 6 14 | per_page: 5 15 | limit: 5 16 | 17 | current_page_num: 1 18 | previous_page: 19 | previous_page_path: 20 | next_page: 2 21 | next_page_path: /en/posts/page2/ 22 | 23 | -------------------------------------------------------------------------------- /test/_includes/paginator_data.html: -------------------------------------------------------------------------------- 1 | total_pages: {{ paginator.total_pages }} 2 | total_post: {{ paginator.total_posts }} 3 | per_page: {{ paginator.per_page }} 4 | limit: {{ paginator.limit }} 5 | 6 | current_page_num: {{ paginator.page }} 7 | previous_page: {{ paginator.previous_page }} 8 | previous_page_path: {{ paginator.previous_page_path }} 9 | next_page: {{ paginator.next_page }} 10 | next_page_path: {{ paginator.next_page_path }} 11 | -------------------------------------------------------------------------------- /test/site-config/_includes/paginator_data.html: -------------------------------------------------------------------------------- 1 | total_pages: {{ paginator.total_pages }} 2 | total_post: {{ paginator.total_posts }} 3 | per_page: {{ paginator.per_page }} 4 | limit: {{ paginator.limit }} 5 | 6 | current_page_num: {{ paginator.page }} 7 | previous_page: {{ paginator.previous_page }} 8 | previous_page_path: {{ paginator.previous_page_path }} 9 | next_page: {{ paginator.next_page }} 10 | next_page_path: {{ paginator.next_page_path }} 11 | -------------------------------------------------------------------------------- /test/filter-category/_includes/paginator_data.html: -------------------------------------------------------------------------------- 1 | total_pages: {{ paginator.total_pages }} 2 | total_post: {{ paginator.total_posts }} 3 | per_page: {{ paginator.per_page }} 4 | limit: {{ paginator.limit }} 5 | 6 | current_page_num: {{ paginator.page }} 7 | previous_page: {{ paginator.previous_page }} 8 | previous_page_path: {{ paginator.previous_page_path }} 9 | next_page: {{ paginator.next_page }} 10 | next_page_path: {{ paginator.next_page_path }} 11 | -------------------------------------------------------------------------------- /lib/octopress-paginate/hooks.rb: -------------------------------------------------------------------------------- 1 | module Octopress 2 | module Paginate 3 | class SiteHook < Hooks::Site 4 | priority :low 5 | 6 | def post_read(site) 7 | site.pages.select {|p| p.data['paginate'] }.each do |page| 8 | Octopress::Paginate.paginate(page) 9 | end 10 | end 11 | end 12 | 13 | class PageHook < Hooks::Page 14 | def merge_payload(payload, page) 15 | if page.data['paginate'] 16 | Octopress::Paginate.page_payload(payload, page) 17 | end 18 | end 19 | end 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /test/standard/_expected/posts/index.html: -------------------------------------------------------------------------------- 1 | Posts 2 | 3 | Posts: 4 | 5 | 6 | Test post number 12 7 | Test Post Number 11 8 | Test post number 10 9 | Test post number 9 10 | Test post number 8 11 | Test post number 7 12 | Test post number 6 13 | Test post number 5 14 | Test post number 4 15 | Test post number 3 16 | 17 | total_pages: 2 18 | total_post: 12 19 | per_page: 10 20 | limit: 5 21 | 22 | current_page_num: 1 23 | previous_page: 24 | previous_page_path: 25 | next_page: 2 26 | next_page_path: /posts/page2/ 27 | 28 | -------------------------------------------------------------------------------- /test/collection/index.html: -------------------------------------------------------------------------------- 1 | --- 2 | title: Penguins 3 | permalink: /penguins/ 4 | paginate: 5 | collection: penguins 6 | per_page: 4 7 | --- 8 | {{ page.title }} 9 | 10 | Penguins: 11 | 12 | {% for penguin in paginator.penguins %} 13 | {{ penguin.title }}{% endfor %} 14 | 15 | total_pages: {{ paginator.total_pages }} 16 | total_penguins: {{ paginator.total_penguins }} 17 | per_page: {{ paginator.per_page }} 18 | limit: {{ paginator.limit }} 19 | 20 | current_page_num: {{ paginator.page }} 21 | previous_page: {{ paginator.previous_page }} 22 | previous_page_path: {{ paginator.previous_page_path }} 23 | next_page: {{ paginator.next_page }} 24 | next_page_path: {{ paginator.next_page_path }} 25 | -------------------------------------------------------------------------------- /octopress-paginate.gemspec: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | lib = File.expand_path('../lib', __FILE__) 3 | $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) 4 | require 'octopress-paginate/version' 5 | 6 | Gem::Specification.new do |spec| 7 | spec.name = "octopress-paginate" 8 | spec.version = Octopress::Paginate::VERSION 9 | spec.authors = ["Brandon Mathis"] 10 | spec.email = ["brandon@imathis.com"] 11 | spec.summary = %q{A nice and simple paginator for Jekyll sites.} 12 | spec.homepage = "https://github.com/octopress/paginate" 13 | spec.license = "MIT" 14 | 15 | spec.files = `git ls-files -z`.split("\x0").grep(/^(bin\/|lib\/|assets\/|demo\/|changelog|readme|license)/i) 16 | spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) } 17 | spec.test_files = spec.files.grep(%r{^(test|spec|features)/}) 18 | spec.require_paths = ["lib"] 19 | 20 | spec.add_runtime_dependency "octopress-hooks" 21 | 22 | end 23 | -------------------------------------------------------------------------------- /test/_clash.yml: -------------------------------------------------------------------------------- 1 | - 2 | title: Standard build 3 | dir: standard 4 | build: true 5 | compare: _expected/posts _site/posts 6 | - 7 | title: Test limit on pagination 8 | dir: limit 9 | build: true 10 | compare: _expected/posts _site/posts 11 | - 12 | title: Test no limit on pagination 13 | dir: no-limit 14 | build: true 15 | compare: _expected/posts _site/posts 16 | - 17 | title: Test site configuration defaults 18 | dir: site-config 19 | build: true 20 | compare: ../no-limit/_expected/posts _site/posts 21 | - 22 | title: Test collection pagination 23 | dir: collection 24 | build: true 25 | compare: _expected/penguins _site/penguins 26 | - 27 | title: Test category filtering 28 | dir: filter-category 29 | build: true 30 | compare: _expected/posts _site/posts 31 | - 32 | title: Language index pagination 33 | dir: multilingual 34 | build: true 35 | compare: 36 | - _expected/de/posts _site/de/posts 37 | - _expected/en/posts _site/en/posts 38 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015 Brandon Mathis 2 | 3 | MIT License 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Octopress Paginate 2 | 3 | Simple and flexible pagination for Jekyll sites featuring: 4 | 5 | - Simple configuration 6 | - Paginate posts and collections 7 | - Page limits (Because who's reading page 35?) 8 | - Filter by categories or tags 9 | - Multi-language support (with [octopress-multilingual](https://github.com/octopress/multilingual)) 10 | 11 | [![Build Status](https://img.shields.io/travis/octopress/paginate/master.svg)](https://travis-ci.org/octopress/paginate) 12 | [![Gem Version](https://img.shields.io/gem/v/octopress-paginate.svg)](https://rubygems.org/gems/octopress-paginate) 13 | [![License](https://img.shields.io/:license-mit-blue.svg)](https://octopress.mit-license.org) 14 | 15 | ## Installation 16 | 17 | If you're using bundler add this gem to your site's Gemfile in the `:jekyll_plugins` group: 18 | 19 | ```ruby 20 | group :jekyll_plugins do 21 | gem 'octopress-paginate' 22 | end 23 | ``` 24 | 25 | Then install the gem with Bundler 26 | 27 | ```shell 28 | $ bundle 29 | ``` 30 | 31 | To install manually without bundler: 32 | 33 | ```shell 34 | $ gem install octopress-paginate 35 | ``` 36 | 37 | Then add the gem to your Jekyll configuration. 38 | 39 | ```ruby 40 | gems: 41 | - octopress-paginate 42 | ``` 43 | 44 | ## Usage 45 | 46 | To paginate posts, create a page to be used as the pagination template. 47 | 48 | ``` 49 | --- 50 | title: Post Index 51 | paginate: true 52 | --- 53 | 54 | {% for post in paginator.posts %} 55 | / do stuff / 56 | {% endfor %} 57 | ``` 58 | 59 | Paginating collection is almost the same as posts except you need to set the collection to paginate. 60 | 61 | ``` 62 | --- 63 | title: Penguin Index 64 | paginate: 65 | collection: penguins 66 | --- 67 | 68 | {% for penguin in paginator.penguins %} 69 | / do stuff / 70 | {% endfor %} 71 | ``` 72 | 73 | ### Multilingual pagination 74 | 75 | If you are running a multilingual site with [octopress-multilingual](https://github.com/octopress/multilingual), simply set a language for your pagination template and posts will be filtered by that language. For example: 76 | 77 | ``` 78 | --- 79 | Title: "Deutsch Posts" 80 | permalink: /de/posts/ # <- Or wherever makes sense on your site 81 | paginate: true 82 | lang: de # <- Add a language 83 | --- 84 | 85 | {% for posts in paginator.posts %} 86 | / do stuff / 87 | {% endfor %} 88 | ``` 89 | 90 | That's all there is to it. 91 | 92 | ### Template variables 93 | 94 | Just like Jekyll's paginator, your pagination pages will have access to the following liquid variables. 95 | 96 | ```yaml 97 | paginator.total_pages # Number of paginated pages 98 | paginator.total_posts # Total number of posts being paginated 99 | paginator.per_page # Posts per page 100 | paginator.limit # Maximum number of paginated pages 101 | paginator.page # Current page number 102 | paginator.previous_page # Previous page number (nil if first page) 103 | paginator.previous_page_path # Url for previous page (nil if first page) 104 | paginator.next_page # Next page number (nil if last page) 105 | paginator.next_page_path # Next page URL (nil if last page) 106 | 107 | # If you're pagination through a collection named `penguins` 108 | pagination.total_penguins # Total number of peguins being paginated 109 | ``` 110 | 111 | ## Configuration 112 | 113 | Pagination is configured on a per-page basis under the `paginate` key in a page's YAML front-matter. Setting `paginate: true` enables pagination with these defaults. 114 | 115 | ```yaml 116 | paginate: 117 | collection: posts 118 | per_page: 10 # maximum number of items per page 119 | limit: 5 # Maximum number of pages to paginate (false for unlimited) 120 | permalink: /page:num/ # pagination path (relative to template page) 121 | title_suffix: " - page :num" # Append to template's page title 122 | category: '' # Paginate items in this category 123 | categories: [] # Paginate items in any of these categories 124 | tag: '' # Paginate items tagged with this tag 125 | tags: [] # Paginate items tagged with any of these tags 126 | reversed: false # Reverse the order of the documents 127 | ``` 128 | 129 | Why set a pagination limit? For sites with lots of posts, this should speed up your build time considerably since Jekyll won't have to generate and write so many additional pages. Additionally, I suspect that it is very uncommon for users to browse paginated post indexes beyond a few pages. If you don't like it, it's easy to disable. 130 | 131 | ### Site-wide pagination defaults 132 | 133 | You can set your own site-wide pagination defaults by configuring the `pagination` key in Jekyll's site config. 134 | 135 | 136 | 137 | ```yaml 138 | pagination: 139 | limit: false 140 | per_page: 20 141 | title_suffix: " (page :num)" 142 | ``` 143 | 144 | Note: this will only change the defaults. A page's YAML front-matter will 145 | override these defaults. 146 | 147 | ### Pagination permalinks 148 | 149 | Assume your pagination template page was at `/index.html`. The second pagination page would be 150 | published to `/page2/index.html` by default. If your template page was at `/posts/index.html` or if was configured 151 | with `permalink: /posts/` the second pagination page would be published to `/posts/page2/index.html`. 152 | 153 | Here are some examples: 154 | 155 | ```yaml 156 | paginate: 157 | permalink /page-:num/ # => /page-2/index.html 158 | permalink /page/:num/ # => /page/2/index.html 159 | permalink /:num/ # => /2/index.html 160 | ``` 161 | 162 | You get the idea. 163 | 164 | ## Contributing 165 | 166 | 1. Fork it () 167 | 2. Create your feature branch (`git checkout -b my-new-feature`) 168 | 3. Commit your changes (`git commit -am 'Add some feature'`) 169 | 4. Push to the branch (`git push origin my-new-feature`) 170 | 5. Create a new Pull Request 171 | -------------------------------------------------------------------------------- /lib/octopress-paginate.rb: -------------------------------------------------------------------------------- 1 | require "octopress-hooks" 2 | require "octopress-paginate/version" 3 | require "octopress-paginate/hooks" 4 | 5 | module Octopress 6 | module Paginate 7 | extend self 8 | 9 | DEFAULT = { 10 | 'collection' => 'posts', 11 | 'per_page' => 10, 12 | 'limit' => 5, 13 | 'permalink' => '/page:num/', 14 | 'title_suffix' => ' - page :num', 15 | 'page_num' => 1, 16 | 'reversed' => false 17 | } 18 | 19 | LOOP = /(paginate.+\s+in)\s+(site\.(.+?))(.+)%}/ 20 | 21 | # Simple Page class override 22 | class PaginationPage < Jekyll::Page 23 | attr_accessor :dir, :name 24 | 25 | def relative_asset_path 26 | site_source = Pathname.new Octopress.site.source 27 | page_source = Pathname.new @base 28 | page_source.relative_path_from(site_source).to_s 29 | end 30 | end 31 | 32 | def paginate(page) 33 | 34 | defaults = DEFAULT.merge(page.site.config['pagination'] || {}) 35 | 36 | if page.data['paginate'].is_a? Hash 37 | page.data['paginate'] = defaults.merge(page.data['paginate']) 38 | else 39 | page.data['paginate'] = defaults 40 | end 41 | 42 | if tag = page.data['paginate']['tag'] 43 | page.data['paginate']['tags'] = Array(tag) 44 | end 45 | 46 | if category = page.data['paginate']['category'] 47 | page.data['paginate']['categories'] = Array(category) 48 | end 49 | 50 | add_pages(page) 51 | end 52 | 53 | def add_pages(page) 54 | config = page.data['paginate'] 55 | pages = (collection(page).size.to_f / config['per_page']).ceil - 1 56 | 57 | if config['limit'] 58 | pages = [pages, config['limit'] - 1].min 59 | end 60 | 61 | page.data['paginate']['pages'] = pages + 1 62 | 63 | new_pages = [] 64 | 65 | pages.times do |i| 66 | index = i+2 67 | 68 | # If page is generated by an Octopress Ink plugin, use the built in 69 | # methods for cloning the page 70 | # 71 | if page.respond_to?(:asset) && page.asset.to_s.match('Octopress::Ink') 72 | new_page = page.asset.new_page(page_data(page, index)) 73 | else 74 | new_page = PaginationPage.new(page.site, page.site.source, File.dirname(page.path), File.basename(page.path)) 75 | new_page.data.merge!(page_data(page, index)) 76 | new_page.process('index.html') 77 | end 78 | 79 | new_pages << new_page 80 | end 81 | 82 | all_pages = [page].concat(new_pages) 83 | 84 | all_pages.each_with_index do |p, index| 85 | 86 | if index > 0 87 | prev_page = all_pages[index - 1] 88 | p.data['paginate']['previous_page'] = index 89 | p.data['paginate']['previous_page_path'] = prev_page.url 90 | end 91 | 92 | if next_page = all_pages[index + 1] 93 | p.data['paginate']['next_page'] = index + 2 94 | p.data['paginate']['next_page_path'] = next_page.url 95 | end 96 | end 97 | 98 | page.site.pages.concat new_pages 99 | end 100 | 101 | def page_data(page, index) 102 | { 103 | 'paginate' => paginate_data(page, index), 104 | 'permalink' => page_permalink(page, index), 105 | 'title' => page_title(page, index), 106 | } 107 | end 108 | 109 | def page_permalink(page, index) 110 | subdir = page.data['paginate']['permalink'].clone.sub(':num', index.to_s) 111 | File.join(page.dir, subdir) 112 | end 113 | 114 | def paginate_data(page, index) 115 | paginate_data = page.data['paginate'].clone 116 | paginate_data['page_num'] = index 117 | paginate_data 118 | end 119 | 120 | def page_title(page, index) 121 | title = if page.data['title'] 122 | page.data['title'] 123 | else 124 | page.data['paginate']['collection'].capitalize 125 | end 126 | 127 | title += page.data['paginate']['title_suffix'].sub(/:num/, index.to_s) 128 | 129 | title 130 | end 131 | 132 | def collection(page) 133 | collection = if page['paginate']['collection'] == 'posts' 134 | if defined?(Octopress::Multilingual) && page.lang 135 | page.site.posts_by_language(page.lang) 136 | else 137 | page.site.posts.docs.reverse 138 | end 139 | else 140 | page.site.collections[page['paginate']['collection']].docs 141 | end 142 | 143 | if page['paginate']['reversed'] == true 144 | collection = collection.reverse 145 | end 146 | 147 | if categories = page.data['paginate']['categories'] 148 | collection = collection.reject{|p| (p.categories & categories).empty?} 149 | end 150 | 151 | if tags = page.data['paginate']['tags'] 152 | collection = collection.reject{|p| (p.tags & tags).empty?} 153 | end 154 | 155 | collection 156 | end 157 | 158 | def page_payload(payload, page) 159 | config = page.data['paginate'] 160 | collection = collection(page) 161 | { 'paginator' => { 162 | "#{config['collection']}" => items(payload, collection), 163 | "page" => config['page_num'], 164 | "per_page" => config['per_page'], 165 | "limit" => config['limit'], 166 | "total_#{config['collection']}" => collection.size, 167 | "total_pages" => config['pages'], 168 | 'previous_page' => config['previous_page'], 169 | 'previous_page_path' => config['previous_page_path'], 170 | 'next_page' => config['next_page'], 171 | 'next_page_path' => config['next_page_path'] 172 | }} 173 | end 174 | 175 | def items(payload, collection) 176 | config = payload['page']['paginate'] 177 | 178 | n = (config['page_num'] - 1) * config['per_page'] 179 | max = n + (config['per_page'] - 1) 180 | 181 | collection[n..max] 182 | end 183 | end 184 | end 185 | 186 | if defined? Octopress::Docs 187 | Octopress::Docs.add({ 188 | name: "Octopress Paginate", 189 | gem: "octopress-paginate", 190 | version: Octopress::Paginate::VERSION, 191 | description: "Simple and flexible pagination for Jekyll posts and collections", 192 | path: File.expand_path(File.join(File.dirname(__FILE__), "../")), 193 | source_url: "https://github.com/octopress/paginate" 194 | }) 195 | end 196 | --------------------------------------------------------------------------------