| ... | ... |
@@ -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 |
+ |