jekyll-paginate-content 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +21 -0
- data/.rspec +3 -0
- data/.travis.yml +5 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +6 -0
- data/LICENSE.txt +21 -0
- data/README.md +862 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/jekyll-paginate-content.gemspec +28 -0
- data/lib/jekyll/paginate/content.rb +795 -0
- data/lib/jekyll/paginate/content/version.rb +7 -0
- data/res/ajni-trail-p1.png +0 -0
- data/res/ajni-trail-p4.png +0 -0
- data/res/jpv2-trail.png +0 -0
- metadata +93 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: a811e6106880b97dfbc4382399a962be50f12f59
|
4
|
+
data.tar.gz: 82e09910deaefa702a17abafe99767b4977e7896
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: e6e7bc896f56d3feb47dac45c923889a6015dba7aee1e585db6733bfa890a8005b97833e744f31d56a7c634c909a927453f03f755283d9cd36093949483ea0c5
|
7
|
+
data.tar.gz: 99564610e60faef9467cd7844b58ace12a8ddb5d8e4239caac1d67bfb73020252842174d4ed9387e43c53237a71eaab7d137a8c267e23613e84da4421d1a0c27
|
data/.gitignore
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
/.bundle/
|
2
|
+
/.yardoc
|
3
|
+
/_yardoc/
|
4
|
+
/coverage/
|
5
|
+
/doc/
|
6
|
+
/pkg/
|
7
|
+
/spec/reports/
|
8
|
+
/tmp/
|
9
|
+
|
10
|
+
# rspec failure tracking
|
11
|
+
.rspec_status
|
12
|
+
|
13
|
+
# Swap
|
14
|
+
[._]*.s[a-v][a-z]
|
15
|
+
[._]*.sw[a-p]
|
16
|
+
[._]s[a-v][a-z]
|
17
|
+
[._]sw[a-p]
|
18
|
+
Session.vim
|
19
|
+
|
20
|
+
Gemfile.lock
|
21
|
+
*.gem
|
data/.rspec
ADDED
data/.travis.yml
ADDED
data/CODE_OF_CONDUCT.md
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
# Contributor Covenant Code of Conduct
|
2
|
+
|
3
|
+
## Our Pledge
|
4
|
+
|
5
|
+
In the interest of fostering an open and welcoming environment, we as
|
6
|
+
contributors and maintainers pledge to making participation in our project and
|
7
|
+
our community a harassment-free experience for everyone, regardless of age, body
|
8
|
+
size, disability, ethnicity, gender identity and expression, level of experience,
|
9
|
+
nationality, personal appearance, race, religion, or sexual identity and
|
10
|
+
orientation.
|
11
|
+
|
12
|
+
## Our Standards
|
13
|
+
|
14
|
+
Examples of behavior that contributes to creating a positive environment
|
15
|
+
include:
|
16
|
+
|
17
|
+
* Using welcoming and inclusive language
|
18
|
+
* Being respectful of differing viewpoints and experiences
|
19
|
+
* Gracefully accepting constructive criticism
|
20
|
+
* Focusing on what is best for the community
|
21
|
+
* Showing empathy towards other community members
|
22
|
+
|
23
|
+
Examples of unacceptable behavior by participants include:
|
24
|
+
|
25
|
+
* The use of sexualized language or imagery and unwelcome sexual attention or
|
26
|
+
advances
|
27
|
+
* Trolling, insulting/derogatory comments, and personal or political attacks
|
28
|
+
* Public or private harassment
|
29
|
+
* Publishing others' private information, such as a physical or electronic
|
30
|
+
address, without explicit permission
|
31
|
+
* Other conduct which could reasonably be considered inappropriate in a
|
32
|
+
professional setting
|
33
|
+
|
34
|
+
## Our Responsibilities
|
35
|
+
|
36
|
+
Project maintainers are responsible for clarifying the standards of acceptable
|
37
|
+
behavior and are expected to take appropriate and fair corrective action in
|
38
|
+
response to any instances of unacceptable behavior.
|
39
|
+
|
40
|
+
Project maintainers have the right and responsibility to remove, edit, or
|
41
|
+
reject comments, commits, code, wiki edits, issues, and other contributions
|
42
|
+
that are not aligned to this Code of Conduct, or to ban temporarily or
|
43
|
+
permanently any contributor for other behaviors that they deem inappropriate,
|
44
|
+
threatening, offensive, or harmful.
|
45
|
+
|
46
|
+
## Scope
|
47
|
+
|
48
|
+
This Code of Conduct applies both within project spaces and in public spaces
|
49
|
+
when an individual is representing the project or its community. Examples of
|
50
|
+
representing a project or community include using an official project e-mail
|
51
|
+
address, posting via an official social media account, or acting as an appointed
|
52
|
+
representative at an online or offline event. Representation of a project may be
|
53
|
+
further defined and clarified by project maintainers.
|
54
|
+
|
55
|
+
## Enforcement
|
56
|
+
|
57
|
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
58
|
+
reported by contacting the project team at TODO: Write your email address. All
|
59
|
+
complaints will be reviewed and investigated and will result in a response that
|
60
|
+
is deemed necessary and appropriate to the circumstances. The project team is
|
61
|
+
obligated to maintain confidentiality with regard to the reporter of an incident.
|
62
|
+
Further details of specific enforcement policies may be posted separately.
|
63
|
+
|
64
|
+
Project maintainers who do not follow or enforce the Code of Conduct in good
|
65
|
+
faith may face temporary or permanent repercussions as determined by other
|
66
|
+
members of the project's leadership.
|
67
|
+
|
68
|
+
## Attribution
|
69
|
+
|
70
|
+
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
|
71
|
+
available at [http://contributor-covenant.org/version/1/4][version]
|
72
|
+
|
73
|
+
[homepage]: http://contributor-covenant.org
|
74
|
+
[version]: http://contributor-covenant.org/version/1/4/
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2017 TODO: Write your name
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,862 @@
|
|
1
|
+
# Jekyll::Paginate::Content
|
2
|
+
|
3
|
+
[![Gem Version](https://badge.fury.io/rb/jekyll-paginate-content.svg)](https://badge.fury.io/rb/jekyll-paginate-content)
|
4
|
+
|
5
|
+
**You may read this documentation [split across several pages](https://ibrado.org/jpc/readme/).**
|
6
|
+
|
7
|
+
*Jekyll::Paginate::Content* (JPC) is a plugin for [Jekyll](https://jekyllrb.com/) that automatically splits pages, posts, and other content into one or more pages. This can be at points where e.g. `<!--page-->` is inserted, or at the <h1> to <h6> headers. It mimics [jekyll-paginate-v2](https://github.com/sverrirs/jekyll-paginate-v2) (JPv2) naming conventions and features, so if you use that, you will be in familiar territory.
|
8
|
+
|
9
|
+
**Features:** Automatic content splitting into several pages, single-page view, configurable permalinks, page trail/pager, SEO support, self-adjusting internal links, multipage-aware Table Of Contents.
|
10
|
+
|
11
|
+
- [Jekyll::Paginate::Content](#jekyllpaginatecontent)
|
12
|
+
* [TL;DR](#tldr)
|
13
|
+
+ [Manual](#manual)
|
14
|
+
+ [Automatic, with config overrides and mixed syntax](#automatic-with-config-overrides-and-mixed-syntax)
|
15
|
+
* [Why use this?](#why-use-this)
|
16
|
+
* [Installation](#installation)
|
17
|
+
* [Configuration](#configuration)
|
18
|
+
* [Usage](#usage)
|
19
|
+
* [Setting up splitting](#setting-up-splitting)
|
20
|
+
+ [Manual mode](#manual-mode)
|
21
|
+
+ [HTML header mode](#html-header-mode)
|
22
|
+
+ [Page headers and footers](#page-headers-and-footers)
|
23
|
+
* [Paginator Properties/Fields](#paginator-propertiesfields)
|
24
|
+
+ [site.baseurl](#sitebaseurl)
|
25
|
+
* [Page/post properties](#pagepost-properties)
|
26
|
+
+ [Setting custom properties](#setting-custom-properties)
|
27
|
+
+ [Overriding and restoring properties](#overriding-and-restoring-properties)
|
28
|
+
- [Special values](#special-values)
|
29
|
+
+ [Default properties](#default-properties)
|
30
|
+
+ [Example](#example)
|
31
|
+
* [Pagination trails](#pagination-trails)
|
32
|
+
+ [Usage](#usage-1)
|
33
|
+
+ [Page flipper](#page-flipper)
|
34
|
+
* [Table Of Contents (TOC)](#table-of-contents-toc)
|
35
|
+
+ [Excluding sections](#excluding-sections)
|
36
|
+
* [Search Engine Optimization (SEO)](#search-engine-optimization-seo)
|
37
|
+
+ [Unified approach](#unified-approach)
|
38
|
+
* [Demos](#demos)
|
39
|
+
* [Limitations](#limitations)
|
40
|
+
* [Contributing](#contributing)
|
41
|
+
* [License](#license)
|
42
|
+
* [Code of Conduct](#code-of-conduct)
|
43
|
+
* [Also by the Author](#also-by-the-author)
|
44
|
+
|
45
|
+
## TL;DR
|
46
|
+
|
47
|
+
### Manual
|
48
|
+
|
49
|
+
```markdown
|
50
|
+
---
|
51
|
+
title: "JPC demo: 3-page manual"
|
52
|
+
layout: page
|
53
|
+
paginate: true
|
54
|
+
---
|
55
|
+
|
56
|
+
{% if paginator.paginated %}
|
57
|
+
<a href="{{ paginator.single_page }}">View as a single page</a>
|
58
|
+
{% elsif paginator %}
|
59
|
+
<a href="{{ paginator.first_path }}">View as {{ paginator.total_pages }} pages</a>
|
60
|
+
{% endif %}
|
61
|
+
|
62
|
+
This shows up at the top of all pages.
|
63
|
+
|
64
|
+
<!--page_header-->
|
65
|
+
|
66
|
+
This is page 1 of the JPC example.
|
67
|
+
|
68
|
+
<a name="lorem"></a>Lorem ipsum dolor...
|
69
|
+
|
70
|
+
<!--page-->
|
71
|
+
This is page 2 with a [link] to the first page which works in single or paged view.
|
72
|
+
|
73
|
+
{% if paginator.paginated %}
|
74
|
+
<p><a href="{{ paginator.next_path }}">Go on to page {{ paginator.next_page }}</a></p>
|
75
|
+
{% endif %}
|
76
|
+
|
77
|
+
<!--page-->
|
78
|
+
This is the last page.
|
79
|
+
|
80
|
+
<!--page_footer-->
|
81
|
+
This goes into the bottom of all pages.
|
82
|
+
|
83
|
+
[link]: #lorem
|
84
|
+
```
|
85
|
+
[Live demo](https://ibrado.org/demos/jpc-3page-manual.md)
|
86
|
+
|
87
|
+
### Automatic, with config overrides and mixed syntax
|
88
|
+
|
89
|
+
```markdown
|
90
|
+
---
|
91
|
+
title: "JPC demo: 3-page auto, mixed syntax"
|
92
|
+
layout: page
|
93
|
+
paginate: true
|
94
|
+
paginate_content:
|
95
|
+
separator: h2
|
96
|
+
title: ":title :num/:max: :section"
|
97
|
+
permalink: /page:numof:max.html
|
98
|
+
---
|
99
|
+
|
100
|
+
<h2>Introduction</h2>
|
101
|
+
Hello!
|
102
|
+
|
103
|
+
## What did something?
|
104
|
+
The quick brown fox...
|
105
|
+
|
106
|
+
What did it do?
|
107
|
+
---------------
|
108
|
+
...jumped over the lazy dog.
|
109
|
+
|
110
|
+
<!--page_footer-->
|
111
|
+
<div>
|
112
|
+
{% if paginator.prev_section %}
|
113
|
+
« <a href="{{ paginator.prev_path }}">{{ paginator.prev_section }}</a>
|
114
|
+
{% endif %}
|
115
|
+
{% if paginator.prev_section and paginator.next_section %} | {% endif %}
|
116
|
+
{% if paginator.next_section %}
|
117
|
+
<a href="{{ paginator.next_path }}">{{ paginator.next_section }}</a> »
|
118
|
+
{% endif %}
|
119
|
+
</div>
|
120
|
+
```
|
121
|
+
|
122
|
+
[Live demo](https://ibrado.org/demos/jpc-3page-auto.md)
|
123
|
+
|
124
|
+
See other [demos](#demos).
|
125
|
+
|
126
|
+
## Why use this?
|
127
|
+
|
128
|
+
1. You want to split long posts and pages/articles/reviews, etc. into multiple pages, e.g. chapters;
|
129
|
+
1. You want to offer faster loading times to your readers;
|
130
|
+
1. You wamt to make slide/presentation-type content;
|
131
|
+
1. You want more ad revenue from your Jekyll site;
|
132
|
+
1. You wanna be the cool kid. :stuck_out_tongue:
|
133
|
+
|
134
|
+
## Installation
|
135
|
+
|
136
|
+
Add the gem to your application's Gemfile:
|
137
|
+
|
138
|
+
```ruby
|
139
|
+
group :jekyll_plugins do
|
140
|
+
# other plugins here
|
141
|
+
gem 'jekyll-paginate-content'
|
142
|
+
end
|
143
|
+
```
|
144
|
+
|
145
|
+
And then execute:
|
146
|
+
|
147
|
+
$ bundle
|
148
|
+
|
149
|
+
Or install it yourself:
|
150
|
+
|
151
|
+
$ gem install jekyll-paginate-content
|
152
|
+
|
153
|
+
## Configuration
|
154
|
+
|
155
|
+
No configuration is required to run *Jekyll::Paginate::Content*. If you want to tweak its behavior, you may set the following options in `_config.yml`:
|
156
|
+
|
157
|
+
```yaml
|
158
|
+
|
159
|
+
paginate_content:
|
160
|
+
#enabled: false # Default: true
|
161
|
+
debug: true # Show additional messages during run; default: false
|
162
|
+
#collection: pages, "articles" # Which collections to paginate; default: pages and posts
|
163
|
+
collections: # Ditto, just a different way of writing it
|
164
|
+
- pages # Quotes are optional if collection names are obviously strings
|
165
|
+
- posts
|
166
|
+
- articles
|
167
|
+
|
168
|
+
auto: true # Set to true to search for the page separator even if you
|
169
|
+
# don't set paginate: true in the front-matter
|
170
|
+
# Default: false
|
171
|
+
|
172
|
+
separator: "<!--split-->" # The page separator; default: "<!--page-->"
|
173
|
+
# Can be "h1" to "h6" for automatic splitting
|
174
|
+
# Note: Setext (underline titles) only supports h1 and h2
|
175
|
+
|
176
|
+
header: "<!--head-->" # The header separator; default: "<!--page_header-->"
|
177
|
+
footer: "<!--foot-->" # The footer separator; default: "<!--page_footer-->"
|
178
|
+
|
179
|
+
permalink: '/borg:numof:max.html' # Relative path to the new pages; default: "/:num/"
|
180
|
+
# :num will be replaced by the current page number
|
181
|
+
# :max will be replaced by the total number of page parts
|
182
|
+
# e.g. /borg7of9.html
|
183
|
+
|
184
|
+
single_page: '/full.html' # Relative path to the single-page view; default: "/view-all/"
|
185
|
+
# Set to "" for no single page view
|
186
|
+
|
187
|
+
minimum: 1000 # Minimum number of characters (including markup) in a page
|
188
|
+
# for automatic header splitting.
|
189
|
+
# If a section is too short, the next section will be merged
|
190
|
+
# Default: none
|
191
|
+
|
192
|
+
|
193
|
+
title: ':title - :num/:max' # Title format of the split pages, default: original title
|
194
|
+
# :num and :max are as in permalink,
|
195
|
+
# :title is the original title
|
196
|
+
# :section is the text of the first header
|
197
|
+
|
198
|
+
retitle_first: true # Should the first part be retitled too? Default: false
|
199
|
+
|
200
|
+
trail: # The page trail settings: number of pages to list
|
201
|
+
before: 3 # before and after the current page
|
202
|
+
after: 3 # Omit or set to 0 for all pages (default)
|
203
|
+
|
204
|
+
seo_canonical: false # Set link ref="canonical" to the view-all page; default: true
|
205
|
+
|
206
|
+
prepend_baseurl: false # Prepend the site.baseurl to paths; default: true
|
207
|
+
|
208
|
+
#properties: # Set properties per type of page, see below
|
209
|
+
# all:
|
210
|
+
# field1: value1
|
211
|
+
# # ...etc...
|
212
|
+
# first:
|
213
|
+
# field2: value2
|
214
|
+
# # ...etc...
|
215
|
+
# part:
|
216
|
+
# field3: value3
|
217
|
+
# # ...etc...
|
218
|
+
# last:
|
219
|
+
# field4: value4
|
220
|
+
# # ...etc...
|
221
|
+
# single:
|
222
|
+
# field5: value5
|
223
|
+
# # ...etc...
|
224
|
+
|
225
|
+
```
|
226
|
+
|
227
|
+
Here's a cleaned-up version with the defaults:
|
228
|
+
|
229
|
+
```yaml
|
230
|
+
|
231
|
+
paginate_content:
|
232
|
+
#enabled: true
|
233
|
+
#debug: false
|
234
|
+
|
235
|
+
#collections:
|
236
|
+
# - pages
|
237
|
+
# - posts
|
238
|
+
|
239
|
+
#auto: false
|
240
|
+
|
241
|
+
#separator: "<!--page-->"
|
242
|
+
#header: "<!--page_header-->"
|
243
|
+
#footer: "<!--page_footer-->"
|
244
|
+
|
245
|
+
#permalink: '/:num/"
|
246
|
+
#single_page: '/view-all/'
|
247
|
+
#minimum: 0
|
248
|
+
|
249
|
+
#title: ':title'
|
250
|
+
#retitle_first: false
|
251
|
+
|
252
|
+
#trail:
|
253
|
+
# before: 0
|
254
|
+
# after: 0
|
255
|
+
|
256
|
+
#seo_canonical: true
|
257
|
+
|
258
|
+
#prepend_baseurl: true
|
259
|
+
|
260
|
+
#properties:
|
261
|
+
# all:
|
262
|
+
# first:
|
263
|
+
# part:
|
264
|
+
# last:
|
265
|
+
# single:
|
266
|
+
|
267
|
+
```
|
268
|
+
|
269
|
+
## Usage
|
270
|
+
|
271
|
+
Just add a `paginate: true` entry to your front-matter:
|
272
|
+
|
273
|
+
```yaml
|
274
|
+
---
|
275
|
+
title: Test post
|
276
|
+
layout: post
|
277
|
+
date: 2017-12-15 22:33:44
|
278
|
+
paginate: true
|
279
|
+
---
|
280
|
+
```
|
281
|
+
|
282
|
+
or set `auto` to `true` in your `_config.yml`:
|
283
|
+
|
284
|
+
```yaml
|
285
|
+
paginate_content:
|
286
|
+
auto: true
|
287
|
+
```
|
288
|
+
|
289
|
+
Note that using `auto` mode might be slower on your machine.
|
290
|
+
|
291
|
+
You may also override `_config.yml` settings for a particular file like so:
|
292
|
+
|
293
|
+
```yaml
|
294
|
+
---
|
295
|
+
title: Test page
|
296
|
+
layout: page
|
297
|
+
paginate: true
|
298
|
+
paginate_content:
|
299
|
+
permalink: '/page:numof:max.html'
|
300
|
+
single_page: '/full.html'
|
301
|
+
---
|
302
|
+
```
|
303
|
+
## Splitting content
|
304
|
+
|
305
|
+
How your files are split depends on your `separator`:
|
306
|
+
|
307
|
+
### Manual mode
|
308
|
+
|
309
|
+
If your `separator` is `"<!--page-->"`, just put that wherever you want a split to occur:
|
310
|
+
|
311
|
+
```html
|
312
|
+
This is a page.
|
313
|
+
<!--page-->
|
314
|
+
This is another page.
|
315
|
+
```
|
316
|
+
|
317
|
+
### HTML header mode
|
318
|
+
|
319
|
+
If you set your header to "h1" up to "h6", your files will be split at those headers. Both the standard `atx` and `Setext` formats are supported -- the former uses 1 to 6 hashes (`# ` to `###### `) at the start for <h1> to <h6>, while the later uses equals-underscores for <h1> and dash-underscores for <h2>
|
320
|
+
|
321
|
+
For example, if your separator is `"h1"`:
|
322
|
+
|
323
|
+
```markdown
|
324
|
+
# Introduction
|
325
|
+
This is a page.
|
326
|
+
|
327
|
+
Discussion
|
328
|
+
==========
|
329
|
+
This is another page
|
330
|
+
|
331
|
+
## Point 1
|
332
|
+
This is not.
|
333
|
+
|
334
|
+
Point 2
|
335
|
+
-------
|
336
|
+
Neither is this
|
337
|
+
|
338
|
+
<h1>Conclusion</h1>
|
339
|
+
But this is.
|
340
|
+
```
|
341
|
+
|
342
|
+
At this time, you'll need at least 4 dashes for Setext-style <h2>. Note that Setext only supports <h1> and <h2>.
|
343
|
+
|
344
|
+
### Page headers and footers
|
345
|
+
|
346
|
+
Anything above your configured `header` string will appear at the top of the generated pages. Likewise, anything after your `footer` string will appear at the bottom.
|
347
|
+
|
348
|
+
```markdown
|
349
|
+
This is the header
|
350
|
+
<!--page_header-->
|
351
|
+
|
352
|
+
This is a page.
|
353
|
+
<!--page-->
|
354
|
+
This is another page.
|
355
|
+
|
356
|
+
<!--page_footer-->
|
357
|
+
This is the footer.
|
358
|
+
```
|
359
|
+
|
360
|
+
If you split your links like so:
|
361
|
+
|
362
|
+
```markdown
|
363
|
+
This is a [link].
|
364
|
+
|
365
|
+
[link]: https://example.com
|
366
|
+
```
|
367
|
+
|
368
|
+
make sure you put these referenced link definitions below the `footer` so that references to them will work across pages.
|
369
|
+
|
370
|
+
### Minimum page length
|
371
|
+
|
372
|
+
You may set the minimum length (in characters) using the `minimum` property in `_config.yml` or your front-matter. Should a particular section be too short, the next section will be merged in, and so on until the minimum is reached or there are no more pages.
|
373
|
+
|
374
|
+
Note that this length includes markup, not just the actual displayed text, so you may want to take that into consideration. A minimum of 1000 to 2000 should work well.
|
375
|
+
|
376
|
+
## Paginator Properties/Fields
|
377
|
+
|
378
|
+
These properties/fields are available to your layouts and content via the `paginator` object, e.g. `{{ paginator.page }}`.
|
379
|
+
|
380
|
+
|
381
|
+
| Field | Aliases | Description |
|
382
|
+
|----------------------|-----------------|-------------------------------------|
|
383
|
+
| `first_page` | | First page number, i.e. 1 |
|
384
|
+
| `first_page_path` | `first_path` | Relative URL to the first page |
|
385
|
+
| `next_page` | | Next page number |
|
386
|
+
| `next_page_path` | `next_path` | Relative URL to the next page |
|
387
|
+
| `previous_page` | `prev_page` | Previous page number |
|
388
|
+
| `previous_page_path` | `previous_path`<br/>`prev_path` | Relative URL to the previous page
|
389
|
+
| `last_page` | | Last page number |
|
390
|
+
| `last_page_path` | `last_path` | Relative URL to the last page |
|
391
|
+
| `page` | `page_num` | Current page number |
|
392
|
+
| `page_path` | | Path to the current page |
|
393
|
+
| `page_trail` | | Page trail, see [below](#pagination-trails) |
|
394
|
+
| `paginated` | `activated` | `true` if this is a partial page |
|
395
|
+
| `total_pages` | `pages` | Total number of pages |
|
396
|
+
| | | |
|
397
|
+
| `single_page` | `view_all` | Path to the original/full page |
|
398
|
+
| `seo` | | HTML header tags for SEO, see [below](#search-engine-optimization-seo)
|
399
|
+
| | | |
|
400
|
+
| `section` | | Text of the first header (<h1> etc.) on this page
|
401
|
+
| `previous_section` | `prev_section` | Ditto for the previous page |
|
402
|
+
| `next_section` | | Ditto for the next page |
|
403
|
+
| | | |
|
404
|
+
| `has_next` | | `true` if there is a next page |
|
405
|
+
| `has_previous` | `has_prev` | `true` if there is a previous page |
|
406
|
+
| `is_first` | | `true` if this is the first page |
|
407
|
+
| `is_last` | | `true` if this is the last page |
|
408
|
+
| `next_is_last` | | `true` if this page is next-to-last |
|
409
|
+
| `previous_is_first` | `prev_is_first` | `true` if this is the second page |
|
410
|
+
|
411
|
+
### site.baseurl
|
412
|
+
|
413
|
+
By default, JPC automatically prepends your `site.baseurl` to generated paths so you don't have to do it yourself. If you don't like this behavior, set `prepend_baseurl: false` in your configuration.
|
414
|
+
|
415
|
+
## Page/Post properties
|
416
|
+
|
417
|
+
These properties are automatically set for pages and other content that have been processed, e.g `{{ post.autogen }}`
|
418
|
+
|
419
|
+
| Field | Description
|
420
|
+
|----------------------|----------------------------------------------------------------------
|
421
|
+
| `permalink` | Relative path of the current page
|
422
|
+
| |
|
423
|
+
| `hidden` | `true` for all pages (including the single-page view) except the first page
|
424
|
+
| `tag`, `tags` | `nil` for all except the first page
|
425
|
+
| `category`, `categories` | `nil` for all except the first page
|
426
|
+
| |
|
427
|
+
| `autogen` | "jekyll-paginate-content" for all pages
|
428
|
+
| `pagination_info` | `.curr_page` = current page number<br/>`.total_pages` = total number of pages<br/>`.type` = "first", "part", "last", or "single"<br/>`.id` = a string which is the same for all related pages
|
429
|
+
|
430
|
+
The tags, categories, and `hidden` are set up this way to avoid duplicate counts and having the parts show up in e.g. your tag index listings. You may override this behavior as discussed [below](#overriding-and-restoring-properties).
|
431
|
+
|
432
|
+
### Setting custom properties
|
433
|
+
|
434
|
+
`paginate_content` in `_config.yml` has a `properties` option:
|
435
|
+
|
436
|
+
```yaml
|
437
|
+
paginate_content:
|
438
|
+
properties:
|
439
|
+
all:
|
440
|
+
field1: value1
|
441
|
+
# ...etc...
|
442
|
+
first:
|
443
|
+
field2: value2
|
444
|
+
# ...etc...
|
445
|
+
part:
|
446
|
+
field3: value3
|
447
|
+
# ...etc...
|
448
|
+
last:
|
449
|
+
field4: value4
|
450
|
+
# ...etc...
|
451
|
+
single:
|
452
|
+
field5: value5
|
453
|
+
# ...etc...
|
454
|
+
```
|
455
|
+
|
456
|
+
where the properties/fields listed under `all` will be set for all pages, `first` properties for the first page (possibly overriding values in `all`), etc.
|
457
|
+
|
458
|
+
**Example:** To help with your layouts, you may want to set a property for the single-page view, say, activating comments:
|
459
|
+
|
460
|
+
```yaml
|
461
|
+
paginate_content:
|
462
|
+
properties:
|
463
|
+
single:
|
464
|
+
comments: true
|
465
|
+
```
|
466
|
+
|
467
|
+
In your layout, you'd use something like
|
468
|
+
|
469
|
+
```html
|
470
|
+
{% if post.comments %}
|
471
|
+
<!-- Disqus section -->
|
472
|
+
{% endif %}
|
473
|
+
```
|
474
|
+
|
475
|
+
The single-page view would then show the [Disqus](https://disqus.com/) comments section.
|
476
|
+
|
477
|
+
### Overriding and restoring properties
|
478
|
+
|
479
|
+
You can set almost any front-matter property via the `properties` section, except for `title`, `layout`, `date`, `permalink`, and `pagination_info`. Use with caution.
|
480
|
+
|
481
|
+
#### Special values
|
482
|
+
|
483
|
+
You may use the following values for properties:
|
484
|
+
|
485
|
+
| Value | Meaning
|
486
|
+
|-------|--------------------------------------
|
487
|
+
| `~` | `nil` (essentially disabling the property)
|
488
|
+
| `$` | The original value of the property
|
489
|
+
| `$.property` | The original value of the specified `property`
|
490
|
+
| `/` | Totally remove this property
|
491
|
+
|
492
|
+
### Default properties
|
493
|
+
|
494
|
+
For reference, the default properties effectively map out to:
|
495
|
+
|
496
|
+
```yaml
|
497
|
+
properties:
|
498
|
+
all:
|
499
|
+
autogen: 'jekyll-paginate-content'
|
500
|
+
hidden: true
|
501
|
+
tag: ~
|
502
|
+
tags: ~
|
503
|
+
category: ~
|
504
|
+
categories: ~
|
505
|
+
pagination_info:
|
506
|
+
curr_page: (a number)
|
507
|
+
total_pages: (a number)
|
508
|
+
id: '(a string)'
|
509
|
+
|
510
|
+
first:
|
511
|
+
hidden: false
|
512
|
+
tag: $
|
513
|
+
tags: $
|
514
|
+
category: $
|
515
|
+
categories: $
|
516
|
+
pagination_info:
|
517
|
+
type: 'first'
|
518
|
+
|
519
|
+
part:
|
520
|
+
pagination_info:
|
521
|
+
type: 'part'
|
522
|
+
|
523
|
+
last:
|
524
|
+
pagination_info:
|
525
|
+
type: 'last'
|
526
|
+
|
527
|
+
single:
|
528
|
+
pagination_info:
|
529
|
+
curr_page: /
|
530
|
+
total_pages: /
|
531
|
+
type: 'single'
|
532
|
+
```
|
533
|
+
|
534
|
+
### Example
|
535
|
+
|
536
|
+
The author's `_config.yml` has the following:
|
537
|
+
|
538
|
+
```yaml
|
539
|
+
properties:
|
540
|
+
all:
|
541
|
+
comments: false
|
542
|
+
share: false
|
543
|
+
x_title: $.title
|
544
|
+
|
545
|
+
#first:
|
546
|
+
# keeps original tags and categories
|
547
|
+
|
548
|
+
part:
|
549
|
+
x_tags: []
|
550
|
+
x_cats: []
|
551
|
+
|
552
|
+
last:
|
553
|
+
comments: true
|
554
|
+
share: true
|
555
|
+
x_tags: $.tags
|
556
|
+
x_cats: $.categories
|
557
|
+
|
558
|
+
single:
|
559
|
+
comments: true
|
560
|
+
share: true
|
561
|
+
x_tags: $.tags
|
562
|
+
x_cats: $.categories
|
563
|
+
```
|
564
|
+
|
565
|
+
`x_tags` and `x_cats` are used in this case to store the original tags and categories for generating a list of related posts only for last pages or single-page views. `comments` and `share` are likewise used to turn on the sections for comments and social media sharing for these pages.
|
566
|
+
|
567
|
+
`x_title` saves the original title for use in social media sharing. The example below also does something similar for the URL to be shared:
|
568
|
+
|
569
|
+
```
|
570
|
+
{% if page.x_title %}
|
571
|
+
{% assign share_title = page.x_title %}
|
572
|
+
{% else %}
|
573
|
+
{% assign share_title = page.title %}
|
574
|
+
{% endif %}
|
575
|
+
|
576
|
+
{% if paginator.first_path %}
|
577
|
+
{% assign share_url = paginator.first_path %}
|
578
|
+
{% else %}
|
579
|
+
{% assign share_url = page.url %}
|
580
|
+
{% endif %}
|
581
|
+
```
|
582
|
+
|
583
|
+
## Pagination trails
|
584
|
+
|
585
|
+
You use `paginator.page_trail` to create a pager that will allow your readers to move from page to page. It is set up as follows:
|
586
|
+
|
587
|
+
```yaml
|
588
|
+
paginate_content:
|
589
|
+
trail:
|
590
|
+
before: 2
|
591
|
+
after: 2
|
592
|
+
```
|
593
|
+
|
594
|
+
`before` refers to the number of page links you want to appear before the current page, as much as possible. Similarly, `after` is the number of page links after the current page. So, in the above example, you have 2 before + 1 current + 2 after = 5 links to pages in your trail "window".
|
595
|
+
|
596
|
+
If you don't specify the `trail` properties, or set `before` and `after` to 0, all page links will be returned.
|
597
|
+
|
598
|
+
Let's say your document has 7 pages, and you have a `trail` as above. The pager would look something like this as you go from page to page:
|
599
|
+
|
600
|
+
<pre><strong>« <1> [2] [3] [4] [5] »
|
601
|
+
« [1] <2> [3] [4] [5] »
|
602
|
+
« [1] [2] <3> [4] [5] »
|
603
|
+
« [2] [3] <4> [5] [6] »
|
604
|
+
« [3] [4] <5> [6] [7] »
|
605
|
+
« [3] [4] [5] <6> [7] »
|
606
|
+
« [3] [4] [5] [6] <7> »
|
607
|
+
</strong></pre>
|
608
|
+
|
609
|
+
### Usage
|
610
|
+
|
611
|
+
`paginator.page_trail` has the following fields:
|
612
|
+
|
613
|
+
| Field | Description
|
614
|
+
|---------|--------------------------------------
|
615
|
+
| `num` | The page number
|
616
|
+
| `path` | The path to the page
|
617
|
+
| `title` | The title of the page
|
618
|
+
|
619
|
+
Here is an example adapted from [JPv2's documentation](https://github.com/sverrirs/jekyll-paginate-v2/blob/master/README-GENERATOR.md#creating-pagination-trails). Note that you don't need to prepend `site.baseurl` to `trail.path` as it is automatically added in by JPC [by default](#sitebaseurl).
|
620
|
+
|
621
|
+
```html
|
622
|
+
{% if paginator.page_trail %}
|
623
|
+
<ul class="pager">
|
624
|
+
{% for trail in paginator.page_trail %}
|
625
|
+
<li {% if page.url == trail.path %}class="selected"{% endif %}>
|
626
|
+
<a href="{{ trail.path }}" title="{{ trail.title }}">{{ trail.num }}</a>
|
627
|
+
</li>
|
628
|
+
{% endfor %}
|
629
|
+
</ul>
|
630
|
+
{% endif %}
|
631
|
+
```
|
632
|
+
|
633
|
+
Its [accompanying style](https://github.com/sverrirs/jekyll-paginate-v2/blob/master/examples/03-tags/_layouts/home.html):
|
634
|
+
|
635
|
+
```html
|
636
|
+
<style>
|
637
|
+
ul.pager { text-align: center; list-style: none; }
|
638
|
+
ul.pager li {display: inline;border: 1px solid black; padding: 10px; margin: 5px;}
|
639
|
+
.selected { background-color: magenta; }
|
640
|
+
</style>
|
641
|
+
```
|
642
|
+
|
643
|
+
You'll end up with something like this, for page 4:
|
644
|
+
|
645
|
+
<p align="center">
|
646
|
+
<img src="https://raw.githubusercontent.com/ibrado/jekyll-paginate-content/master/res/jpv2-trail.png" />
|
647
|
+
</p>
|
648
|
+
|
649
|
+
The author's own pager is a little more involved and uses some convenience fields and aliases:
|
650
|
+
|
651
|
+
```html
|
652
|
+
{% if paginator.page_trail %}
|
653
|
+
<div class="pager">
|
654
|
+
{% if paginator.is_first %}
|
655
|
+
<span class="pager-inactive"><i class="fa fa-fast-backward" aria-hidden="true"></i></span>
|
656
|
+
<span class="pager-inactive"><i class="fa fa-backward" aria-hidden="true"></i></span>
|
657
|
+
{% else %}
|
658
|
+
<a href="{{ paginator.first_path }}"><i class="fa fa-fast-backward" aria-hidden="true"></i></a>
|
659
|
+
<a href="{{ paginator.previous_path }}"><i class="fa fa-backward" aria-hidden="true"></i></a>
|
660
|
+
{% endif %}
|
661
|
+
|
662
|
+
{% for p in paginator.page_trail %}
|
663
|
+
{% if p.num == paginator.page %}
|
664
|
+
{{ p.num }}
|
665
|
+
{% else %}
|
666
|
+
<a href="{{ p.path }}" data-toggle="tooltip" data-placement="top" title="{{ p.title }}">{{ p.num }}</a>
|
667
|
+
{% endif %}
|
668
|
+
{% endfor %}
|
669
|
+
|
670
|
+
{% if paginator.is_last %}
|
671
|
+
<span class="pager-inactive"><i class="fa fa-forward" aria-hidden="true"></i></span>
|
672
|
+
<span class="pager-inactive"><i class="fa fa-fast-forward" aria-hidden="true"></i></span>
|
673
|
+
{% else %}
|
674
|
+
<a href="{{ paginator.next_path }}"><i class="fa fa-forward" aria-hidden="true"></i></a>
|
675
|
+
<a href="{{ paginator.last_path }}"><i class="fa fa-fast-forward" aria-hidden="true"></i></a>
|
676
|
+
{% endif %}
|
677
|
+
</div>
|
678
|
+
{% endif %}
|
679
|
+
```
|
680
|
+
|
681
|
+
This results in a pager that looks like this:
|
682
|
+
|
683
|
+
<p align="center">
|
684
|
+
<img src="https://raw.githubusercontent.com/ibrado/jekyll-paginate-content/master/res/ajni-trail-p1.png" />
|
685
|
+
</p>
|
686
|
+
|
687
|
+
<p align="center">
|
688
|
+
<img src="https://raw.githubusercontent.com/ibrado/jekyll-paginate-content/master/res/ajni-trail-p4.png" />
|
689
|
+
</p>
|
690
|
+
|
691
|
+
### Page flipper
|
692
|
+
|
693
|
+
You may also want to add a page "flipper" that uses section names:
|
694
|
+
|
695
|
+
```html
|
696
|
+
<!--page_footer-->
|
697
|
+
<div>
|
698
|
+
{% if paginator.previous_section %}
|
699
|
+
« <a href="{{ paginator.previous_path }}">{{ paginator.previous_section }}</a>
|
700
|
+
{% endif %}
|
701
|
+
{% if paginator.previous_section and paginator.next_section %} | {% endif %}
|
702
|
+
{% if paginator.next_section %}
|
703
|
+
<a href="{{ paginator.next_path }}">{{ paginator.next_section }}</a> »
|
704
|
+
{% endif %}
|
705
|
+
</div>
|
706
|
+
```
|
707
|
+
|
708
|
+
Should there be no available section name, "Untitled" will be returned. You can then handle it like so:
|
709
|
+
|
710
|
+
```html
|
711
|
+
{% if paginator.previous_section == "Untitled" %}
|
712
|
+
Previous
|
713
|
+
{% else %}
|
714
|
+
{{ paginator.previous_section }}
|
715
|
+
{% endif %}
|
716
|
+
```
|
717
|
+
|
718
|
+
Of course, you always have the option of adding some navigational cues to your content:
|
719
|
+
|
720
|
+
```html
|
721
|
+
{% if paginator.paginated %}
|
722
|
+
<a href="{{ paginator.next_page_path }}">On to the next chapter...</a>
|
723
|
+
{% endif %}
|
724
|
+
```
|
725
|
+
|
726
|
+
This text will not appear in the single-page view.
|
727
|
+
|
728
|
+
## Table Of Contents (TOC)
|
729
|
+
|
730
|
+
JPC automatically generates a Table of Contents for you. To use this from within your content, simply insert the following:
|
731
|
+
|
732
|
+
```
|
733
|
+
{{ paginator.toc.simple }}
|
734
|
+
```
|
735
|
+
|
736
|
+
If you want to use this from an HTML layout, e.g. an included `sidebar.html`:
|
737
|
+
|
738
|
+
```
|
739
|
+
{{ paginator.toc.simple | markdownify }}
|
740
|
+
```
|
741
|
+
|
742
|
+
The difference between this and the one built into [kramdown](https://kramdown.gettalong.org/), the default Jekyll Markdown engine, is that it is aware that content may be split across several pages now, and adjusts links depending on the current page.
|
743
|
+
|
744
|
+
> The reason `paginator.toc.simple` is used vs just `paginator.toc` is to allow for further TOC features in the future.
|
745
|
+
|
746
|
+
### Excluding sections
|
747
|
+
|
748
|
+
Should you want some fields excluded from the Table Of Contents, add them to the `toc_exclude` option in your site configuration or content front-matter:
|
749
|
+
|
750
|
+
```yaml
|
751
|
+
paginate_content:
|
752
|
+
toc_exclude: "Table Of Contents"
|
753
|
+
```
|
754
|
+
or
|
755
|
+
|
756
|
+
```yaml
|
757
|
+
paginate_content:
|
758
|
+
toc_exclude:
|
759
|
+
- "Table Of Contents"
|
760
|
+
- "Shy Section"
|
761
|
+
```
|
762
|
+
|
763
|
+
The generated section ids follow the usual convention:
|
764
|
+
|
765
|
+
1. Convert the section name to lowercase
|
766
|
+
1. Remove all punctuation
|
767
|
+
1. Convert multiple spaces to a single space
|
768
|
+
1. Convert spaces to dashes
|
769
|
+
1. If that id already exists, add "-1", "-2", etc. until the id is unique
|
770
|
+
|
771
|
+
## Search Engine Optimization (SEO)
|
772
|
+
|
773
|
+
Now that your site features split pages (*finally!*), how do you optimize it for search engines?
|
774
|
+
|
775
|
+
`paginator.seo` has the following fields:
|
776
|
+
|
777
|
+
| Field | Description
|
778
|
+
|-------------|--------------------------------------
|
779
|
+
| `canonical` | HTML `link rel` of the canonical URL (primary page for search results)
|
780
|
+
| `prev` | Ditto for the previous page, if applicable
|
781
|
+
| `next` | Ditto for the next page, if applicable
|
782
|
+
| `links` | All of the above, combined
|
783
|
+
|
784
|
+
You could simply add the following somewhere inside the <tt><head></tt> of your document:
|
785
|
+
|
786
|
+
```
|
787
|
+
{{ paginator.seo.links }}
|
788
|
+
```
|
789
|
+
|
790
|
+
It will produce up to three lines, like so (assuming you are on page 5):
|
791
|
+
|
792
|
+
```html
|
793
|
+
<link rel="canonical" href="https://example.com/2017/12/my-post/view-all/" />
|
794
|
+
<link rel="prev" href="https://example.com/2017/12/my-post/4/" />
|
795
|
+
<link rel="next" href="https://example.com/2017/12/my-post/6/" />
|
796
|
+
```
|
797
|
+
|
798
|
+
`rel="prev"` and/or `rel="next"` will not be included if there is no previous and/or next page, respectively. If you don't want to set canonical to the single-view page, just set `seo_canonical` in your `_config.yml` to `false`.
|
799
|
+
|
800
|
+
### Unified approach
|
801
|
+
|
802
|
+
It would be better to use the following approach, though:
|
803
|
+
|
804
|
+
```html
|
805
|
+
{% unless paginator %}
|
806
|
+
<link rel="canonical" href="{{ site.canonical }}{{ site.baseurl }}{{ page.url }}" />
|
807
|
+
{% endunless %}
|
808
|
+
{% if paginator.seo.links %}
|
809
|
+
{{ paginator.seo.links }}
|
810
|
+
{% else %}
|
811
|
+
{% if paginator.previous_page_path %}
|
812
|
+
<link rel="prev" href="{{ site.url }}{{ site.baseurl }}{{ paginator.previous_page_path }}" />
|
813
|
+
{% endif %}
|
814
|
+
{% if paginator.next_page_path %}
|
815
|
+
<link rel="next" href="{{ site.url }}{{ site.baseurl }}{{ paginator.next_page_path }}" />
|
816
|
+
{% endif %}
|
817
|
+
{% endif %}
|
818
|
+
```
|
819
|
+
|
820
|
+
This way it works with JPv2, JPC, and with no paginator active.
|
821
|
+
|
822
|
+
What about `canonical` for JPv2-generated pages? Unless you have a "view-all" page that includes all your unpaginated posts and you want search engines to use that possibly huge page as the primary search result, it is probably best to just not put a `canonical` link at all.
|
823
|
+
|
824
|
+
## Demos
|
825
|
+
|
826
|
+
1. TL;DR demos: [manual](https://ibrado.org/demos/jpc-3page-manual/), [automatic](https://ibrado.org/demos/jpc-3page-auto/)
|
827
|
+
1. Simple example as a [post](https://ibrado.org/2017/12/jpc-demo-post/), as an item in a [collection](https://ibrado.org/demos/jpc/), and as a [page](https://ibrado.org/jpc-demo/).
|
828
|
+
1. [This README](https://ibrado.org/jpc/readme/), autopaginated
|
829
|
+
|
830
|
+
## Limitations
|
831
|
+
|
832
|
+
1. Some link/anchor formats may not be supported yet; inform author, please.
|
833
|
+
1. The Setext mode, i.e. underscoring header names with equal signs (<tt><h1></tt>) or dashes (<tt><h2></tt>), needs to have at least 4 dashes for <tt><h2></tt>.
|
834
|
+
|
835
|
+
## Contributing
|
836
|
+
|
837
|
+
1. Fork this project: [https://github.com/ibrado/jekyll-paginate-content/fork](https://github.com/ibrado/jekyll-paginate-content/fork)
|
838
|
+
1. Clone it (`git clone git://github.com/your_user_name/jekyll-paginate-content.git`)
|
839
|
+
1. `cd jekyll-paginate-content`
|
840
|
+
1. Create a new branch (e.g. `git checkout -b my-bug-fix`)
|
841
|
+
1. Make your changes
|
842
|
+
1. Commit your changes (`git commit -m "Bug fix"`)
|
843
|
+
1. Build it (`gem build jekyll-paginate-content.gemspec`)
|
844
|
+
1. Install and test it (`gem install ./jekyll-paginate-content-*.gem`)
|
845
|
+
1. Repeat from step 5 as necessary
|
846
|
+
1. Push the branch (`git push -u origin my-bug-fix`)
|
847
|
+
1. Create a Pull Request, making sure to select the proper branch, e.g. `my-bug-fix` (via https://github.com/your_user_name/jekyll-paginate-content)
|
848
|
+
|
849
|
+
Bug reports and pull requests are welcome on GitHub at [https://github.com/ibrado/jekyll-paginate-content](https://github.com/ibrado/jekyll-paginate-content). This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
|
850
|
+
|
851
|
+
## License
|
852
|
+
|
853
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
854
|
+
|
855
|
+
## Code of Conduct
|
856
|
+
Everyone interacting in the Jekyll::Paginate::Content project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/ibrado/jekyll-paginate-content/blob/master/CODE_OF_CONDUCT.md).
|
857
|
+
|
858
|
+
## Also by the Author
|
859
|
+
|
860
|
+
[Jekyll Stickyposts Plugin](https://github.com/ibrado/jekyll-stickyposts) - Move/pin posts tagged `sticky: true` before all others. Sorting on custom fields supported; collection and paginator friendly.
|
861
|
+
|
862
|
+
[Jekyll Tweetsert Plugin](https://github.com/ibrado/jekyll-tweetsert) - Turn tweets into Jekyll posts. Multiple timelines, filters, hashtags, automatic category/tags, and more!
|