public
Fork of wycats/merb-more
Description: Merb More: The Full Stack. Take what you need; leave what you don't.
Homepage: http://www.merbivore.com
Clone URL: git://github.com/jherdman/merb-more.git
Major refactoring of some internals
fabien (author)
Mon Jun 09 04:36:14 -0700 2008
commit  a0d045be44220203c4ccb398568974283bdc6dbb
tree    52dd6246a7e45427e164e0c65ae1c1da5ecb4e5d
parent  7fa7aa21dfc877f52dd1613335b7cd58675d0c8c
...
107
108
109
 
 
 
110
111
112
...
114
115
116
117
 
118
119
120
...
107
108
109
110
111
112
113
114
115
...
117
118
119
 
120
121
122
123
0
@@ -107,6 +107,9 @@ if defined?(Merb::Plugins)
0
   #
0
   # This is done right after the app's after_load_callbacks are run.
0
   # Any settings can be taken into account in the activation step.
0
+ #
0
+ # @note Activation will only take place if the slice has been routed;
0
+ # this means you need have at least one slice route setup.
0
   class Merb::Slices::Activate < Merb::BootLoader
0
   
0
     after AfterAppLoads
0
@@ -114,7 +117,7 @@ if defined?(Merb::Plugins)
0
     def self.run
0
       Merb::Slices.each_slice do |slice|
0
         Merb.logger.info!("Activating slice '#{slice}' ...")
0
- slice.activate if slice.respond_to?(:activate)
0
+ slice.activate if slice.respond_to?(:activate) && slice.routed?
0
       end
0
     end
0
   
...
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
...
132
133
134
135
136
137
138
139
140
141
 
142
143
144
...
83
84
85
 
 
86
 
 
 
 
 
 
 
 
 
 
 
87
 
 
 
 
 
 
 
 
88
89
90
91
92
93
94
95
...
116
117
118
 
 
 
 
 
 
 
119
120
121
122
0
@@ -83,29 +83,13 @@ module Merb
0
           # @return <Module> A slice module.
0
           def slice; self.class.slice; end
0
           
0
- protected
0
-
0
           # Generate a url - takes the slice's :path_prefix into account.
0
- #
0
- # This is only relevant for default routes, as named routes are
0
- # handled correctly without any special considerations.
0
- #
0
- # @param name<#to_sym,Hash> The name of the URL to generate.
0
- # @param rparams<Hash> Parameters for the route generation.
0
- #
0
- # @return String The generated URL.
0
- #
0
- # @notes If a hash is used as the first argument, a default route will be
0
- # generated based on it and rparams.
0
           def slice_url(name, rparams={})
0
- rparams[:controller] = prefix_slice_controller_name(rparams[:controller]) if rparams[:controller]
0
- uri = Merb::Router.generate(name, rparams, {
0
- :controller => prefix_slice_controller_name(controller_name),
0
- :action => action_name,
0
- :format => params[:format]
0
- }
0
- )
0
- Merb::Config[:path_prefix] ? Merb::Config[:path_prefix] + uri : uri
0
+ self.slice.url(name, rparams, {
0
+ :controller => controller_name,
0
+ :action => action_name,
0
+ :format => params[:format]
0
+ })
0
           end
0
 
0
           private
0
@@ -132,13 +116,7 @@ module Merb
0
               _template_location(context, type, controller)
0
             end
0
           end
