Skip to content

Commit

Permalink
FEATURE: display category icon in post body
Browse files Browse the repository at this point in the history
This commit allows displaying category icons in the body of the post.

Related meta topic: https://meta.discourse.org/t/category-icons-dont-show-up-in-post-text/315851
  • Loading branch information
Lhcfl committed Jul 15, 2024
1 parent 1df45ac commit bf972b9
Show file tree
Hide file tree
Showing 3 changed files with 139 additions and 0 deletions.
47 changes: 47 additions & 0 deletions javascripts/discourse/initializers/category-icons.js
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,53 @@ export default {
}
});
}

if (settings.render_category_icon_in_post) {
const site = api.container.lookup("service:site");
const slugMap = {};
for (const str of categoryThemeList) {
const [slug, icon, color, match] = str.split(",");
if (slug && icon) {
for (const cat of site.categories) {
if (match === "partial") {
if (!cat.slug.toLowerCase().includes(slug.toLowerCase())) {
continue;
}
} else {
if (cat.slug.toLowerCase() !== slug.toLowerCase()) {
continue;
}
}
const opts = {
icon,
color,
};
if (!color || color?.match(/categoryColo(u*)r/g)) {
opts.color = `#${cat.color}`;
}
slugMap[cat.slug.toLowerCase()] = opts;
}
}
}
api.decorateCookedElement((elem) => {
const categorgHashtags = elem.querySelectorAll(
'.hashtag-cooked[data-type="category"]'
);
for (const hashtag of categorgHashtags) {
const opt = slugMap[hashtag.dataset?.slug?.toLowerCase()];
if (!opt) {
continue;
}
const newIcon = document.createElement("span");
newIcon.classList.add("hashtag-category-icon");
newIcon.innerHTML = iconHTML(opt.icon);
newIcon.style.color = opt.color;
hashtag
.querySelector("span.hashtag-category-badge")
?.replaceWith(newIcon);
}
});
}
});
},
};
3 changes: 3 additions & 0 deletions settings.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ category_icon_list:
type: "list"
list_type: "simple"
description: 'Enter comma-delimited configuration for categories, in the format "slug,icon,color,match". Color can be in hex format (#123456) or left blank, then the default color for the category is used (same as the Badge color). If match is "partial" then the slug need only partially match the category-slug, otherwise an exact match is required'
render_category_icon_in_post:
default: true
description: "Show category icons in the post body"
svg_icons:
default: "question-circle"
type: "list"
Expand Down
89 changes: 89 additions & 0 deletions test/acceptance/post-body-category-icons-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import { visit } from "@ember/test-helpers";
import { test } from "qunit";
import TopicFixtures from "discourse/tests/fixtures/topic";
import { acceptance } from "discourse/tests/helpers/qunit-helpers";
import { cloneJSON } from "discourse-common/lib/object";

function makeHashtagHTML(category) {
return `<a class=\"hashtag-cooked\" href=\"${category.href}\" data-type=\"category\" data-slug=\"${category.slug}\" data-id=\"${category.id}\"><span class=\"hashtag-icon-placeholder\"><svg class=\"fa d-icon d-icon-square-full svg-icon svg-node\"><use href=\"#square-full\"></use></svg></span><span>${category.name}</span></a>`;
}

acceptance("Post body - Category icons", function (needs) {
needs.user();

const categories = [
{
id: 1,
name: "Category 1",
slug: "category-1",
color: "111111",
},
{
id: 2,
name: "Category 2",
slug: "category-2",
color: "000000",
},
{
id: 3,
name: "Category 3",
slug: "category-3",
color: "888888",
},
];

needs.site({
categories,
});

needs.hooks.beforeEach(function () {
settings.category_lock_icon = "wrench";
settings.category_icon_list = `category-1,wrench,#FF0000|category-2,question-circle,categoryColor`;
});

needs.pretender((server, helper) => {
server.get("/t/131.json", () => {
const topicList = cloneJSON(TopicFixtures["/t/130.json"]);
topicList.post_stream.posts[0].cooked = `<p>${makeHashtagHTML(
categories[0]
)} ${makeHashtagHTML(categories[1])} ${makeHashtagHTML(
categories[2]
)}</p>`;
return helper.response(topicList);
});
});

test("Icon for category when `category_icon_list` theme setting has been configured", async function (assert) {
await visit("/t/131");

assert
.dom(
`.cooked .hashtag-cooked[data-id="1"] .hashtag-category-icon .d-icon-wrench`
)
.exists("wrench icon is displayed for category-1");

assert
.dom(`.cooked .hashtag-cooked[data-id="1"] .hashtag-category-icon`)
.hasStyle(
{ color: "rgb(255, 0, 0)" },
"category-1 's icon has the right color"
);

assert
.dom(
`.cooked .hashtag-cooked[data-id="2"] .hashtag-category-icon .d-icon-question-circle`
)
.exists("question-circle icon is displayed for category-2");

assert
.dom(`.cooked .hashtag-cooked[data-id="2"] .hashtag-category-icon`)
.hasStyle(
{ color: "rgb(0, 0, 0)" },
"category-2 's icon has the right categoryColor"
);

assert
.dom(`.cooked .hashtag-cooked[data-id="3"] .hashtag-category-badge`)
.exists("unconfigured categories have a default badge");
});
});

0 comments on commit bf972b9

Please sign in to comment.