public
Fork of halorgium/mephisto
Description: A mirror of the mephisto code-base
Homepage: http://mephistoblog.com/
Clone URL: git://github.com/technoweenie/mephisto.git
Click here to lend your support to: mephisto and make a donation at www.pledgie.com !
NEW FEATURE: Redirections (see environment.rb)

git-svn-id: http://svn.techno-weenie.net/projects/mephisto/trunk@2296 
567b1171-46fb-0310-a4c9-b4bef9110e78
technoweenie (author)
Fri Sep 29 21:09:08 -0700 2006
commit  9cfd49d151f021bec8d141209a0903dc40e34a13
tree    5ce45ab8e6f899e0466281739360059c99e1b756
parent  ef018e312c6c402c07dbbb0d09f1c9e00d2302d2
...
1
2
 
 
3
4
5
...
1
2
3
4
5
6
7
0
@@ -1,5 +1,7 @@
0
 * SVN *
0
 
0
+* NEW FEATURE: Redirections (see environment.rb)
0
+
0
 * Allow drag/drop reordering of sections in a site [Bill Katz]
0
 
0
 * Refine child_sections liquid filter, add descendant_sections filter [Cristi Balan]
...
12
13
14
 
 
 
 
 
 
 
 
 
 
 
15
16
17
...
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
0
@@ -12,6 +12,17 @@ class MephistoController < ApplicationController
0
   end
0
 
0
   protected
0
+ def dispatch_redirect
0
+ # @section is the http status
0
+ # @dispatch_path.first has the headers
0
+ if @dispatch_path.first.is_a?(Hash)
0
+ response.headers['Status'] = interpret_status @section
0
+ redirect_to @dispatch_path.first[:location]
0
+ else
0
+ head @section
0
+ end
0
+ end
0
+
0
     def dispatch_list
0
       @articles = @section.articles.find_by_date(:include => :user, :limit => @section.articles_per_page)
0
       self.cached_references << @section
...
52
53
54
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
55
...
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
0
@@ -52,3 +52,28 @@ require 'mephisto_init'
0
 # shouldn't need to set the host, it's set automatically
0
 UserMailer.default_url_options[:host] = 'localhost:3000'
0
 UserMailer.mail_from = 'webmaster@localhost'
0
+
0
+# OPTIONAL - Redirections
0
+# Deny a route by immediately returning a 404
0
+#
0
+# Mephisto::Routing.deny 'articles/trackback/*' # return 404
0
+#
0
+# Specify multiple denied routes:
0
+#
0
+# Mephisto::Routing.deny 'articles/trackback/*', 'monkey/foo/*'
0
+#
0
+# Redirect elsewhere. You can fill in variables marked by ? or * with variable names beginning with :
0
+#
0
+# Redirect /old/foo to /new/foo and /old/foo/bar to /new/foo/bar
0
+#
0
+# Mephisto::Routing.redirect 'old/*' => 'new/$1'
0
+#
0
+# Redirect with a more specific set of variables
0
+#
0
+# Mephisto::Routing.redirect 'article/?/?/?' => 'new/$2/$1/$3'
0
+#
0
+# Multiple redirections at a time
0
+#
0
+# Mephisto::Routing.redirect \
0
+# 'old/*' => 'new/$1',
0
+# 'article/?/?/?' => 'new/$2/$1/$3'
0
\ No newline at end of file
...
6
7
8
 
 
 
 
9
10
11
...
6
7
8
9
10
11
12
13
14
15
0
@@ -6,6 +6,10 @@ module Mephisto
0
     def self.run(site, path)
0
       # check for any bad urls like /foo//bar
0
       return [:error, nil, *path] if path.any? &:blank?
0
+
0
+ if args = Mephisto::Routing.handle_redirection(path * "/")
0
+ return [:redirect, *args]
0
+ end
0
 
0
       # check for permalink
0
       if options = recognize_permalink(site, path)
...
22
23
24
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
26
27
...
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
0
@@ -22,5 +22,57 @@ module Mephisto
0
       map.dispatch '*path', :controller => 'mephisto', :action => 'dispatch'
0
       map.home '', :controller => 'mephisto', :action => 'dispatch'
0
     end
