diff --git a/app/assets/javascripts/discourse/controllers/tags-index.js.es6 b/app/assets/javascripts/discourse/controllers/tags-index.js.es6
index 07a9da7cfed..545bf7b21ec 100644
--- a/app/assets/javascripts/discourse/controllers/tags-index.js.es6
+++ b/app/assets/javascripts/discourse/controllers/tags-index.js.es6
@@ -1,7 +1,20 @@
+import computed from 'ember-addons/ember-computed-decorators';
+
export default Ember.Controller.extend({
sortProperties: ['count:desc', 'id'],
canAdminTags: Ember.computed.alias("currentUser.staff"),
+ groupedByCategory: Ember.computed.notEmpty('model.extras.categories'),
+ groupedByTagGroup: Ember.computed.notEmpty('model.extras.tag_groups'),
+
+ @computed('groupedByCategory', 'groupedByTagGroup')
+ otherTagsTitleKey(groupedByCategory, groupedByTagGroup) {
+ if (!groupedByCategory && !groupedByTagGroup) {
+ return 'tagging.all_tags';
+ } else {
+ return 'tagging.other_tags';
+ }
+ },
actions: {
sortByCount() {
diff --git a/app/assets/javascripts/discourse/templates/components/tag-list.hbs b/app/assets/javascripts/discourse/templates/components/tag-list.hbs
index a3e912d26ca..9c791cf25d7 100644
--- a/app/assets/javascripts/discourse/templates/components/tag-list.hbs
+++ b/app/assets/javascripts/discourse/templates/components/tag-list.hbs
@@ -4,6 +4,9 @@
{{#if category}}
{{category-title-link category=category}}
{{/if}}
+{{#if tagGroupName}}
+
{{tagGroupName}}
+{{/if}}
{{#each sortedTags as |tag|}}
{{#if tag.count}}
diff --git a/app/assets/javascripts/discourse/templates/tags/index.hbs b/app/assets/javascripts/discourse/templates/tags/index.hbs
index 1cf1beb970b..1036b77bc77 100644
--- a/app/assets/javascripts/discourse/templates/tags/index.hbs
+++ b/app/assets/javascripts/discourse/templates/tags/index.hbs
@@ -23,4 +23,8 @@
{{tag-list tags=category.tags sortProperties=sortProperties categoryId=category.id}}
{{/each}}
-{{tag-list tags=model sortProperties=sortProperties titleKey="tagging.all_tags"}}
+{{#each model.extras.tag_groups as |tagGroup|}}
+ {{tag-list tags=tagGroup.tags sortProperties=sortProperties tagGroupName=tagGroup.name}}
+{{/each}}
+
+{{tag-list tags=model sortProperties=sortProperties titleKey=otherTagsTitleKey}}
diff --git a/app/controllers/tags_controller.rb b/app/controllers/tags_controller.rb
index 54115945e06..b65d54ae0c9 100644
--- a/app/controllers/tags_controller.rb
+++ b/app/controllers/tags_controller.rb
@@ -19,30 +19,60 @@ class TagsController < ::ApplicationController
before_action :set_category_from_params, except: [:index, :update, :destroy, :tag_feed, :search, :notifications, :update_notifications]
def index
- categories = Category.where("id in (select category_id from category_tags)")
- .where("id in (?)", guardian.allowed_category_ids)
- .preload(:tags)
- category_tag_counts = categories.map do |c|
- h = Tag.category_tags_by_count_query(c, limit: 300).count(Tag::COUNT_ARG)
- h.merge!(c.tags.where.not(name: h.keys).inject({}) { |sum, t| sum[t.name] = 0; sum }) # unused tags
- { id: c.id, tags: self.class.tag_counts_json(h) }
- end
-
- tag_counts = self.class.tags_by_count(guardian, limit: 300).count(Tag::COUNT_ARG)
- @tags = self.class.tag_counts_json(tag_counts)
-
@description_meta = I18n.t("tags.title")
@title = @description_meta
respond_to do |format|
+
format.html do
+ tag_counts = self.class.tags_by_count(guardian, limit: 300).count(Tag::COUNT_ARG)
+ @tags = self.class.tag_counts_json(tag_counts)
render :index
end
+
format.json do
- render json: {
- tags: @tags,
- extras: { categories: category_tag_counts }
- }
+ if SiteSetting.tags_listed_by_group
+ # TODO: performance is bad
+ grouped_tag_counts = TagGroup.order('name ASC').preload(:tags).map do |tag_group|
+ h = Tag.tags_by_count_query(limit: 300)
+ .joins("LEFT JOIN tag_group_memberships ON tags.id = tag_group_memberships.tag_id")
+ .where('tag_group_memberships.tag_group_id = ?', tag_group.id)
+ .count(Tag::COUNT_ARG)
+ { id: tag_group.id, name: tag_group.name, tags: self.class.tag_counts_json(h) }
+ end
+
+ ungrouped_tag_counts = guardian.filter_allowed_categories(
+ Tag.tags_by_count_query(limit: 300)
+ .where("tags.id NOT IN (select tag_id from tag_group_memberships)")
+ .count(Tag::COUNT_ARG)
+ )
+
+ render json: {
+ tags: self.class.tag_counts_json(ungrouped_tag_counts), # tags that don't belong to a group
+ extras: { tag_groups: grouped_tag_counts }
+ }
+ else
+ unrestricted_tag_counts = guardian.filter_allowed_categories(
+ Tag.tags_by_count_query(limit: 300)
+ .where("tags.id NOT IN (select tag_id from category_tags)")
+ .count(Tag::COUNT_ARG)
+ )
+
+ categories = Category.where("id in (select category_id from category_tags)")
+ .where("id in (?)", guardian.allowed_category_ids)
+ .preload(:tags)
+
+ category_tag_counts = categories.map do |c|
+ h = Tag.category_tags_by_count_query(c, limit: 300).count(Tag::COUNT_ARG)
+ h.merge!(c.tags.where.not(name: h.keys).inject({}) { |sum, t| sum[t.name] = 0; sum }) # unused tags
+ { id: c.id, tags: self.class.tag_counts_json(h) }
+ end
+
+ render json: {
+ tags: self.class.tag_counts_json(unrestricted_tag_counts),
+ extras: { categories: category_tag_counts }
+ }
+ end
end
end
end
diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml
index 4af1df836d7..ede17d1af9b 100644
--- a/config/locales/client.en.yml
+++ b/config/locales/client.en.yml
@@ -2507,6 +2507,7 @@ en:
tagging:
all_tags: "All Tags"
+ other_tags: "Other Tags"
selector_all_tags: "all tags"
selector_no_tags: "no tags"
changed: "tags changed:"
diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml
index b55a7364b0e..04a9b1bb849 100644
--- a/config/locales/server.en.yml
+++ b/config/locales/server.en.yml
@@ -1584,6 +1584,7 @@ en:
show_filter_by_tag: "Show a dropdown to filter a topic list by tag."
max_tags_in_filter_list: "Maximum number of tags to show in the filter dropdown. The most used tags will be shown."
tags_sort_alphabetically: "Show tags in alphabetical order. Default is to show in order of popularity."
+ tags_listed_by_group: "List tags by tag group on the Tags page (/tags)."
tag_style: "Visual style for tag badges."
staff_tags: "A list of tags that can only be applied by staff members"
min_trust_level_to_tag_topics: "Minimum trust level required to tag topics"
diff --git a/config/site_settings.yml b/config/site_settings.yml
index 9ea097e0acf..00d579e71c0 100644
--- a/config/site_settings.yml
+++ b/config/site_settings.yml
@@ -1521,6 +1521,9 @@ tags:
client: true
default: false
refresh: true
+ tags_listed_by_group:
+ client: true
+ default: false
staff_tags:
type: list
client: true