mirror of
https://github.com/discourse/discourse.git
synced 2025-06-01 07:37:55 +08:00
FEATURE: permalink normalization
Optionally allow admins to apply regex based normalization to permalinks prior to matching. This allows us to drop query string, or cleanly ignore slugs, etc.
This commit is contained in:
@ -5,11 +5,72 @@ class Permalink < ActiveRecord::Base
|
||||
|
||||
before_validation :normalize_url
|
||||
|
||||
def normalize_url
|
||||
if self.url
|
||||
self.url = self.url.strip
|
||||
self.url = self.url[1..-1] if url[0,1] == '/'
|
||||
class Normalizer
|
||||
attr_reader :source
|
||||
|
||||
def initialize(source)
|
||||
@source = source
|
||||
if source.present?
|
||||
@rules = source.split("|").map do |rule|
|
||||
parse_rule(rule)
|
||||
end.compact
|
||||
end
|
||||
end
|
||||
|
||||
def parse_rule(rule)
|
||||
return unless rule =~ /\/.*\//
|
||||
|
||||
escaping = false
|
||||
regex = ""
|
||||
sub = ""
|
||||
c = 0
|
||||
|
||||
rule.chars.each do |l|
|
||||
c += 1 if !escaping && l == "/"
|
||||
escaping = l == "\\"
|
||||
|
||||
if c > 1
|
||||
sub << l
|
||||
else
|
||||
regex << l
|
||||
end
|
||||
end
|
||||
|
||||
if regex.length > 1
|
||||
[Regexp.new(regex[1..-1]), sub[1..-1] || ""] rescue nil
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def normalize(url)
|
||||
return url unless @rules
|
||||
@rules.each do |(regex,sub)|
|
||||
url = url.sub(regex,sub)
|
||||
end
|
||||
|
||||
url
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def self.normalize_url(url)
|
||||
if url
|
||||
url = url.strip
|
||||
url = url[1..-1] if url[0,1] == '/'
|
||||
end
|
||||
|
||||
normalizations = SiteSetting.permalink_normalizations
|
||||
|
||||
@normalizer = Normalizer.new(normalizations) unless @normalizer && @normalizer.source == normalizations
|
||||
@normalizer.normalize(url)
|
||||
end
|
||||
|
||||
def self.find_by_url(url)
|
||||
find_by(url: normalize_url(url))
|
||||
end
|
||||
|
||||
def normalize_url
|
||||
self.url = Permalink.normalize_url(url) if url
|
||||
end
|
||||
|
||||
def target_url
|
||||
|
Reference in New Issue
Block a user