... | ... |
@@ -2,4 +2,41 @@ |
2 | 2 |
layout: default |
3 | 3 |
--- |
4 | 4 |
|
5 |
-{% include blog_index.html %} |
|
5 |
+<div class="blog-index"> |
|
6 |
+{% assign index = true %} |
|
7 |
+{% for post in paginator.posts %} |
|
8 |
+{% assign content = post.content %} |
|
9 |
+ <article> |
|
10 |
+ {% include article.html %} |
|
11 |
+ </article> |
|
12 |
+{% endfor %} |
|
13 |
+<nav role="pagination"> |
|
14 |
+ <div> |
|
15 |
+ {% if paginator.next_page %} |
|
16 |
+ <a class="prev" href="{{paginator.next_page}}">← Older</a> |
|
17 |
+ {% endif %} |
|
18 |
+ <a href="/blog/archives">Blog Archives</a> |
|
19 |
+ {% if paginator.previous_page %} |
|
20 |
+ <a class="next" href="{{paginator.previous_page}}">Newer →</a> |
|
21 |
+ {% endif %} |
|
22 |
+ </div> |
|
23 |
+</nav> |
|
24 |
+{% if site.disqus_short_name %} |
|
25 |
+<script type="text/javascript"> |
|
26 |
+ var disqus_shortname = '{{ site.disqus_short_name }}'; |
|
27 |
+ (function () { |
|
28 |
+ var s = document.createElement('script'); s.async = true; |
|
29 |
+ s.type = 'text/javascript'; |
|
30 |
+ s.src = 'http://' + disqus_shortname + '.disqus.com/count.js'; |
|
31 |
+ (document.getElementsByTagName('HEAD')[0] || document.getElementsByTagName('BODY')[0]).appendChild(s); |
|
32 |
+ }()); |
|
33 |
+</script> |
|
34 |
+{% endif %} |
|
35 |
+</div> |
|
36 |
+<aside role=sidebar> |
|
37 |
+ {% if site.blog_index_asides.size %} |
|
38 |
+ {% include_array blog_index_asides %} |
|
39 |
+ {% else %} |
|
40 |
+ {% include_array default_asides %} |
|
41 |
+ {% endif %} |
|
42 |
+</aside> |
... | ... |
@@ -29,8 +29,9 @@ category_dir: blog/categories |
29 | 29 |
markdown: rdiscount |
30 | 30 |
pygments: false # default python pygments have been replaced by pygments.rb |
31 | 31 |
|
32 |
-paginate: 10 # Posts per page on the blog index |
|
33 |
-recent_posts: 5 # Posts in the sidebar Recent Posts section |
|
32 |
+paginate: 10 # Posts per page on the blog index |
|
33 |
+pagination_dir: blog # Directory base for pagination URLs eg. /blog/page/2/ |
|
34 |
+recent_posts: 5 # Posts in the sidebar Recent Posts section |
|
34 | 35 |
|
35 | 36 |
# list each of the sidebar modules you want to include, in the order you want them to appear. |
36 | 37 |
# To add custom asides, create files in /source/_includes/custom/asides/ and add them to the list like 'custom/asides/custom_aside_name.html' |
37 | 38 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,121 @@ |
0 |
+module Jekyll |
|
1 |
+ |
|
2 |
+ class Pagination < Generator |
|
3 |
+ # This generator is safe from arbitrary code execution. |
|
4 |
+ safe true |
|
5 |
+ |
|
6 |
+ # Generate paginated pages if necessary. |
|
7 |
+ # |
|
8 |
+ # site - The Site. |
|
9 |
+ # |
|
10 |
+ # Returns nothing. |
|
11 |
+ def generate(site) |
|
12 |
+ site.pages.dup.each do |page| |
|
13 |
+ paginate(site, page) if Pager.pagination_enabled?(site.config, page) |
|
14 |
+ end |
|
15 |
+ end |
|
16 |
+ |
|
17 |
+ # Paginates the blog's posts. Renders the index.html file into paginated |
|
18 |
+ # directories, e.g.: page2/index.html, page3/index.html, etc and adds more |
|
19 |
+ # site-wide data. |
|
20 |
+ # |
|
21 |
+ # site - The Site. |
|
22 |
+ # page - The index.html Page that requires pagination. |
|
23 |
+ # |
|
24 |
+ # {"paginator" => { "page" => <Number>, |
|
25 |
+ # "per_page" => <Number>, |
|
26 |
+ # "posts" => [<Post>], |
|
27 |
+ # "total_posts" => <Number>, |
|
28 |
+ # "total_pages" => <Number>, |
|
29 |
+ # "previous_page" => <Number>, |
|
30 |
+ # "next_page" => <Number> }} |
|
31 |
+ def paginate(site, page) |
|
32 |
+ all_posts = site.site_payload['site']['posts'] |
|
33 |
+ pages = Pager.calculate_pages(all_posts, site.config['paginate'].to_i) |
|
34 |
+ page_dir = page.destination('').sub(/\/[^\/]+$/, '') |
|
35 |
+ page_dir_config = site.config['pagination_dir'] |
|
36 |
+ dir = ((page_dir_config || page_dir) + '/').sub(/^\/+/, '') |
|
37 |
+ |
|
38 |
+ (1..pages).each do |num_page| |
|
39 |
+ pager = Pager.new(site.config, num_page, all_posts, pages, page_dir+'/', '/'+dir) |
|
40 |
+ if num_page > 1 |
|
41 |
+ newpage = Page.new(site, site.source, page_dir, page.name) |
|
42 |
+ newpage.pager = pager |
|
43 |
+ newpage.dir = File.join(page.dir, "#{dir}page/#{num_page}") |
|
44 |
+ site.pages << newpage |
|
45 |
+ else |
|
46 |
+ page.pager = pager |
|
47 |
+ end |
|
48 |
+ end |
|
49 |
+ end |
|
50 |
+ end |
|
51 |
+ |
|
52 |
+ class Pager |
|
53 |
+ attr_reader :page, :per_page, :posts, :total_posts, :total_pages, :previous_page, :next_page |
|
54 |
+ |
|
55 |
+ # Calculate the number of pages. |
|
56 |
+ # |
|
57 |
+ # all_posts - The Array of all Posts. |
|
58 |
+ # per_page - The Integer of entries per page. |
|
59 |
+ # |
|
60 |
+ # Returns the Integer number of pages. |
|
61 |
+ def self.calculate_pages(all_posts, per_page) |
|
62 |
+ (all_posts.size.to_f / per_page.to_i).ceil |
|
63 |
+ end |
|
64 |
+ |
|
65 |
+ # Determine if pagination is enabled for a given file. |
|
66 |
+ # |
|
67 |
+ # config - The configuration Hash. |
|
68 |
+ # file - The String filename of the file. |
|
69 |
+ # |
|
70 |
+ # Returns true if pagination is enabled, false otherwise. |
|
71 |
+ def self.pagination_enabled?(config, file) |
|
72 |
+ file.name == 'index.html' && !config['paginate'].nil? && file.content =~ /paginator\./ |
|
73 |
+ end |
|
74 |
+ |
|
75 |
+ # Initialize a new Pager. |
|
76 |
+ # |
|
77 |
+ # config - The Hash configuration of the site. |
|
78 |
+ # page - The Integer page number. |
|
79 |
+ # all_posts - The Array of all the site's Posts. |
|
80 |
+ # num_pages - The Integer number of pages or nil if you'd like the number |
|
81 |
+ # of pages calculated. |
|
82 |
+ def initialize(config, page, all_posts, num_pages = nil, index_dir, pagination_dir) |
|
83 |
+ @page = page |
|
84 |
+ @per_page = config['paginate'].to_i |
|
85 |
+ @page_dir = pagination_dir + 'page/' |
|
86 |
+ @total_pages = num_pages || Pager.calculate_pages(all_posts, @per_page) |
|
87 |
+ @previous_page = nil |
|
88 |
+ |
|
89 |
+ if @page > @total_pages |
|
90 |
+ raise RuntimeError, "page number can't be greater than total pages: #{@page} > #{@total_pages}" |
|
91 |
+ end |
|
92 |
+ |
|
93 |
+ init = (@page - 1) * @per_page |
|
94 |
+ offset = (init + @per_page - 1) >= all_posts.size ? all_posts.size : (init + @per_page - 1) |
|
95 |
+ |
|
96 |
+ @total_posts = all_posts.size |
|
97 |
+ @posts = all_posts[init..offset] |
|
98 |
+ @previous_page = @page != 1 ? @page_dir + (@page - 1).to_s + '/' : nil |
|
99 |
+ @previous_page = index_dir if @page - 1 == 1 |
|
100 |
+ @next_page = @page != @total_pages ? @page_dir + (@page + 1).to_s + '/' : nil |
|
101 |
+ end |
|
102 |
+ |
|
103 |
+ # Convert this Pager's data to a Hash suitable for use by Liquid. |
|
104 |
+ # |
|
105 |
+ # Returns the Hash representation of this Pager. |
|
106 |
+ def to_liquid |
|
107 |
+ { |
|
108 |
+ 'page' => page, |
|
109 |
+ 'per_page' => per_page, |
|
110 |
+ 'posts' => posts, |
|
111 |
+ 'total_posts' => total_posts, |
|
112 |
+ 'total_pages' => total_pages, |
|
113 |
+ 'previous_page' => previous_page, |
|
114 |
+ 'next_page' => next_page |
|
115 |
+ } |
|
116 |
+ end |
|
117 |
+ end |
|
118 |
+ |
|
119 |
+end |
|
120 |
+ |