pagination.js 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. 'use strict';
  2. const util = require('util');
  3. function pagination(base, posts, options) {
  4. if (typeof base !== 'string') throw new TypeError('base must be a string!');
  5. if (!posts) throw new TypeError('posts is required!');
  6. options = options || {};
  7. if (base && base[base.length - 1] !== '/') base += '/';
  8. const length = posts.length;
  9. const perPage = Object.prototype.hasOwnProperty.call(options, 'perPage') ? +options.perPage : 10;
  10. const total = perPage ? Math.ceil(length / perPage) : 1;
  11. const format = options.format || 'page/%d/';
  12. const layout = options.layout || ['archive', 'index'];
  13. const data = options.data || {};
  14. const result = [];
  15. const urlCache = {};
  16. function formatURL(i) {
  17. if (urlCache[i]) return urlCache[i];
  18. let url = base;
  19. if (i > 1) url += util.format(format, i);
  20. urlCache[i] = url;
  21. return url;
  22. }
  23. function makeData(i) {
  24. const data = {
  25. base,
  26. total,
  27. current: i,
  28. current_url: formatURL(i),
  29. posts: perPage ? posts.slice(perPage * (i - 1), perPage * i) : posts,
  30. prev: 0,
  31. prev_link: '',
  32. next: 0,
  33. next_link: ''
  34. };
  35. if (i > 1) {
  36. data.prev = i - 1;
  37. data.prev_link = formatURL(data.prev);
  38. }
  39. if (i < total) {
  40. data.next = i + 1;
  41. data.next_link = formatURL(data.next);
  42. }
  43. return data;
  44. }
  45. if (perPage) {
  46. for (let i = 1; i <= total; i++) {
  47. result.push({
  48. path: formatURL(i),
  49. layout,
  50. data: Object.assign(makeData(i), data)
  51. });
  52. }
  53. } else {
  54. result.push({
  55. path: base,
  56. layout,
  57. data: Object.assign(makeData(1), data)
  58. });
  59. }
  60. return result;
  61. }
  62. module.exports = pagination;