view/widget/tags.jsx

  1. /**
  2. * Tags widget JSX component.
  3. * @module view/widget/tags
  4. */
  5. const { Component } = require('inferno');
  6. const { cacheComponent } = require('../../util/cache');
  7. /**
  8. * Tags widget JSX component.
  9. *
  10. * @example
  11. * <Tags
  12. * title="Widget title"
  13. * showCount={true}
  14. * tags={[
  15. * {
  16. * url: '/path/to/category/page',
  17. * name: 'Category name',
  18. * count: 1
  19. * }
  20. * ]} />
  21. */
  22. class Tags extends Component {
  23. render() {
  24. const { tags, title, showCount } = this.props;
  25. return (
  26. <div class="card widget" data-type="tags">
  27. <div class="card-content">
  28. <div class="menu">
  29. <h3 class="menu-label">{title}</h3>
  30. <div class="field is-grouped is-grouped-multiline">
  31. {tags.map((tag) => (
  32. <div class="control">
  33. <a class="tags has-addons" href={tag.url}>
  34. <span class="tag">{tag.name}</span>
  35. {showCount ? <span class="tag">{tag.count}</span> : null}
  36. </a>
  37. </div>
  38. ))}
  39. </div>
  40. </div>
  41. </div>
  42. </div>
  43. );
  44. }
  45. }
  46. /**
  47. * Cacheable tags widget JSX component.
  48. * <p>
  49. * This class is supposed to be used in combination with the <code>locals</code> hexo filter
  50. * ({@link module:hexo/filter/locals}).
  51. *
  52. * @see module:util/cache.cacheComponent
  53. * @see https://github.com/hexojs/hexo/blob/4.2.0/lib/plugins/helper/list_tags.js
  54. * @example
  55. * <Tags.Cacheable
  56. * site={{ tags: {...} }}
  57. * helper={{
  58. * url_for: function() {...},
  59. * _p: function() {...}
  60. * }}
  61. * tags={{...}}
  62. * widget={{
  63. * order_by: "name",
  64. * amount: 100,
  65. * show_count: true
  66. * }} />
  67. */
  68. Tags.Cacheable = cacheComponent(Tags, 'widget.tags', (props) => {
  69. const { helper, widget = {} } = props;
  70. const { order_by = 'name', amount, show_count = true } = widget;
  71. let tags = props.tags || props.site.tags;
  72. const { url_for, _p } = helper;
  73. if (!tags || !tags.length) {
  74. return null;
  75. }
  76. tags = tags.sort(order_by).filter((tag) => tag.length);
  77. if (amount) {
  78. tags = tags.limit(amount);
  79. }
  80. return {
  81. showCount: show_count,
  82. title: _p('common.tag', Infinity),
  83. tags: tags.map((tag) => ({
  84. name: tag.name,
  85. count: tag.length,
  86. url: url_for(tag.path),
  87. })),
  88. };
  89. });
  90. module.exports = Tags;