0
-
0
- # Helper method to add :path_prefix if needed.
0
- def prefix_slice_controller_name(name)
0
- controller = name.gsub(%r|^#{slice.identifier_sym}/|, '')
0
- slice[:path_prefix].blank? ? controller : slice[:path_prefix] / controller
0
- end
0
-
0
+
0
         end
0
       
0
       end
...
110
111
112
 
113
114
 
115
116
 
117
118
119
...
123
124
125
126
 
127
128
129
...
110
111
112
113
114
 
115
116
 
117
118
119
120
...
124
125
126
 
127
128
129
130
0
@@ -110,10 +110,11 @@ module Merb
0
         Merb::Slices::Loader.load_classes(slice_file)
0
         slice = register(slice_file, false) # just to get module by slice_file
0
         slice.load_slice # load the slice
0
+ Merb::Slices::Loader.reload_router!
0
         slice.init if slice.respond_to?(:init)
0
- slice.activate if slice.respond_to?(:activate)
0
+ slice.activate if slice.respond_to?(:activate) && slice.routed?
0
         slice
0
- ensure
0
+ rescue
0
         Merb::Slices::Loader.reload_router!
0
       end
0
       alias :register_and_load :activate_by_file
0
@@ -123,7 +124,7 @@ module Merb
0
       # @param slice_module<#to_s> The Slice module to unregister.
0
       def deactivate(slice_module)
0
         if slice = self[slice_module]
0
- slice.deactivate if slice.respond_to?(:deactivate)
0
+ slice.deactivate if slice.respond_to?(:deactivate) && slice.routed?
0
           unregister(slice)
0
         end
0
       end
...
5
6
7
 
8
9
10
...
30
31
32
 
 
 
 
 
 
33
34
35
...
86
87
88
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
89
90
91
...
5
6
7
8
9
10
11
...
31
32
33
34
35
36
37
38
39
40
41
42
...
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
127
0
@@ -5,6 +5,7 @@ module Merb
0
       def self.extended(slice_module)
0
         slice_module.meta_class.module_eval do
0
           attr_accessor :identifier, :identifier_sym, :root, :file
0
+ attr_accessor :routes, :named_routes
0
           attr_accessor :description, :version, :author
0
         end
0
       end
0
@@ -30,6 +31,12 @@ module Merb
0
       # Stub to setup routes inside the host application.
0
       def setup_router(scope); end
0
       
0
+ # Check if there have been any routes setup.
0
+ def routed?
0
+ self.routes && !self.routes.empty?
0
+ end
0
+
0
+ # Return a value suitable for routes/urls.
0
       def to_param
0
         self.identifier
0
       end
0
@@ -86,6 +93,35 @@ module Merb
0
       def collected_app_paths
0
         @collected_app_paths ||= []
0
       end
0
+
0
+ # Generate a url - takes the slice's :path_prefix into account.
0
+ #
0
+ # This is only relevant for default routes, as named routes are
0
+ # handled correctly without any special considerations.
0
+ #
0
+ # @param name<#to_sym,Hash> The name of the URL to generate.
0
+ # @param rparams<Hash> Parameters for the route generation.
0
+ #
0
+ # @return String The generated URL.
0
+ #
0
+ # @notes If a hash is used as the first argument, a default route will be
0
+ # generated based on it and rparams.
0
+ def url(name, rparams = {}, defaults = {})
0
+ defaults = rparams if name.is_a?(Hash) && defaults.empty?
0
+ rparams = name if name.is_a?(Hash)
0
+
0
+ if name.is_a?(Symbol)
0
+ raise "Named route not found: #{name}" unless self.named_routes[name]
0
+ uri = Merb::Router.generate(name, rparams, defaults)
0
+ else
0
+ defaults[:controller] = defaults[:controller].gsub(%r|^#{self.identifier_sym}/|, '') if defaults[:controller]
0
+ uri = Merb::Router.generate(name, rparams, defaults)
0
+ uri = self[:path_prefix] / uri unless self[:path_prefix].blank?
0
+ uri = "/#{uri}" unless uri[0,1] == '/'
0
+ end
0
+
0
+ Merb::Config[:path_prefix] ? Merb::Config[:path_prefix] + uri : uri
0
+ end
0
     
0
       # The slice-level load paths to use when loading the slice.
0
       #
...
1
2
 
3
4
5
...
32
33
34
 
 
35
36
37
...
44
45
46
47
48
49
50
51
 
 
 
 
 
 
 
 
 
52
53
54
...
1
2
3
4
5
6
...
33
34
35
36
37
38
39
40
...
47
48
49
 
 
 
 
 
50
51
52
53
54
55
56
57
58
59
60
61
0
@@ -1,5 +1,6 @@
0
 module Merb
0
   class Router
0
+
0
     class Behavior
0
       
0
       # Add all known slices to the router
0
@@ -32,6 +33,8 @@ module Merb
0
       #
0
       # @return <Behaviour> The current router context.
0
       #
0
+ # @note If a slice has no routes at all, the activate hook won't be executed.
0
+ #
0
       # @note Normally you should specify the slice_module using a String or Symbol
0
       # this ensures that your module can be removed from the router at runtime.
0
       def add_slice(slice_module, options = {}, &block)
0
@@ -44,11 +47,15 @@ module Merb
0
           options[:prepend_routes] = block if block_given?
0
           slice_module[:path_prefix] = options[:path]
0
           Merb.logger.info!("Mounting slice #{slice_module} at /#{options[:path]}")
0
- self.namespace(namespace.to_sym, options.except(:default_routes, :prepend_routes, :append_routes)) do |ns|
0
- options[:prepend_routes].call(ns) if options[:prepend_routes].respond_to?(:call)
0
- slice_module.setup_router(ns) # setup the routes from the slice itself
0
- options[:append_routes].call(ns) if options[:append_routes].respond_to?(:call)
0
- ns.match(%r{/:controller(/:action(/:id)?)?(\.:format)?}).to(options[:params] || {}) if options[:default_routes]
0
+
0
+ # setup routes - capture the slice's routes for easy reference
0
+ slice_module.routes, slice_module.named_routes = Merb::Router.capture do
0
+ self.namespace(namespace.to_sym, options.except(:default_routes, :prepend_routes, :append_routes)) do |ns|
0
+ options[:prepend_routes].call(ns) if options[:prepend_routes].respond_to?(:call)
0
+ slice_module.setup_router(ns) # setup the routes from the slice itself
0
+ options[:append_routes].call(ns) if options[:append_routes].respond_to?(:call)
0
+ ns.default_routes(options[:params] || {}) if options[:default_routes]
0
+ end
0
           end
0
         else
0
           Merb.logger.info!("Skipped adding slice #{slice_module} to router...")
...
2
3
4
5
 
6
7
8
...
48
49
50
 
 
 
51
 
 
52
53
54
...
2
3
4
 
5
6
7
8
...
48
49
50
51
52
53
54
55
56
57
58
59
0
@@ -2,7 +2,7 @@ if defined?(Merb::Plugins)
0
 
0
   $:.unshift File.dirname(__FILE__)
0
 
0
- dependency 'merb-slices'
0
+ load_dependency 'merb-slices'
0
   Merb::Plugins.add_rakefiles "<%= base_name %>/merbtasks", "<%= base_name %>/slicetasks"
0
 
0
   # Register the Slice for the current host application
0
@@ -48,7 +48,12 @@ if defined?(Merb::Plugins)
0
     # Routes will be added within this scope (namespace). In fact, any
0
     # router behaviour is a valid namespace, so you can attach
0
     # routes at any level of your router setup.
0
+ #
0
+ # @note prefix your named routes with :<%= underscored_name %>_
0
+ # to avoid potential conflicts with global named routes.
0
     def self.setup_router(scope)
0
+ # example of a named route
0
+ scope.match('/index.:format').to(:controller => 'main', :action => 'index').name(:<%= underscored_name %>_index)
0
     end
0
     
0
   end
...
1
2
3
4
5
...
 
 
1
2
3
0
@@ -1,5 +1,3 @@
0
-$SLICED_APP=true # we're running inside the host application context
0
-
0
 namespace :slices do
0
   namespace :<%= underscored_name %> do
0
   
...
1
2
3
4
5
...
 
 
1
2
3
0
@@ -1,5 +1,3 @@
0
-$SLICED_APP=true # we're running inside the host application context
0
-
0
 namespace :slices do
0
   namespace :<%= underscored_name %> do
0
     
...
6
7
8
 
 
 
 
 
 
 
 
9
10
11
...
37
38
39
 
 
 
 
 
 
 
 
 
 
40
41
42
...
6
7
8
9
10
11
12
13
14
15
16
17
18
19
...
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
0
@@ -6,6 +6,14 @@ describe "<%= module_name %> (module)" do
0
   
0
   # Feel free to remove the specs below
0
   
0
+ before :all do
0
+ Merb::Router.prepare { |r| r.add_slice(:<%= module_name %>) } if standalone?
0
+ end
0
+
0
+ after :all do
0
+ Merb::Router.reset! if standalone?
0
+ end
0
+
0
   it "should be registered in Merb::Slices.slices" do
0
     Merb::Slices.slices.should include(<%= module_name %>)
0
   end
0
@@ -37,6 +45,16 @@ describe "<%= module_name %> (module)" do
0
     <%= module_name %>.author.should == "YOUR NAME"
0
   end
0
   
0
+ it "should have :routes and :named_routes properties" do
0
+ <%= module_name %>.routes.should_not be_empty
0
+ <%= module_name %>.named_routes[:<%= underscored_name %>_index].should be_kind_of(Merb::Router::Route)
0
+ end
0
+
0
+ it "should have an url helper method for slice-specific routes" do
0
+ <%= module_name %>.url(:controller => 'main', :action => 'show', :format => 'html').should == "/<%= base_name %>/main/show.html"
0
+ <%= module_name %>.url(:<%= underscored_name %>_index, :format => 'html').should == "/<%= base_name %>/index.html"
0
+ end
0
+
0
   it "should have a config property (Hash)" do
0
     <%= module_name %>.config.should be_kind_of(Hash)
0
   end
...
8
9
10
 
 
 
 
11
12
13
...
26
27
28
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
30
31
...
8
9
10
11
12
13
14
15
16
17
...
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
0
@@ -8,6 +8,10 @@ describe "<%= module_name %>::Main (controller)" do
0
     Merb::Router.prepare { |r| r.add_slice(:<%= module_name %>) } if standalone?
0
   end
0
   
0
+ after :all do
0
+ Merb::Router.reset! if standalone?
0
+ end
0
+
0
   it "should have access to the slice module" do
0
     controller = dispatch_to(<%= module_name %>::Main, :index)
0
     controller.slice.should == <%= module_name %>
0
@@ -26,6 +30,22 @@ describe "<%= module_name %>::Main (controller)" do
0
     controller.action_name.should == 'index'
0
   end
0
   
0
+ it "should work with the example named route" do
0
+ controller = get("/<%= base_name %>/index.html")
0
+ controller.should be_kind_of(<%= module_name %>::Main)
0
+ controller.action_name.should == 'index'
0
+ end
0
+
0
+ it "should have routes in <%= module_name %>.routes" do
0
+ <%= module_name %>.routes.should_not be_empty
0
+ end
0
+
0
+ it "should have a slice_url helper method for slice-specific routes" do
0
+ controller = dispatch_to(<%= module_name %>::Main, 'index')
0
+ controller.slice_url(:action => 'show', :format => 'html').should == "/<%= base_name %>/main/show.html"
0
+ controller.slice_url(:<%= underscored_name %>_index, :format => 'html').should == "/<%= base_name %>/index.html"
0
+ end
0
+
0
   it "should have helper methods for dealing with public paths" do
0
     controller = dispatch_to(<%= module_name %>::Main, :index)
0
     controller.public_path_for(:image).should == "/slices/<%= base_name %>/images"
...
29
30
31
32
 
33
34
35
...
29
30
31
 
32
33
34
35
0
@@ -29,7 +29,7 @@ module Merb
0
       
0
       # Whether the specs are being run from a host application or standalone
0
       def standalone?
0
- not $SLICED_APP
0
+ Merb.root == ::<%= module_name %>.root
0
       end
0
       
0
     end
...
2
3
4
5
 
6
7
8
...
43
44
45
 
 
 
46
47
48
...
2
3
4
 
5
6
7
8
...
43
44
45
46
47
48
49
50
51
0
@@ -2,7 +2,7 @@ if defined?(Merb::Plugins)
0
 
0
   $:.unshift File.dirname(__FILE__)
0
 
0
- dependency 'merb-slices'
0
+ load_dependency 'merb-slices'
0
   Merb::Plugins.add_rakefiles "<%= base_name %>/merbtasks", "<%= base_name %>/slicetasks"
0
 
0
   # Register the Slice for the current host application
0
@@ -43,6 +43,9 @@ if defined?(Merb::Plugins)
0
     # Routes will be added within this scope (namespace). In fact, any
0
     # router behaviour is a valid namespace, so you can attach
0
     # routes at any level of your router setup.
0
+ #
0
+ # @note prefix your named routes with :<%= underscored_name %>_
0
+ # to avoid potential conflicts with global named routes.
0
     def self.setup_router(scope)
0
     end
0
     
...
1
2
3
4
5
...
 
 
1
2
3
0
@@ -1,5 +1,3 @@
0
-$SLICED_APP=true # we're running inside the host application context
0
-
0
 namespace :slices do
0
   namespace :<%= underscored_name %> do
0
   
...
1
2
3
4
5
...
 
 
1
2
3
0
@@ -1,5 +1,3 @@
0
-$SLICED_APP=true # we're running inside the host application context
0
-
0
 namespace :slices do
0
   namespace :<%= underscored_name %> do
0
     
...
2
3
4
5
 
6
7
8
...
42
43
44
 
 
 
45
46
47
...
2
3
4
 
5
6
7
8
...
42
43
44
45
46
47
48
49
50
0
@@ -2,7 +2,7 @@ if defined?(Merb::Plugins)
0
 
0
   $:.unshift File.dirname(__FILE__)
0
 
0
- dependency 'merb-slices'
0
+ load_dependency 'merb-slices'
0
   Merb::Plugins.add_rakefiles "<%= base_name %>/merbtasks", "<%= base_name %>/slicetasks"
0
 
0
   # Register the Slice for the current host application
0
@@ -42,6 +42,9 @@ if defined?(Merb::Plugins)
0
     # Routes will be added within this scope (namespace). In fact, any
0
     # router behaviour is a valid namespace, so you can attach
0
     # routes at any level of your router setup.
0
+ #
0
+ # @note prefix your named routes with :<%= underscored_name %>_
0
+ # to avoid potential conflicts with global named routes.
0
     def self.setup_router(scope)
0
     end
0
     
...
1
2
3
4
5
...
 
 
1
2
3
0
@@ -1,5 +1,3 @@
0
-$SLICED_APP=true # we're running inside the host application context
0
-
0
 namespace :slices do
0
   namespace :<%= underscored_name %> do
0
   
...
1
2
3
4
5
...
 
 
1
2
3
0
@@ -1,5 +1,3 @@
0
-$SLICED_APP=true # we're running inside the host application context
0
-
0
 namespace :slices do
0
   namespace :<%= underscored_name %> do
0
     

Comments

    No one has commented yet.