jekyll-paginate-v2 1.8.2 → 1.9.0

Sign up to get free protection for your applications and to get access to all the features.
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