make site url redirections accept dynamic segments (/old_store/:product_name -> /products/:product_name)
did
committed Jun 02, 2017
commit 87c853571f8a45eb606077d740a47fa3c9e25f61
Showing 2
changed files with
32 additions
and 1 deletions
locomotive/steam/middlewares/url_redirection.rb b/lib/locomotive/steam/middlewares/url_redirection.rb
+23
-1
| @@ | @@ -35,7 +35,29 @@ module Locomotive::Steam |
| def redirect_url | |
| return false if site.url_redirections.nil? || site.url_redirections.size == 0 | |
| - | site.url_redirections.to_h[requested_url] |
| + | redirections_hash = site.url_redirections.to_h |
| + | |
| + | redirections_hash[requested_url] || find_dynamic_url_redirection(redirections_hash) |
| + | end |
| + | |
| + | def find_dynamic_url_redirection(redirections_hash) |
| + | number_of_segments = requested_url.split('/').size |
| + | |
| + | # attempt to find the first dynamic route which matches |
| + | redirections_hash.each do |route, redirection| |
| + | # a little bit of optimization |
| + | next unless route.include?(':') && route.split('/').size == number_of_segments |
| + | |
| + | _regexp = route.gsub(/:([^\/]+)/, "(?<\\1>[^\/]+)").gsub('/', '\/') |
| + | |
| + | if matches = Regexp.new(_regexp).match(requested_url) |
| + | matches.names.each { |n| redirection.gsub!(":#{n}", matches[n]) } |
| + | |
| + | return redirection |
| + | end |
| + | end |
| + | |
| + | false |
| end | |
| end | |
spec/unit/middlewares/url_redirection_spec.rb
+9
-0
| @@ | @@ -54,6 +54,15 @@ describe Locomotive::Steam::Middlewares::UrlRedirection do |
| end | |
| + | describe 'url matching a pattern' do |
| + | |
| + | let(:redirections) { [['/old_images/:file', '/images/old/:file']] } |
| + | let(:url) { 'http://models.example.com/old_images/cat.png' } |
| + | |
| + | it { is_expected.to eq [301, '/images/old/cat.png'] } |
| + | |
| + | end |
| + | |
| describe 'let the parent app know about the redirection when it happens' do | |
| let(:events) { [] } | |