jekyll-paginate-v2 1.8.2 → 1.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2a7da34c28f9aa75d455021554bcd12dc1efd8ea
4
- data.tar.gz: 19a37f789f35926c1a150389d9bb45bdc7162f64
3
+ metadata.gz: d2c5d1cedeea26a437e352ed736ea9f794e2b9c3
4
+ data.tar.gz: b566918809647d4dbc92aef957a8c30f70a17acc
5
5
  SHA512:
6
- metadata.gz: cedfe9b72ca218c52648461e37b8c74b1e061113cfb55278cff2d74d3b1ed55c58d32e9929ea9f971823d5cfddc514304999d65266f03ac83461e871baf8cc3e
7
- data.tar.gz: a81ac4c6c64925a6eaa346ca925e44f92abd948e3b70f1f57780088c441bff736de67ae81ff1992a7cfb13df426c32bc6e62e8605769287c077bf003e5dea522
6
+ metadata.gz: 39e3bfcbe0350ab850b2881f5c14507f82f36c910372fd2eb1e1fcd3270115f6f8779c125aa147d4b3a190a6fa91eb70cad5daf68f39704d0518995eb1c24792
7
+ data.tar.gz: 858eb0f571516a94a5926c40b804ec62c8d28ed5032b2ced95780cfa9371498ecd3b3219a8cfffbe02c382a7b41ac4b73ac008f2dcb9a900801f8fc7f83ee69d
@@ -26,6 +26,8 @@ The **Generator** forms the core of the pagination logic. It is responsible for
26
26
  * [How to detect auto-generated pages](#detecting-generated-pagination-pages)
27
27
  * [Formatting page titles](#formatting-page-titles)
28
28
  * [Reading pagination meta information](#reading-pagination-meta-information)
29
+ * [How to generate a JSON API](#generating-a-json-api)
30
+ * [Renaming pagination file names](#renaming-pagination-file-names)
29
31
  * [Common issues](#common-issues)
30
32
  - [Dependency Error after installing](#i-keep-getting-a-dependency-error-when-running-jekyll-serve-after-installing-this-gem)
31
33
  - [Bundler error upgrading gem (Bundler::GemNotFound)](#im-getting-a-bundler-error-after-upgrading-the-gem-bundlergemnotfound)
@@ -89,6 +91,14 @@ pagination:
89
91
  before: 2
90
92
  after: 2
91
93
 
94
+ # Optional, the default file extension for generated pages (e.g html, json, xml).
95
+ # Internally this is set to html by default
96
+ extension: html
97
+
98
+ # Optional, the default name of the index file for generated pages (e.g. 'index.html')
99
+ # Without file extension
100
+ indexpage: 'index'
101
+
92
102
  ############################################################
93
103
  ```
94
104
 
@@ -481,6 +491,107 @@ Below is an example on how to print out a "Page x of n" in the pagination layout
481
491
  <h2>Page {{page.pagination_info.curr_page}} of {{page.pagination_info.total_pages}}</h2>
482
492
  ```
483
493
 
494
+ ## Generating a JSON API
495
+
496
+ Delivering content via an API is useful, for a lot of the same reasons that pagination is useful. We want to delivery content, in such a way, that is:
497
+
498
+ 1. Easy for the user to consume.
499
+ 2. Easy for the browser to load.
500
+
501
+ Paginating content meets both of these requirements, but developers are limited to presenting content statically rather than dynamically. Some example of dynamic content delivery are:
502
+ - Pop up modals
503
+ - Infinite scrolling
504
+ - Multi-tiered pagination (e.g. Netflix UI horizontal scrolling for multiple movie categories)
505
+
506
+ ### So how do I generate a JSON API for Jekyll?
507
+
508
+ First, create a new jekyll page and set its layout to `null` to avoid any extra html to show up.
509
+
510
+ Next, use the `extension` and `indexpage` option to customize the output of the page and its paginated content as JSON files.
511
+
512
+ Here's an example page:
513
+ ```
514
+ ---
515
+ layout: null
516
+ permalink: /api
517
+ pagination:
518
+ permalink: 'feed-:num'
519
+ enabled: true
520
+ extension: json
521
+ indexpage: 'feed-1'
522
+ ---
523
+
524
+ {
525
+ "pages": [{% for post in paginator.posts %}
526
+ {% if forloop.first != true %},{% endif %}
527
+ {
528
+ "title": "{{ post.title }}",
529
+ "link": "{{ post.url }}"
530
+ }{% endfor %}
531
+ ]
532
+ }
533
+ ```
534
+ Next, run `jekyll build`. This will generate a set of paginated JSON files under the folder `/api`. These JSON files can be loaded via Javascript/AJAX to dynamically load content into your site.
535
+
536
+ Below's an example set of routes that the configuration would generate:
537
+ - http://localhost:4000/api/feed-1.json
538
+ - http://localhost:4000/api/feed-2.json
539
+ - http://localhost:4000/api/feed-3.json
540
+
541
+ And here is an example of one of the feed.json files that are created given the markup above
542
+ ```
543
+ {
544
+ "pages": [
545
+ {
546
+ "title": "Narcisse Snake Pits",
547
+ "link": "/2016/11/narcisse-snake-pits.html"
548
+ },{
549
+ "title": "Luft-Fahrzeug-Gesellschaft",
550
+ "link": "/2016/11/luft-fahrzeug-gesellschaft.html"
551
+ },{
552
+ "title": "Rotary engine",
553
+ "link": "/2016/11/rotary-engine.html"
554
+ }
555
+ ],
556
+ "next": "/api/feed-11.json",
557
+ "prev": "/api/feed-9.json",
558
+ "first": "/api/feed-1.json"
559
+ }
560
+ ```
561
+
562
+ For further information see [Example 4](https://github.com/sverrirs/jekyll-paginate-v2/tree/master/examples/04-jsonapi), that project can serve as a starting point for your experiments with this feature.
563
+
564
+ ### How did you generate those 'next', 'prev' and 'first' links?
565
+
566
+ All the normal paginator variables can be used in these JSON feed files. You can use them to achive quite powerful features such as pre-loading and detecting when there are no more feeds to load.
567
+
568
+ ```
569
+ {% if paginator.next_page %}
570
+ ,"next": "{{ paginator.next_page_path }}"
571
+ {% endif %}
572
+ {% if paginator.last_page %}
573
+ ,"prev": "{{ paginator.last_page_path }}"
574
+ {% endif %}
575
+ {% if paginator.first_page %}
576
+ ,"first": "{{ paginator.first_page_path }}"
577
+ {% endif %}
578
+ ```
579
+
580
+ ## Renaming pagination file names
581
+ By default the pagination system creates all paginated pages as `index.html`. The system provides an option to override this name and file extension with the
582
+
583
+ ```yml
584
+ indexpage: index
585
+ extension: html
586
+ ```
587
+
588
+ If you wanted to generate all pagination files as `default.htm` then the settings should be configured as follows
589
+
590
+ ```yml
591
+ indexpage: default
592
+ extension: htm
593
+ ```
594
+
484
595
  ## Common issues
485
596
 
486
597
  ### I keep getting a dependency error when running jekyll serve after installing this gem
@@ -82,7 +82,7 @@ module Jekyll
82
82
  def self.paginate(legacy_config, all_posts, page, page_add_lambda )
83
83
  pages = Utils.calculate_number_of_pages(all_posts, legacy_config['per_page'].to_i)
84
84
  (1..pages).each do |num_page|
85
- pager = Paginator.new( legacy_config['per_page'], page.url, legacy_config['permalink'], all_posts, num_page, pages )
85
+ pager = Paginator.new( legacy_config['per_page'], page.url, legacy_config['permalink'], all_posts, num_page, pages, '', '' )
86
86
  if num_page > 1
87
87
  template_full_path = File.join(page.site.source, page.path)
88
88
  template_dir = File.dirname(page.path)
@@ -16,6 +16,8 @@ module Jekyll
16
16
  'before' => 0, # Limits how many links to show before the current page in the pagination trail (0, means off, default: 0)
17
17
  'after' => 0, # Limits how many links to show after the current page in the pagination trail (0 means off, default: 0)
18
18
  },
19
+ 'indexpage' => 'index', # The default name of the index pages
20
+ 'extension' => 'html', # The default extension for the output pages
19
21
  'debug' => false, # Turns on debug output for the gem
20
22
  'legacy' => false # Internal value, do not use (will be removed after 2018-01-01)
21
23
  }
@@ -26,9 +26,10 @@ module Jekyll
26
26
  # Compatibility Note: (REMOVE AFTER 2018-01-01)
27
27
  # If the legacy paginate logic is configured then read those values and merge with config
28
28
  if !site.config['paginate'].nil?
29
+ Jekyll.logger.info "Pagination:","Legacy paginate configuration settings detected and will be used."
29
30
  # You cannot run both the new code and the old code side by side
30
31
  if !site.config['pagination'].nil?
31
- err_msg = "The new jekyll-paginate-v2 and the old jekyll-paginate logic cannot both be configured in the site config at the same time. Please disable the old 'paginate:' config settings."
32
+ err_msg = "The new jekyll-paginate-v2 and the old jekyll-paginate logic cannot both be configured in the site config at the same time. Please disable the old 'paginate:' config settings by either omitting the values or setting them to 'paginate:off'."
32
33
  Jekyll.logger.error err_msg
33
34
  raise ArgumentError.new(err_msg)
34
35
  end
@@ -262,6 +262,11 @@ module Jekyll
262
262
  # list of all newly created pages
263
263
  newpages = []
264
264
 
265
+ # Consider the default index page name and extension
266
+ indexPageName = config['indexpage'].split('.')[0]
267
+ indexPageExt = Utils.ensure_leading_dot(config['extension'])
268
+ indexPageWithExt = indexPageName + indexPageExt
269
+
265
270
  # Now for each pagination page create it and configure the ranges for the collection
266
271
  # This .pager member is a built in thing in Jekyll and defines the paginator implementation
267
272
  # Simpy override to use mine
@@ -269,7 +274,7 @@ module Jekyll
269
274
 
270
275
  # 1. Create the in-memory page
271
276
  # External Proc call to create the actual page for us (this is passed in when the pagination is run)
272
- newpage = PaginationPage.new( template, cur_page_nr, total_pages )
277
+ newpage = PaginationPage.new( template, cur_page_nr, total_pages, indexPageWithExt )
273
278
 
274
279
  # 2. Create the url for the in-memory page (calc permalink etc), construct the title, set all page.data values needed
275
280
  paginated_page_url = config['permalink']
@@ -282,17 +287,17 @@ module Jekyll
282
287
  paginated_page_url = File.join(first_index_page_url, paginated_page_url)
283
288
 
284
289
  # 3. Create the pager logic for this page, pass in the prev and next page numbers, assign pager to in-memory page
285
- newpage.pager = Paginator.new( config['per_page'], first_index_page_url, paginated_page_url, using_posts, cur_page_nr, total_pages)
290
+ newpage.pager = Paginator.new( config['per_page'], first_index_page_url, paginated_page_url, using_posts, cur_page_nr, total_pages, indexPageName, indexPageExt)
286
291
 
287
292
  # Create the url for the new page, make sure we prepend any permalinks that are defined in the template page before
288
293
  if newpage.pager.page_path.end_with? '/'
289
- newpage.set_url(File.join(newpage.pager.page_path, 'index.html'))
290
- elsif newpage.pager.page_path.end_with? '.html'
294
+ newpage.set_url(File.join(newpage.pager.page_path, indexPageWithExt))
295
+ elsif newpage.pager.page_path.end_with? indexPageExt
291
296
  # Support for direct .html files
292
297
  newpage.set_url(newpage.pager.page_path)
293
298
  else
294
299
  # Support for extensionless permalinks
295
- newpage.set_url(newpage.pager.page_path+'.html')
300
+ newpage.set_url(newpage.pager.page_path+indexPageExt)
296
301
  end
297
302
 
298
303
  if( template.data['permalink'] )
@@ -9,13 +9,15 @@ module Jekyll
9
9
  # This page exists purely in memory and is not read from disk
10
10
  #
11
11
  class PaginationPage < Page
12
- def initialize(page_to_copy, cur_page_nr, total_pages)
12
+ def initialize(page_to_copy, cur_page_nr, total_pages, index_pageandext)
13
13
  @site = page_to_copy.site
14
14
  @base = ''
15
15
  @url = ''
16
+ @name = index_pageandext.nil? ? 'index.html' : index_pageandext
17
+
18
+ self.process(@name) # Creates the basename and ext member values
16
19
 
17
20
  # Only need to copy the data part of the page as it already contains the layout information
18
- #self.data = Marshal.load(Marshal.dump(page_to_copy.data)) # Deep copying, http://stackoverflow.com/a/8206537/779521
19
21
  self.data = Jekyll::Utils.deep_merge_hashes( page_to_copy.data, {} )
20
22
  if !page_to_copy.data['autopage']
21
23
  self.content = page_to_copy.content
@@ -28,14 +30,7 @@ module Jekyll
28
30
  end
29
31
 
30
32
  # Store the current page and total page numbers in the pagination_info construct
31
- self.data['pagination_info'] = {"curr_page" => cur_page_nr, 'total_pages' => total_pages }
32
-
33
- # Set the page extension
34
- extension = self.data['pagination']['extension']
35
- extension = extension.nil? ? '.html': '.' + extension
36
- @name = 'index' + extension
37
-
38
- self.process(@name) # Creates the basename and ext member values
33
+ self.data['pagination_info'] = {"curr_page" => cur_page_nr, 'total_pages' => total_pages }
39
34
 
40
35
  # Perform some validation that is also performed in Jekyll::Page
41
36
  validate_data! page_to_copy.path
@@ -19,7 +19,7 @@ module Jekyll
19
19
 
20
20
  # Initialize a new Paginator.
21
21
  #
22
- def initialize(config_per_page, first_index_page_url, paginated_page_url, posts, cur_page_nr, num_pages)
22
+ def initialize(config_per_page, first_index_page_url, paginated_page_url, posts, cur_page_nr, num_pages, default_indexpage, default_ext)
23
23
  @page = cur_page_nr
24
24
  @per_page = config_per_page.to_i
25
25
  @total_pages = num_pages
@@ -31,6 +31,24 @@ module Jekyll
31
31
  init = (@page - 1) * @per_page
32
32
  offset = (init + @per_page - 1) >= posts.size ? posts.size : (init + @per_page - 1)
33
33
 
34
+ # Adjust the first index page url
35
+ if( first_index_page_url.end_with?('/'))
36
+ first_index_page_url = first_index_page_url + default_indexpage + default_ext
37
+ puts "Appending default index+ext: #{first_index_page_url}"
38
+ elsif !first_index_page_url.include?('.')
39
+ first_index_page_url = first_index_page_url + default_indexpage
40
+ puts "Appending default index only: #{first_index_page_url}"
41
+ end
42
+
43
+ # Adjust the paginated pages as well
44
+ if( paginated_page_url.end_with?('/'))
45
+ paginated_page_url = paginated_page_url + default_indexpage + default_ext
46
+ puts "Appending default paginated index+ext: #{paginated_page_url}"
47
+ elsif !paginated_page_url.include?('.')
48
+ paginated_page_url = paginated_page_url + default_ext
49
+ puts "Appending default paginated ext only: #{paginated_page_url}"
50
+ end
51
+
34
52
  @total_posts = posts.size
35
53
  @posts = posts[init..offset]
36
54
  @page_path = @page == 1 ? first_index_page_url : Utils.format_page_number(paginated_page_url, cur_page_nr, @total_pages)
@@ -32,6 +32,17 @@ module Jekyll
32
32
  def self.format_page_title(toFormat, title, cur_page_nr=nil, total_page_count=nil)
33
33
  return format_page_number(toFormat.sub(':title', title.to_s), cur_page_nr, total_page_count)
34
34
  end #function format_page_title
35
+
36
+ # Static: Return a String version of the input which has a leading dot.
37
+ # If the input already has a dot in position zero, it will be
38
+ # returned unchanged.
39
+ #
40
+ # path - a String path
41
+ #
42
+ # Returns the path with a leading slash
43
+ def self.ensure_leading_dot(path)
44
+ path[0..0] == "." ? path : ".#{path}"
45
+ end
35
46
 
36
47
  # Static: Return a String version of the input which has a leading slash.
37
48
  # If the input already has a forward slash in position zero, it will be
@@ -1,8 +1,8 @@
1
1
  module Jekyll
2
2
  module PaginateV2
3
- VERSION = "1.8.2"
3
+ VERSION = "1.9.0"
4
4
  # When modifying remember to issue a new tag command in git before committing, then push the new tag
5
- # git tag -a v1.8.2 -m "Gem v1.8.2"
5
+ # git tag -a v1.9.0 -m "Gem v1.9.0"
6
6
  # git push origin --tags
7
7
  # Yanking a published Gem
8
8
  # gem yank jekyll-paginate-v2 -v VERSION
@@ -6,7 +6,7 @@ module Jekyll::PaginateV2::Generator
6
6
  it "must include the necessary paginator attributes" do
7
7
 
8
8
  # config_per_page, first_index_page_url, paginated_page_url, posts, cur_page_nr, num_pages
9
- pager = Paginator.new(10, "index.html", "/page:num/", [], 1, 10)
9
+ pager = Paginator.new(10, "index.html", "/page:num/", [], 1, 10, 'index', '.html')
10
10
 
11
11
  # None of these accessors should throw errors, just run through them to test
12
12
  val = pager.page
@@ -22,10 +22,10 @@ module Jekyll::PaginateV2::Generator
22
22
  end
23
23
 
24
24
  it "must throw an error if the current page number is greater than the total pages" do
25
- err = -> { pager = Paginator.new(10, "index.html", "/page:num/", [], 10, 8) }.must_raise RuntimeError
25
+ err = -> { pager = Paginator.new(10, "index.html", "/page:num/", [], 10, 8, 'index', '.html') }.must_raise RuntimeError
26
26
 
27
27
  # No error should be raised below
28
- pager = Paginator.new(10, "index.html", "/page:num/", [], 8, 10)
28
+ pager = Paginator.new(10, "index.html", "/page:num/", [], 8, 10, 'index', '.html')
29
29
  end
30
30
 
31
31
  it "must trim the list of posts correctly based on the cur_page_nr and per_page" do
@@ -35,7 +35,7 @@ module Jekyll::PaginateV2::Generator
35
35
  # Initialize a pager with
36
36
  # 5 posts per page
37
37
  # at page 2 out of 5 pages
38
- pager = Paginator.new(5, "index.html", "/page:num/", posts, 2, 5)
38
+ pager = Paginator.new(5, "index.html", "/page:num/", posts, 2, 5, '', '')
39
39
 
40
40
  pager.page.must_equal 2
41
41
  pager.per_page.must_equal 5
@@ -60,7 +60,7 @@ module Jekyll::PaginateV2::Generator
60
60
  # Initialize a pager with
61
61
  # 5 posts per page
62
62
  # at page 2 out of 5 pages
63
- pager = Paginator.new(5, "index.html", "/page:num/", posts, 1, 5)
63
+ pager = Paginator.new(5, "index.html", "/page:num/", posts, 1, 5, '', '')
64
64
 
65
65
  pager.page.must_equal 1
66
66
  pager.per_page.must_equal 5
@@ -85,7 +85,7 @@ module Jekyll::PaginateV2::Generator
85
85
  # Initialize a pager with
86
86
  # 5 posts per page
87
87
  # at page 2 out of 5 pages
88
- pager = Paginator.new(5, "index.html", "/page:num/", posts, 5, 5)
88
+ pager = Paginator.new(5, "index.html", "/page:num/", posts, 5, 5, '', '')
89
89
 
90
90
  pager.page.must_equal 5
91
91
  pager.per_page.must_equal 5
@@ -103,5 +103,55 @@ module Jekyll::PaginateV2::Generator
103
103
  pager.next_page_path.must_be_nil
104
104
  end
105
105
 
106
+ it "must create the explicit index page and index extension when specified" do
107
+ # Create a dummy list of posts that is easy to track
108
+ posts = ['1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16','17','18','19','20','21','22','23','24','25','26','27','28','29','30','31','32','33','34','35']
109
+
110
+ # Initialize a pager with
111
+ # 5 posts per page
112
+ # at page 2 out of 5 pages
113
+ pager = Paginator.new(5, "index.html", "/page:num/", posts, 2, 5, 'index', '.html')
114
+
115
+ pager.page.must_equal 2
116
+ pager.per_page.must_equal 5
117
+ pager.total_pages.must_equal 5
118
+
119
+ pager.total_posts.must_equal 35
120
+
121
+ pager.posts.size.must_equal 5
122
+ pager.posts[0].must_equal '6'
123
+ pager.posts[4].must_equal '10'
124
+
125
+ pager.previous_page.must_equal 1
126
+ pager.previous_page_path.must_equal 'index.html'
127
+ pager.next_page.must_equal 3
128
+ pager.next_page_path.must_equal '/page3/index.html'
129
+ end
130
+
131
+ it "must create the explicit index page and index extension when specified" do
132
+ # Create a dummy list of posts that is easy to track
133
+ posts = ['1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16','17','18','19','20','21','22','23','24','25','26','27','28','29','30','31','32','33','34','35']
134
+
135
+ # Initialize a pager with
136
+ # 5 posts per page
137
+ # at page 2 out of 5 pages
138
+ pager = Paginator.new(5, "/", "/feed:num", posts, 2, 5, 'feed', '.json')
139
+
140
+ pager.page.must_equal 2
141
+ pager.per_page.must_equal 5
142
+ pager.total_pages.must_equal 5
143
+
144
+ pager.total_posts.must_equal 35
145
+
146
+ pager.posts.size.must_equal 5
147
+ pager.posts[0].must_equal '6'
148
+ pager.posts[4].must_equal '10'
149
+
150
+ pager.previous_page.must_equal 1
151
+ pager.previous_page_path.must_equal '/feed.json'
152
+ pager.next_page.must_equal 3
153
+ pager.next_page_path.must_equal '/feed3.json'
154
+ end
155
+
106
156
  end
107
157
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jekyll-paginate-v2
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.8.2
4
+ version: 1.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sverrir Sigmundarson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-09-27 00:00:00.000000000 Z
11
+ date: 2017-09-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: jekyll