index.js 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. 'use strict';
  2. const { extname } = require('path');
  3. const Box = require('../box');
  4. const View = require('./view');
  5. const I18n = require('hexo-i18n');
  6. class Theme extends Box {
  7. constructor(ctx, options) {
  8. super(ctx, ctx.theme_dir, options);
  9. this.config = {};
  10. this.views = {};
  11. this.processors = [
  12. require('./processors/config'),
  13. require('./processors/i18n'),
  14. require('./processors/source'),
  15. require('./processors/view')
  16. ];
  17. let languages = ctx.config.language;
  18. if (!Array.isArray(languages)) languages = [languages];
  19. languages.push('default');
  20. this.i18n = new I18n({
  21. languages: [...new Set(languages.filter(Boolean))]
  22. });
  23. class _View extends View {}
  24. this.View = _View;
  25. _View.prototype._theme = this;
  26. _View.prototype._render = ctx.render;
  27. _View.prototype._helper = ctx.extend.helper;
  28. }
  29. getView(path) {
  30. // Replace backslashes on Windows
  31. path = path.replace(/\\/g, '/');
  32. const ext = extname(path);
  33. const name = path.substring(0, path.length - ext.length);
  34. const views = this.views[name];
  35. if (!views) return;
  36. if (ext) {
  37. return views[ext];
  38. }
  39. return views[Object.keys(views)[0]];
  40. }
  41. setView(path, data) {
  42. const ext = extname(path);
  43. const name = path.substring(0, path.length - ext.length);
  44. this.views[name] = this.views[name] || {};
  45. const views = this.views[name];
  46. views[ext] = new this.View(path, data);
  47. }
  48. removeView(path) {
  49. const ext = extname(path);
  50. const name = path.substring(0, path.length - ext.length);
  51. const views = this.views[name];
  52. if (!views) return;
  53. delete views[ext];
  54. }
  55. }
  56. module.exports = Theme;