require 'middleman-core' require 'middleman_dato/middleman_extension' module Middleman module Paginate class Extension < ::Middleman::ConfigExtension self.resource_list_manipulator_priority = 0 expose_to_config paginate: :paginate CollectionProxyDescriptor = Struct.new(:descriptors) do def execute_descriptor(app, resources) descriptors.reduce(resources) do |resources, descriptor| descriptor.execute_descriptor(app, resources) end end end class Pager attr_reader :current_page, :total_pages, :per_page def initialize(base_path, suffix, current_page, total_pages, per_page) @base_path = base_path @suffix = suffix @current_page = current_page @total_pages = total_pages @per_page = per_page end def next_page current_page < total_pages && current_page + 1 end def previous_page current_page > 1 && current_page - 1 end def full_page_path(page = current_page) "#{@base_path}#{page == 1 ? '/index' : @suffix.gsub(/:num/, page.to_s)}.html" end def page_path(page = current_page) full_path = full_page_path(page) if full_path.end_with?("/index.html") full_path.gsub(/index\.html$/, '') else full_path end end end def paginate(collection, base_path, template, per_page: 20, suffix: "/page/:num/index", locals: {}, data: {}, locale: nil) pages = collection.each_slice(per_page).to_a descriptors = [] pages.each_with_index do |page_collection, i| pager = Pager.new(base_path, suffix, i + 1, pages.size, per_page) opts = { locals: locals.merge(items: page_collection, pager: pager), data: data, locale: locale } descriptors << Middleman::Sitemap::Extensions::ProxyDescriptor.new( Middleman::Util.normalize_path(pager.full_page_path), Middleman::Util.normalize_path(template), opts.dup ) end CollectionProxyDescriptor.new(descriptors) end end end end