随着时间越长,站内内容会越来越多,但 Jekyll 及官方却未提供分页功能或插件,这对内容展示上非常不友好。所幸 Jekyll 支持用户通过 Ruby 脚本实现自定义插件,通过插件可以实现一个我们想要的分页功能插件。

插件实现思路

实现插件逻辑代码

laijinman-post-list-page-generator.rb

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
module Laijinman
    class PostListPageGenerator < Jekyll::Generator
        safe true

        def generate(site)
            paginate  = site.config['paginate'] || 10;
            dir       = 'posts'
            layout    = 'posts'
            all_posts = site.site_payload['site']['posts']

            posts    = all_posts.reject { |p| p['hidden'] }
            pre_page = paginate.to_i

            total_posts = posts.size
            total_pages = total_posts.fdiv(pre_page).ceil
            (1..total_pages).each do |page|
                paginator = Paginator.new(posts, pre_page, page, dir)

                data = Hash.new()
                data['paginator'] = paginator
                site.pages << Page.new(site, paginator.page_path, data, layout)
            end
        end
    end
end

laijinman-paginator.rb

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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
module Laijinman
    class Paginator
        attr_reader :dir, :pre_page, :page, :total_records, :total_pages, :records,
            :page_path, :previous_page, :previous_page_path, :next_page,
            :next_page_path;
      
        def initialize(records, pre_page, page, dir)
            @dir                = dir
            @pre_page           = pre_page
            @page               = page
            @total_records      = records.size
            @total_pages        = @total_records.fdiv(@pre_page).ceil
            @records            = records[(@page - 1) * @pre_page, @pre_page]
            @page_path          = dir
            @previous_page      = nil
            @previous_page_path = nil
            @next_page          = nil
            @next_page_path     = nil
      
            if 1 < @page
                @page_path = File.join('/', dir, page.to_s)
            end
      
            if 1 < @page
                @previous_page = @page - 1
                if 1 < @previous_page
                    @previous_page_path = File.join('/', dir, @previous_page.to_s)
                else
                    @previous_page_path = File.join('/', dir)
                end
            end
      
            if @total_pages > @page
                @next_page = @page + 1
                @next_page_path = File.join('/', dir, @next_page.to_s)
            end
      
            def to_liquid
                {
                    'dir'                => @dir,
                    'page'               => @page,
                    'per_page'           => @per_page,
                    'records'            => @records,
                    'total_records'      => @total_records,
                    'total_pages'        => @total_pages,
                    'page_path'          => @page_path,
                    'previous_page'      => @previous_page,
                    'previous_page_path' => @previous_page_path,
                    'next_page'          => @next_page,
                    'next_page_path'     => @next_page_path
                }
            end
        end
    end
end

laijinman-page.rb

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
module Laijinman

  class Page < Jekyll::Page
    def initialize(site, dir, data, layout)
      @site = site
      @base = site.source
      @dir  = dir
      @name = 'index.html'

      self.process(@name)

      self.read_yaml(File.join(@base, '_layouts'), "#{layout}.html")

      data.each do |key, value|
          self.data[key]  = value
      end
    end
  end
end

页面渲染

html

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
{%- if page.paginator.records.size > 0 -%}
<ul id="post-pagination" class="pagination">
  <li>
    {% if page.paginator.previous_page_path %}
    <a href="{{ page.paginator.previous_page_path | uri_escape }}">{{ "上一页" | translate: "Previous" }}</a>
    {% else %}
      <span>{{ "上一页" | translate: "Previous" }}</span>
    {% endif %}
  <li>

{% for page in (1..page.paginator.total_pages) %}
  <li>
    {% if page == page.paginator.page %}
      <span class="active">{{ page }}</span>
    {% elsif 1 == page %}
    <a href="/{{ page.paginator.dir }}">{{ page }}</a>
    {% else %}
      <a href="/{{ page.paginator.dir }}/{{ page }}">{{ page }}</a>
    {% endif %}
  </li>
{% endfor %}

{% if page.paginator.next_page %}
  <li>
    <a href="{{ page.paginator.next_page_path | uri_escape }}">{{ "下一页" | translate: "Next"}}</a>
  </li>
{% else %}
  <li>
    <span>{{ "下一页" | translate: "Next"}}</span>
  </li>
{% endif %}
</ul>
{%- endif -%}

css/style

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
ul.pagination {
    display: inline-block;
    width: 100%;
    margin: 0;
    
    > li {
        display: inline;
        
        > a, > span {
            float: left;
            padding: 8px 16px;
            text-decoration: none;
        }
    }
}

演示

相关链接