mirror of
https://github.com/discourse/discourse.git
synced 2025-02-25 18:55:32 -06:00
FEATURE: Mixed case tagging (#6454)
- By default, behaviour is not changed: tags are made lowercase upon creation and edit. - If force_lowercase_tags is disabled, then mixed case tags are allowed. - Tags must remain case-insensitively unique. This is enforced by ActiveRecord and Postgres. - A migration is added to provide a `UNIQUE` index on `lower(name)`. Migration includes a safety to correct any current tags that do not meet the criteria. - A `where_name` scope is added to `models/tag.rb`, to allow easy case-insensitive lookups. This is used instead of `Tag.where(name: "blah")`. - URLs remain lowercase. Mixed case URLs are functional, but have the lowercase equivalent as the canonical.
This commit is contained in:
@@ -39,7 +39,7 @@ module DiscourseTagging
|
||||
# guardian is explicitly nil cause we don't want to strip all
|
||||
# staff tags that already passed validation
|
||||
tags = filter_allowed_tags(
|
||||
Tag.where(name: tag_names),
|
||||
Tag.where_name(tag_names),
|
||||
nil, # guardian
|
||||
for_topic: true,
|
||||
category: category,
|
||||
@@ -48,7 +48,7 @@ module DiscourseTagging
|
||||
|
||||
if tags.size < tag_names.size && (category.nil? || (category.tags.count == 0 && category.tag_groups.count == 0))
|
||||
tag_names.each do |name|
|
||||
unless Tag.where(name: name).exists?
|
||||
unless Tag.where_name(name).exists?
|
||||
tags << Tag.create(name: name)
|
||||
end
|
||||
end
|
||||
@@ -82,8 +82,7 @@ module DiscourseTagging
|
||||
# for_topic: results are for tagging a topic
|
||||
# selected_tags: an array of tag names that are in the current selection
|
||||
def self.filter_allowed_tags(query, guardian, opts = {})
|
||||
|
||||
selected_tag_ids = opts[:selected_tags] ? Tag.where(name: opts[:selected_tags]).pluck(:id) : []
|
||||
selected_tag_ids = opts[:selected_tags] ? Tag.where_name(opts[:selected_tags]).pluck(:id) : []
|
||||
|
||||
if !opts[:for_topic] && !selected_tag_ids.empty?
|
||||
query = query.where('tags.id NOT IN (?)', selected_tag_ids)
|
||||
@@ -92,8 +91,8 @@ module DiscourseTagging
|
||||
term = opts[:term]
|
||||
if term.present?
|
||||
term.gsub!("_", "\\_")
|
||||
term = clean_tag(term)
|
||||
query = query.where('tags.name like ?', "%#{term}%")
|
||||
term = clean_tag(term).downcase
|
||||
query = query.where('lower(tags.name) like ?', "%#{term}%")
|
||||
end
|
||||
|
||||
# Filters for category-specific tags:
|
||||
@@ -203,7 +202,8 @@ module DiscourseTagging
|
||||
end
|
||||
|
||||
def self.clean_tag(tag)
|
||||
tag.downcase.strip
|
||||
tag.downcase! if SiteSetting.force_lowercase_tags
|
||||
tag.strip
|
||||
.gsub(/\s+/, '-').squeeze('-')
|
||||
.gsub(TAGS_FILTER_REGEXP, '')[0...SiteSetting.max_tag_length]
|
||||
end
|
||||
@@ -212,7 +212,7 @@ module DiscourseTagging
|
||||
|
||||
return [] unless guardian.can_tag_topics? && tags_arg.present?
|
||||
|
||||
tag_names = Tag.where(name: tags_arg).pluck(:name)
|
||||
tag_names = Tag.where_name(tags_arg).pluck(:name)
|
||||
|
||||
if guardian.can_create_tag?
|
||||
tag_names += (tags_arg - tag_names).map { |t| clean_tag(t) }
|
||||
@@ -226,7 +226,7 @@ module DiscourseTagging
|
||||
def self.add_or_create_tags_by_name(taggable, tag_names_arg, opts = {})
|
||||
tag_names = DiscourseTagging.tags_for_saving(tag_names_arg, Guardian.new(Discourse.system_user), opts) || []
|
||||
if taggable.tags.pluck(:name).sort != tag_names.sort
|
||||
taggable.tags = Tag.where(name: tag_names).all
|
||||
taggable.tags = Tag.where_name(tag_names).all
|
||||
if taggable.tags.size < tag_names.size
|
||||
new_tag_names = tag_names - taggable.tags.map(&:name)
|
||||
new_tag_names.each do |name|
|
||||
|
Reference in New Issue
Block a user