# Meta标签清理：删除未使用的，删除拼写错误的，添加图标并移动到正确的标签组？

**URL:** <https://meta.discourse.org/t/meta-tag-cleanup-delete-unused-ones-delete-misspelled-ones-add-icons-and-move-to-correct-tag-groups/364105>\
**Category:** Site feedback\
**Tags:** tags\
**Created:** [2025年四月30日 07:09 UTC](https://meta.discourse.org/t/meta-tag-cleanup-delete-unused-ones-delete-misspelled-ones-add-icons-and-move-to-correct-tag-groups/364105 "2025-04-30T07:09:14Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![NateDhaliwal](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/natedhaliwal/32/313494_2.png) [@NateDhaliwal](https://meta.discourse.org/u/NateDhaliwal)\
**Post date:** [2025年四月30日 07:09 UTC](https://meta.discourse.org/t/meta-tag-cleanup-delete-unused-ones-delete-misspelled-ones-add-icons-and-move-to-correct-tag-groups/364105/1 "2025-04-30T07:09:14Z")

</div>

是否可以删除那些最后一次使用是在两年前的标签？

例如，#size-s、#size-m、（甚至未使用过）#size-l 和（也从未用过）#size-xl。

然后，还有一些标签拼写错误。例如 #phbb，这似乎是 #phpbb 的错误。

此外，#hcaptcha 似乎没有图标，并且被放置在“其他标签”标签组中，而不是“官方插件”标签组中。此外，#graphviz 缺少图标，而 #topic-list-author 位于“其他标签”标签组中，而不是“官方主题组件”标签组中。

#horizon-theme 缺少图标，#discourse-translator 标签存在没有意义，因为 #translator 标签已经存在。

等等！还有更多。#ai-artifacts 和 #ai-custom-prompt 被放置在“其他标签”标签组中，而它们应该放在“Discourse AI Features”标签组中。此外，#sidebar-tags 标签位于“官方插件”标签组中，而不是“官方主题组件”标签组中。

如果这过于吹毛求疵，我提前道歉。

---

<div class="post-metadata">

**Author:** ![Lilly](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/lilly/32/575047_2.png) [@Lilly](https://meta.discourse.org/u/Lilly)\
**Post date:** [2025年四月30日 11:56 UTC](https://meta.discourse.org/t/meta-tag-cleanup-delete-unused-ones-delete-misspelled-ones-add-icons-and-move-to-correct-tag-groups/364105/2 "2025-04-30T11:56:32Z")

</div>

您觉得从未使用过的一些标签实际上在私有类别中被使用了。不过，是的，标签需要一些维护。谢谢。

---

<div class="post-metadata">

**Author:** ![tobiaseigen](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/tobiaseigen/32/539204_2.png) [@tobiaseigen](https://meta.discourse.org/u/tobiaseigen)\
**Post date:** [2025年四月30日 13:01 UTC](https://meta.discourse.org/t/meta-tag-cleanup-delete-unused-ones-delete-misspelled-ones-add-icons-and-move-to-correct-tag-groups/364105/6 "2025-04-30T13:01:57Z")

</div>

谢谢你，内特！感谢你注重细节。正如莉莉所说，许多标签的使用方式对公众不可见。在私有类别和与客户的私人消息中。我期待着为 `/tags` 页面带来一些秩序！

我刚尝试将 `#phpbb` 添加到当前标记为 `#phbb` 的主题中，但不知何故不起作用。这很奇怪。`#phpbb` 在 Migrations 标签组中，但该标签组不限制谁可以使用该标签。

---

<div class="post-metadata">

**Author:** ![NateDhaliwal](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/natedhaliwal/32/313494_2.png) [@NateDhaliwal](https://meta.discourse.org/u/NateDhaliwal)\
**Post date:** [2025年四月30日 13:38 UTC](https://meta.discourse.org/t/meta-tag-cleanup-delete-unused-ones-delete-misspelled-ones-add-icons-and-move-to-correct-tag-groups/364105/7 "2025-04-30T13:38:02Z")

</div>

我明白了。感谢澄清@Lilly @tobiaseigen！

---

<div class="post-metadata">

**Author:** ![NateDhaliwal](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/natedhaliwal/32/313494_2.png) [@NateDhaliwal](https://meta.discourse.org/u/NateDhaliwal)\
**Post date:** [2026年四月20日 11:10 UTC](https://meta.discourse.org/t/meta-tag-cleanup-delete-unused-ones-delete-misspelled-ones-add-icons-and-move-to-correct-tag-groups/364105/8 "2026-04-20T11:10:09Z")

</div>

又回到这个话题了 👀。

Meta 上有很多标签是“对所有人可见，但仅限工作人员使用（我猜）”，因此它们会出现在标签选择器中（例如输入 ‘qu’ 会显示 #quest 和 #basic-downgraderequest 等标签）。不过，我推测这些标签实际上并不需要让社区其他成员看到，仅供内部使用。那么，将这些标签仅对内部组可见而不是对所有人可见，是否更合理呢？还是说这样做有特定的理由？

谢谢。

---

<div class="post-metadata">

**Author:** ![Canapin](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/canapin/32/119591_2.png) [@Canapin](https://meta.discourse.org/u/Canapin)\
**Post date:** [2026年四月20日 11:15 UTC](https://meta.discourse.org/t/meta-tag-cleanup-delete-unused-ones-delete-misspelled-ones-add-icons-and-move-to-correct-tag-groups/364105/9 "2026-04-20T11:15:33Z")

</div>

另外，#revision-needed 标签目前没有任何主题使用。也许它仅用于私密内容，但出于某些原因，该标签却是公开可见的。

---

<div class="post-metadata">

**Author:** ![chapoi](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/chapoi/32/537252_2.png) [@chapoi](https://meta.discourse.org/u/chapoi)\
**Post date:** [2026年四月20日 11:32 UTC](https://meta.discourse.org/t/meta-tag-cleanup-delete-unused-ones-delete-misspelled-ones-add-icons-and-move-to-correct-tag-groups/364105/10 "2026-04-20T11:32:36Z")

</div>

那确实是一个私有标签。我不确定我们能否为 @mcwumbly 设置范围，因为只有员工和企业需要访问权限。

---

<div class="post-metadata">

**Author:** ![Lilly](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/lilly/32/575047_2.png) [@Lilly](https://meta.discourse.org/u/Lilly)\
**Post date:** [2026年四月20日 12:27 UTC](https://meta.discourse.org/t/meta-tag-cleanup-delete-unused-ones-delete-misspelled-ones-add-icons-and-move-to-correct-tag-groups/364105/11 "2026-04-20T12:27:54Z")

</div>

有一些私有标签正在泄露

 ![IMG5153](https://global.discourse-cdn.com/meta/original/4X/d/c/2/dc22d426b3dd016302fc76abb03c991a61a83a48.jpeg)

---

<div class="post-metadata">

**Author:** ![chapoi](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/chapoi/32/537252_2.png) [@chapoi](https://meta.discourse.org/u/chapoi)\
**Post date:** [2026年四月20日 12:50 UTC](https://meta.discourse.org/t/meta-tag-cleanup-delete-unused-ones-delete-misspelled-ones-add-icons-and-move-to-correct-tag-groups/364105/12 "2026-04-20T12:50:34Z")

</div>

我不认为它们是“私密”的，因为你能看到它们，这本身是个问题。它们在这方面并不敏感。

但我同意，为了普通用户的体验，最好不要让它们显示出来，这是当然的。

---

<div class="post-metadata">

**Author:** ![Lilly](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/lilly/32/575047_2.png) [@Lilly](https://meta.discourse.org/u/Lilly)\
**Post date:** [2026年四月20日 12:52 UTC](https://meta.discourse.org/t/meta-tag-cleanup-delete-unused-ones-delete-misspelled-ones-add-icons-and-move-to-correct-tag-groups/364105/13 "2026-04-20T12:52:27Z")

</div>

如果某个标签在功能上被列为受限标签，那么无论数据本身有多敏感，未经授权的成员都不应在用户界面中看到它。

---

<div class="post-metadata">

**Author:** ![zogstrip](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/zogstrip/32/512781_2.png) [@zogstrip](https://meta.discourse.org/u/zogstrip)\
**Post date:** [2026年四月20日 14:00 UTC](https://meta.discourse.org/t/meta-tag-cleanup-delete-unused-ones-delete-misspelled-ones-add-icons-and-move-to-correct-tag-groups/364105/14 "2026-04-20T14:00:51Z")

</div>

> [@Lilly](#):
>
> 如果一个标签在功能上被列为受限，那么未授权成员绝不应在用户界面中看到它。

即时教学总是在以下两者之间保持微妙的平衡：一方面，不向用户显示他们知道存在但因“某些原因”无法使用的标签，可能会让用户感到困惑；另一方面，向用户灌输他们无法采取任何行动的信息，又会让他们感到信息过载。🤔

我会看看能否改善这些标签的用户体验。👀

---

<div class="post-metadata">

**Author:** ![Lilly](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/lilly/32/575047_2.png) [@Lilly](https://meta.discourse.org/u/Lilly)\
**Post date:** [2026年四月20日 14:58 UTC](https://meta.discourse.org/t/meta-tag-cleanup-delete-unused-ones-delete-misspelled-ones-add-icons-and-move-to-correct-tag-groups/364105/16 "2026-04-20T14:58:37Z")

</div>

> [@zogstrip](#):
>
> 明明知道某个标签存在，却因为“某些原因”无法使用，却又不显示该标签。

哈哈，很遗憾我完全不知道 meta 上居然有这个标签（我本来应该知道的 😅）。我当时只是在随机输入一些单词，看看会出现什么结果。

但即使寻找合法的标签——例如在 meta 上开始输入“social”：

 ![Screenshot 2026-04-20 at 7.08.21 AM](https://global.discourse-cdn.com/meta/original/4X/b/a/a/baa60739d27c672102dee5806e92d2ea000530f5.png)

问题在于，我不理解当前的功能逻辑。为什么要向没有权限的用户显示那些仅限于安全类别的标签的存在呢？

作为管理员，如果我在类别设置页面将某个标签限制为仅在特定类别中使用（`将这些标签限制在'X'类别` 和 `将这些标签组限制在'X'类别`），那么我预期这些标签会遵循类别权限。也就是说，只有拥有该类别权限的用户才能在任何地方看到该标签（无论 `允许查看标签的主题组` 如何设置，或者即使用户仍然无法看到带有该标签的任何主题）。

 ![Screenshot 2026-04-20 at 7.49.24 AM](https://global.discourse-cdn.com/meta/original/4X/6/6/3/663fbf11457b9ca0b9447abeb476dc88e4636de0.png)

我明白措辞是“可用”而不是“可见”，但这仍然让我觉得奇怪。当然，`bots-gone-mad` 这个标签也可以被没有该类别权限的用户在多个地方看到。

 ![Screenshot 2026-04-20 at 7.51.24 AM](https://global.discourse-cdn.com/meta/original/4X/5/a/2/5a20c9c07713bcff435cd8f0bc62b9896c899ecd.png)

 ![Screenshot 2026-04-20 at 7.51.55 AM](https://global.discourse-cdn.com/meta/original/4X/e/1/b/e1b23a27796832337d76b5d85e12ab69e02c8b1d.png)

因此，目前的情况是，即使标签被限制在安全类别中，管理员也必须被告知不要在安全类别中创建敏感标签，因为这些标签仍可能被未授权用户（或至少不是这些标签 intended 的用户）发现。

标签功能还是挺有趣的 🙂

---

<div class="post-metadata">

**Author:** ![zogstrip](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/zogstrip/32/512781_2.png) [@zogstrip](https://meta.discourse.org/u/zogstrip)\
**Post date:** [2026年四月20日 15:03 UTC](https://meta.discourse.org/t/meta-tag-cleanup-delete-unused-ones-delete-misspelled-ones-add-icons-and-move-to-correct-tag-groups/364105/17 "2026-04-20T15:03:13Z")

</div>

> [@Lilly](#):
>
> 为什么还要向未授权用户显示仅限安全分类的标签的存在？

是的，逻辑完全可能并非“100%”正确，因此某些标签在不该显示的时候被显示了。这就是为什么我正在检查这个问题。

---

<div class="post-metadata">

**Author:** ![zogstrip](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/zogstrip/32/512781_2.png) [@zogstrip](https://meta.discourse.org/u/zogstrip)\
**Post date:** [2026年四月23日 09:28 UTC](https://meta.discourse.org/t/meta-tag-cleanup-delete-unused-ones-delete-misspelled-ones-add-icons-and-move-to-correct-tag-groups/364105/18 "2026-04-23T09:28:24Z")

</div>

希望我全都找到了 😅

> <https://github.com/discourse/discourse/pull/39399>
>
> Tag search (\`/tags/filter/search\`) was not fully consistent with category-based …tag visibility. A tag restricted to a private category via \`CategoryTag\` or \`CategoryTagGroup\` could still appear in several of the endpoint's outputs for users who did not have access to that category: as a disabled entry with an explanation in the composer autocomplete, as a regular allowed result when the tag filter dropdown on topic lists queried without \`filterForInput\`, or as a \`forbidden\_message\` when the exact tag name was typed. The missing-parent-tag reason could include a parent tag name even when the parent itself was restricted to a category the viewer could not access, and the synonym-exclusion reason could include the synonym's target name without checking whether the target was itself visible. The serialized tag payload also included the \`target\_tag: { id, name, slug }\` field for every synonym regardless of target visibility, and \`fetch\_category\` resolved any \`categoryId\` the caller passed without checking visibility, which made the behaviour for an invisible existing category distinguishable from the behaviour for a non-existent one. Finally, the fallback disabled-tag reason always said "cannot be used in this category" even when the request had no category context at all.
> 
> The underlying cause is that "visibility" in \`DiscourseTagging\` was defined purely in terms of \`TagGroupPermission\` and ignored category access entirely, so each code path in \`Tags::Search\` was relying on its own partial checks (or none). Most of the behaviour is long-standing; the disabled-entries path in autocomplete is a regression from #39072, but the others have been in place for years.
> 
> The fix redefines visibility to include category access and routes every tag-search code path through that single definition.
> 
> \`DiscourseTagging.visible\_tags\` now composes a new \`filter\_visible\_in\_accessible\_categories\` helper on top of the existing tag-group-permission check: a tag is kept only if it has no category restriction, or if at least one of its restrictions points to a category in \`guardian.allowed\_category\_ids\`. The helper is a single \`WHERE\` clause with one named bind reused twice.
> 
> \`DiscourseTagging.filter\_allowed\_tags\` enforces this visibility in-SQL by adding \`t.id IN (visible\_tags subquery)\` to its builder for non-admin callers. That single subquery subsumes the narrower hidden-tag-group \`EXCEPT\` block the method used to build, so the whole filter is now one trip to the database instead of being post-filtered in Ruby.
> 
> \`Tags::Search\` steps all flow through the new visibility universe. \`search\_tags\` inherits the guarantee through \`filter\_allowed\_tags\`. \`append\_disabled\_tags\` and \`detect\_forbidden\_tag\` both start from \`DiscourseTagging.filter\_visible(Tag.all, guardian)\` via a private \`visible\_tags\` helper, so neither can surface a tag outside the user's scope. \`fetch\_category\` intersects the requested id with \`guardian.allowed\_category\_ids\` and returns \`nil\` otherwise, so categories the caller cannot see are treated the same as categories that do not exist.
> 
> \`explain\_exclusion\` gates its two name-surfacing branches on visibility: the synonym-exclusion reason is only emitted when the target tag is visible, and the missing-parent-tag reason is only emitted when the parent tag is visible. When neither of those reasons (nor any category-based reason) applies, the fallback now picks between \`tags.forbidden.in\_this\_category\` (when \`params.categoryId\` is present) and a new \`tags.forbidden.not\_allowed\` wording (when it is not), so the message matches the actual context of the request.
> 
> \`TagsController.tag\_counts\_json\` filters the \`target\_tags\` lookup through \`DiscourseTagging.filter\_visible\`, so synonyms whose targets are invisible no longer carry a \`target\_tag\` field in the payload. This benefits every caller of \`tag\_counts\_json\` (search, tag index, tag show, the hashtag data source, and the detailed tag serializer), not just the tag search endpoint.
> 
> The accompanying specs cover each path both positively and negatively: admins and authorized users still see their tags, partial matches still return disabled entries with the right reason, exact matches still produce \`forbidden\_message\` for tags the user can see; unauthorized users, anonymous users, invisible-category probes, synonym payloads, and parent-tag reasons are all verified not to surface anything outside the user's scope.
> 
> Ref - t/364105
