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:
Sam
2015-07-15 15:32:35 +10:00
parent d20324ece8
commit b772d96f7a
5 changed files with 92 additions and 4 deletions

View File

@ -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