generator.js 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. 'use strict';
  2. const pagination = require('hexo-pagination');
  3. const fmtNum = num => {
  4. return num < 10 ? '0' + num : num;
  5. };
  6. module.exports = function(locals) {
  7. const config = this.config;
  8. let archiveDir = config.archive_dir;
  9. const paginationDir = config.pagination_dir || 'page';
  10. const allPosts = locals.posts.sort(config.archive_generator.order_by || '-date');
  11. const perPage = config.archive_generator.per_page;
  12. let result = [];
  13. if (!allPosts.length) return;
  14. if (archiveDir[archiveDir.length - 1] !== '/') archiveDir += '/';
  15. function generate(path, posts, options) {
  16. options = options || {};
  17. options.archive = true;
  18. result = result.concat(pagination(path, posts, {
  19. perPage: perPage,
  20. layout: ['archive', 'index'],
  21. format: paginationDir + '/%d/',
  22. data: options
  23. }));
  24. }
  25. generate(archiveDir, allPosts);
  26. if (!config.archive_generator.yearly) return result;
  27. const posts = {};
  28. // Organize posts by date
  29. allPosts.forEach(post => {
  30. const date = post.date;
  31. const year = date.year();
  32. const month = date.month() + 1; // month is started from 0
  33. if (!Object.prototype.hasOwnProperty.call(posts, year)) {
  34. // 13 arrays. The first array is for posts in this year
  35. // and the other arrays is for posts in this month
  36. posts[year] = [
  37. [],
  38. [],
  39. [],
  40. [],
  41. [],
  42. [],
  43. [],
  44. [],
  45. [],
  46. [],
  47. [],
  48. [],
  49. []
  50. ];
  51. }
  52. posts[year][0].push(post);
  53. posts[year][month].push(post);
  54. // Daily
  55. if (config.archive_generator.daily) {
  56. const day = date.date();
  57. if (!Object.prototype.hasOwnProperty.call(posts[year][month], 'day')) {
  58. posts[year][month].day = {};
  59. }
  60. (posts[year][month].day[day] || (posts[year][month].day[day] = [])).push(post);
  61. }
  62. });
  63. const Query = this.model('Post').Query;
  64. const years = Object.keys(posts);
  65. let year, data, month, monthData, url;
  66. // Yearly
  67. for (let i = 0, len = years.length; i < len; i++) {
  68. year = +years[i];
  69. data = posts[year];
  70. url = archiveDir + year + '/';
  71. if (!data[0].length) continue;
  72. generate(url, new Query(data[0]), {year: year});
  73. if (!config.archive_generator.monthly && !config.archive_generator.daily) continue;
  74. // Monthly
  75. for (month = 1; month <= 12; month++) {
  76. monthData = data[month];
  77. if (!monthData.length) continue;
  78. if (config.archive_generator.monthly) {
  79. generate(url + fmtNum(month) + '/', new Query(monthData), {
  80. year: year,
  81. month: month
  82. });
  83. }
  84. if (!config.archive_generator.daily) continue;
  85. // Daily
  86. for (let day = 1; day <= 31; day++) {
  87. const dayData = monthData.day[day];
  88. if (!dayData || !dayData.length) continue;
  89. generate(url + fmtNum(month) + '/' + fmtNum(day) + '/', new Query(dayData), {
  90. year: year,
  91. month: month,
  92. day: day
  93. });
  94. }
  95. }
  96. }
  97. return result;
  98. };