0
+
0
+ def self.redirections
0
+ @redirections ||= {}
0
+ end
0
+
0
+ def self.deny(*paths)
0
+ paths.each do |path|
0
+ redirections[convert_redirection_to_regex(path)] = :deny
0
+ end
0
+ end
0
+
0
+ def self.redirect(options)
0
+ options.each do |key, value|
0
+ redirections[convert_redirection_to_regex(key)] = sanitize_path(value)
0
+ end
0
+ end
0
+
0
+ def self.handle_redirection(path)
0
+ redirections.each do |pattern, action|
0
+ if match = pattern.match(path)
0
+ if action == :deny
0
+ return [:not_found]
0
+ else
0
+ return [:moved_permanently, {:location => build_destination(action.dup, match)}]
0
+ end
0
+ end
0
+ end
0
+ nil
0
+ end
0
+
0
+ protected
0
+ def self.sanitize_path(path)
0
+ path =~ /^(\/)|(https?:\/\/)/ ? path : "/#{path.split("://").last}"
0
+ end
0
+
0
+ def self.convert_redirection_to_regex(path)
0
+ path = path.split("://").last
0
+ path = path[1..-1] if path.starts_with('/')
0
+ path = Regexp.escape(path)
0
+ path.gsub! /\//, "\\/"
0
+ path.gsub! /(\\\*)|(\\\?$)/, "(.*)"
0
+ path.gsub! /\\\?/, "([^\\/]+)"
0
+ Regexp.new("^#{path}$")
0
+ end
0
+
0
+ def self.build_destination(path, matches)
0
+ i = -1
0
+ path.gsub!(/\$\d+/) { |s| matches[s[1..-1].to_i] }
0
+ path.gsub!(/[^:]\/\//, &:first)
0
+ path.chomp!('/')
0
+ path
0
+ end
0
   end
0
 end
0
\ No newline at end of file
...
76
77
78
 
 
 
 
 
 
 
 
 
 
 
79
80
81
...
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
0
@@ -76,6 +76,17 @@ THEME_FILES = [
0
   'templates/single.liquid'
0
 ] unless Object.const_defined?(:THEME_FILES)
0
 
0
+Mephisto::Routing.redirections.clear
0
+Mephisto::Routing.deny 'limited_deny'
0
+Mephisto::Routing.deny 'deny/foo/*'
0
+Mephisto::Routing.deny 'deny/bar/?/?'
0
+Mephisto::Routing.redirect \
0
+ 'redirect/from/*' => 'to/here',
0
+ 'redirect/match/wildcard/*' => 'this/$1',
0
+ 'redirect/match/vars/?/?' => 'this/$2/$1',
0
+ '/sanitize/path' => 'foo://bar',
0
+ 'redirect/external' => 'http://external/$1/$2'
0
+
0
 class Test::Unit::TestCase
0
   self.use_transactional_fixtures = true
0
   self.use_instantiated_fixtures = false
...
79
80
81
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
82
83
84
85
86
87
 
 
 
 
 
 
 
 
 
 
 
 
 
88
89
90
...
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
0
@@ -79,12 +79,48 @@ context "Dispatcher" do
0
     assert_dispatch :error, nil, '', 'foo', ['', 'foo']
0
   end
0
 
0
+ specify "should handle denied requests" do
0
+ %w(deny/foo/bar deny/foo/bar/baz limited_deny deny/bar/baz/blah).each { |path| assert_denied path }
0
+ end
0
+
0
+ specify "should redirect without variable matches" do
0
+ assert_redirected_to '/to/here', 'redirect/from/here'
0
+ assert_redirected_to '/bar', 'sanitize/path'
0
+ end
0
+
0
+ specify "should redirect with unused variable matches" do
0
+ assert_redirected_to 'http://external', 'redirect/external'
0
+ end
0
+
0
+ specify "should redirect with wildcard match" do
0
+ assert_redirected_to '/this/foo', 'redirect/match/wildcard/foo'
0
+ assert_redirected_to '/this/foo/bar', 'redirect/match/wildcard/foo/bar'
0
+ end
0
+
0
+ specify "should redirect and match multiple vars" do
0
+ assert_redirected_to '/this/bar/foo', 'redirect/match/vars/foo/bar'
0
+ assert_redirected_to '/this/bar/baz/foo', 'redirect/match/vars/foo/bar/baz'
0
+ end
0
+
0
   protected
0
     def assert_dispatch(dispatch_type, section, *args)
0
       path = args.pop
0
       result = Mephisto::Dispatcher.run sites(:first), path
0
       assert_equal [dispatch_type, section, *args], result
0
     end
0
+
0
+ def assert_denied(path)
0
+ result = Mephisto::Dispatcher.run sites(:first), path.split('/')
0
+ assert_equal :redirect, result.first
0
+ assert_equal :not_found, result.last
0
+ end
0
+
0
+ def assert_redirected_to(expected, path)
0
+ result = Mephisto::Dispatcher.run sites(:first), path.split('/')
0
+ assert_equal :redirect, result.shift
0
+ assert_equal :moved_permanently, result.first
0
+ assert_equal expected, result.last[:location]
0
+ end
0
 end
0
 
0
 context "Dispatcher Permalink Regular Expression" do

Comments

    No one has commented yet.