Skip to content

Commit 75d7f1d

Browse files
authored
DEV: Add backward compatibility for tag object arrays (discourse#47)
What is the problem? Discourse core PR #36678 changes `renderTag` to pass tag objects instead of strings to custom tag renderers. This breaks the `iconTagRenderer` function which expects the `tag` parameter to be a string and calls `escapeExpression(tag)` directly. What is the solution? Extract the tag name at the start of `iconTagRenderer` using `typeof tag === "string" ? tag : tag.name` before processing. Also rename the local `tagName` variable to `htmlTagName` to avoid confusion with the extracted tag name. This ensures backward compatibility with both the old string format and the new object format.
1 parent 08b2de3 commit 75d7f1d

3 files changed

Lines changed: 61 additions & 5 deletions

File tree

javascripts/discourse/initializers/tag-icons.js

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,16 @@ function iconTagRenderer(tag, params) {
1111
let tagIconList = settings.tag_icon_list.split("|");
1212

1313
params = params || {};
14-
const visibleName = escapeExpression(tag);
14+
// TODO(https://github.com/discourse/discourse/pull/36678): The string check can be
15+
// removed using .discourse-compatibility once the PR is merged.
16+
const tagStr = typeof tag === "string" ? tag : tag.name;
17+
const visibleName = escapeExpression(tagStr);
1518
tag = visibleName.toLowerCase();
1619

1720
const classes = ["discourse-tag"];
18-
const tagName = params.tagName || "a";
21+
const htmlTagName = params.tagName || "a";
1922
let path;
20-
if (tagName === "a" && !params.noHref) {
23+
if (htmlTagName === "a" && !params.noHref) {
2124
if ((params.isPrivateMessage || params.pmOnly) && currentUser) {
2225
const username = params.tagsForUser
2326
? params.tagsForUser
@@ -64,7 +67,7 @@ function iconTagRenderer(tag, params) {
6467

6568
let val =
6669
"<" +
67-
tagName +
70+
htmlTagName +
6871
href +
6972
" data-tag-name=" +
7073
tag +
@@ -75,7 +78,7 @@ function iconTagRenderer(tag, params) {
7578
tagIconHTML + // inject tag Icon in html
7679
(params.displayName ? escape(params.displayName) : visibleName) +
7780
"</" +
78-
tagName +
81+
htmlTagName +
7982
">";
8083

8184
if (params.count) {
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# frozen_string_literal: true
2+
3+
module PageObjects
4+
module Components
5+
class TagIcon < PageObjects::Components::Base
6+
def has_icon_for_tag?(tag_name:, icon:, color: nil)
7+
selector = ".discourse-tag[data-tag-name='#{tag_name}'] .tag-icon"
8+
selector += "[style*='color: #{color}']" if color
9+
selector += " .d-icon-#{icon}"
10+
page.has_css?(selector)
11+
end
12+
13+
def has_no_icon_for_tag?(tag_name:)
14+
page.has_css?(".discourse-tag[data-tag-name='#{tag_name}']") &&
15+
page.has_no_css?(".discourse-tag[data-tag-name='#{tag_name}'] .tag-icon")
16+
end
17+
end
18+
end
19+
end

spec/system/tag_icons_spec.rb

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# frozen_string_literal: true
2+
3+
require_relative "page_objects/components/tag_icon"
4+
5+
RSpec.describe "Tag icons", type: :system do
6+
fab!(:tag) { Fabricate(:tag, name: "support") }
7+
fab!(:topic) { Fabricate(:topic, tags: [tag]) }
8+
fab!(:post) { Fabricate(:post, topic:) }
9+
fab!(:user)
10+
11+
let(:topic_page) { PageObjects::Pages::Topic.new }
12+
let(:tag_icon) { PageObjects::Components::TagIcon.new }
13+
let!(:theme) { upload_theme_component }
14+
15+
before do
16+
SiteSetting.tagging_enabled = true
17+
theme.update_setting(:tag_icon_list, "support,question-circle,#ff0000")
18+
theme.save!
19+
sign_in(user)
20+
end
21+
22+
it "displays tag with icon on topic page" do
23+
topic_page.visit_topic(topic)
24+
expect(tag_icon).to have_icon_for_tag(tag_name: "support", icon: "question-circle", color: "#ff0000")
25+
end
26+
27+
it "displays tag without icon when not configured" do
28+
theme.update_setting(:tag_icon_list, "")
29+
theme.save!
30+
31+
topic_page.visit_topic(topic)
32+
expect(tag_icon).to have_no_icon_for_tag(tag_name: "support")
33+
end
34+
end

0 commit comments

Comments
 (0)