FEATURE: clean up tags extensibility

centralizes all logic for topic tag rendering and provides API for extension
This commit is contained in:
Sam 2017-02-28 17:07:51 -05:00
parent d27575176a
commit f918951d42
7 changed files with 74 additions and 41 deletions

View File

@ -0,0 +1,6 @@
import { registerUnbound } from 'discourse-common/lib/helpers';
import renderTags from 'discourse/lib/render-tags';
export default registerUnbound('discourse-tags', function(topic, params) {
return new Handlebars.SafeString(renderTags(topic, params));
});

View File

@ -14,9 +14,10 @@ import { addPopupMenuOptionsCallback } from 'discourse/controllers/composer';
import { extraConnectorClass } from 'discourse/lib/plugin-connectors'; import { extraConnectorClass } from 'discourse/lib/plugin-connectors';
import { addPostSmallActionIcon } from 'discourse/widgets/post-small-action'; import { addPostSmallActionIcon } from 'discourse/widgets/post-small-action';
import { addDiscoveryQueryParam } from 'discourse/controllers/discovery-sortable'; import { addDiscoveryQueryParam } from 'discourse/controllers/discovery-sortable';
import { addTagsHtmlCallback } from 'discourse/lib/render-tags';
// If you add any methods to the API ensure you bump up this number // If you add any methods to the API ensure you bump up this number
const PLUGIN_API_VERSION = '0.8.1'; const PLUGIN_API_VERSION = '0.8.2';
class PluginApi { class PluginApi {
constructor(version, container) { constructor(version, container) {
@ -387,6 +388,21 @@ class PluginApi {
addDiscoveryQueryParam(param, options) { addDiscoveryQueryParam(param, options) {
addDiscoveryQueryParam(param, options); addDiscoveryQueryParam(param, options);
} }
/**
* Register a callback to be called every time tags render
* example:
*
* callback = function(topic, params) {
* if (topic.get("created_at") < "2000-00-01") {
* return "<span class='discourse-tag'>ANCIENT</span>"
* }
* }
*
**/
addTagsHtmlCallback(callback) {
addTagsHtmlCallback(callback);
};
} }
let _pluginv01; let _pluginv01;

View File

@ -1,5 +1,3 @@
import { h } from 'virtual-dom';
export default function renderTag(tag, params) { export default function renderTag(tag, params) {
params = params || {}; params = params || {};
tag = Handlebars.Utils.escapeExpression(tag); tag = Handlebars.Utils.escapeExpression(tag);
@ -19,19 +17,3 @@ export default function renderTag(tag, params) {
return val; return val;
}; };
export function tagNode(tag, params) {
const classes = ['tag-' + tag, 'discourse-tag'];
const tagName = params.tagName || "a";
if (Discourse.SiteSettings.tag_style || params.style) {
classes.push(params.style || Discourse.SiteSettings.tag_style);
}
if (tagName === 'a') {
const href = Discourse.getURL(`/tags/${tag}`);
return h(tagName, { className: classes.join(' '), attributes: { href } }, tag);
} else {
return h(tagName, { className: classes.join(' ') }, tag);
}
}

View File

@ -0,0 +1,45 @@
import renderTag from 'discourse/lib/render-tag';
let callbacks = null;
export function addTagsHtmlCallback(callback) {
callbacks = callbacks || [];
callbacks.push(callback);
};
export default function(topic, params){
let tags = topic.tags;
let buffer = "";
if (params && params.mode === "list") {
tags = topic.get("visibleListTags");
}
let customHtml = null;
if (callbacks) {
callbacks.forEach((c) => {
const html = c(topic, params);
if (html) {
if (customHtml) {
customHtml += html;
} else {
customHtml = html;
}
}
});
}
if (customHtml || (tags && tags.length > 0)) {
buffer = "<div class='discourse-tags'>";
if (tags) {
for(var i=0; i<tags.length; i++){
buffer += renderTag(tags[i]);
}
if (customHtml) {
buffer += customHtml;
}
}
buffer += "</div>";
}
return buffer;
};

View File

@ -19,13 +19,7 @@
</tr> </tr>
<tr> <tr>
{{category-link topic.category}} {{category-link topic.category}}
{{#if topic.tags}} {{discourse-tags topic mode="list"}}
<div class="discourse-tags">
{{#each topic.visibleListTags as |tag|}}
{{discourse-tag tag}}
{{/each}}
</div>
{{/if}}
</tr> </tr>
</td> </td>
<td class="topic-stats"> <td class="topic-stats">

View File

@ -18,15 +18,7 @@
{{/if}} {{/if}}
</span> </span>
{{#if topic.tags}} {{discourse-tags topic mode="list"}}
<div class='discourse-tags'>
{{#each topic.visibleListTags as |tag|}}
{{discourse-tag tag}}
{{/each}}
{{raw-plugin-outlet name="topic-list-custom-tags"}}
</div>
{{/if}}
{{raw-plugin-outlet name="topic-list-tags"}}
{{#if expandPinned}} {{#if expandPinned}}
{{raw "list/topic-excerpt" topic=topic}} {{raw "list/topic-excerpt" topic=topic}}
{{/if}} {{/if}}

View File

@ -3,7 +3,7 @@ import { h } from 'virtual-dom';
import { iconNode } from 'discourse/helpers/fa-icon-node'; import { iconNode } from 'discourse/helpers/fa-icon-node';
import DiscourseURL from 'discourse/lib/url'; import DiscourseURL from 'discourse/lib/url';
import RawHtml from 'discourse/widgets/raw-html'; import RawHtml from 'discourse/widgets/raw-html';
import { tagNode } from 'discourse/lib/render-tag'; import renderTags from 'discourse/lib/render-tags';
import { topicFeaturedLinkNode } from 'discourse/lib/render-topic-featured-link'; import { topicFeaturedLinkNode } from 'discourse/lib/render-topic-featured-link';
export default createWidget('header-topic-info', { export default createWidget('header-topic-info', {
@ -46,11 +46,9 @@ export default createWidget('header-topic-info', {
} }
let extra = []; let extra = [];
if (this.siteSettings.tagging_enabled) { const tags = renderTags(topic);
const tags = topic.get('tags') || []; if (tags && tags.length > 0) {
if (tags.length) { extra.push(new RawHtml({html: tags}));
extra.push(h('div.list-tags', tags.map(tagNode)));
}
} }
extra = extra.concat(applyDecorators(this, 'after-tags', attrs, state)); extra = extra.concat(applyDecorators(this, 'after-tags', attrs, state));