X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=catagits%2FCatalyst-Runtime.git;a=blobdiff_plain;f=lib%2FCatalyst.pm;h=4015c1c087f851fdec4b182ddfec1d67de6965af;hp=fbfb3bf443e8511f3f4cdf7725cf62dfe2f5dc1c;hb=d261d1535bf21a062b59d7900707dcba8dff1431;hpb=d0fa4aff0f751dedf9ef8b904735f274bea6f028 diff --git a/lib/Catalyst.pm b/lib/Catalyst.pm index fbfb3bf..4015c1c 100644 --- a/lib/Catalyst.pm +++ b/lib/Catalyst.pm @@ -1206,6 +1206,12 @@ path, use C<< $c->uri_for_action >> instead. sub uri_for { my ( $c, $path, @args ) = @_; + if (blessed($path) && $path->isa('Catalyst::Controller')) { + $path = $path->path_prefix; + $path =~ s{/+\z}{}; + $path .= '/'; + } + if ( blessed($path) ) { # action object my $captures = ( scalar @args && ref $args[0] eq 'ARRAY' ? shift(@args) @@ -2126,34 +2132,27 @@ sub setup_actions { my $c = shift; $c->dispatcher->setup_actions( $c, @_ ) } =head2 $c->setup_components -Sets up components. Specify a C config option to pass -additional options directly to L. To add additional -search paths, specify a key named C as an array -reference. Items in the array beginning with C<::> will have the -application class name prepended to them. +This method is called internally to set up the application's components. + +It finds modules by calling the L method, expands them to +package names with the L method, and then installs +each component into the application. -All components found will also have any -L loaded and set up as components. -Note, that modules which are B an I of the main -file namespace loaded will not be instantiated as components. +The C config option is passed to both of the above methods. + +Installation of each component is performed by the L method, +below. =cut sub setup_components { my $class = shift; - my @paths = qw( ::Controller ::C ::Model ::M ::View ::V ); my $config = $class->config->{ setup_components }; - my $extra = delete $config->{ search_extra } || []; - - push @paths, @$extra; - my $locator = Module::Pluggable::Object->new( - search_path => [ map { s/^(?=::)/$class/; $_; } @paths ], - %$config - ); + my @comps = sort { length $a <=> length $b } + $class->locate_components($config); - my @comps = sort { length $a <=> length $b } $locator->plugins; my %comps = map { $_ => 1 } @comps; my $deprecated_component_names = grep { /::[CMV]::/ } @comps; @@ -2170,14 +2169,16 @@ sub setup_components { Catalyst::Utils::ensure_class_loaded( $component, { ignore_loaded => 1 } ); #Class::MOP::load_class($component); - my $module = $class->setup_component( $component ); + my @packages = $class->expand_component_module( $component, $config ); + my %modules = ( - $component => $module, map { $_ => $class->setup_component( $_ ) } grep { - not exists $comps{$_} - } Devel::InnerPackage::list_packages( $component ) + # we preloaded $component above, so we must allow it here again + # -- rjbs, 2009-08-11 + ($_ eq $component) or (not exists $comps{$_}) + } @packages ); for my $key ( keys %modules ) { @@ -2186,6 +2187,53 @@ sub setup_components { } } +=head2 $c->locate_components( $setup_component_config ) + +This method is meant to provide a list of component modules that should be +setup for the application. By default, it will use L. + +Specify a C config option to pass additional options directly +to L. To add additional search paths, specify a key named +C as an array reference. Items in the array beginning with C<::> +will have the application class name prepended to them. + +=cut + +sub locate_components { + my $class = shift; + my $config = shift; + + my @paths = qw( ::Controller ::C ::Model ::M ::View ::V ); + my $extra = delete $config->{ search_extra } || []; + + push @paths, @$extra; + + my $locator = Module::Pluggable::Object->new( + search_path => [ map { s/^(?=::)/$class/; $_; } @paths ], + %$config + ); + + my @comps = $locator->plugins; + + return @comps; +} + +=head2 $c->expand_component_module( $component, $setup_component_config ) + +Components found by C will be passed to this method, which +is expected to return a list of component (package) names to be set up. + +By default, this method will return the component itself as well as any inner +packages found by L. + +=cut + +sub expand_component_module { + my ($class, $module) = @_; + my @inner = Devel::InnerPackage::list_packages( $module ); + return ($module, @inner); +} + =head2 $c->setup_component =cut @@ -2215,6 +2263,10 @@ sub setup_component { my $suffix = Catalyst::Utils::class2classsuffix( $component ); my $config = $class->config->{ $suffix } || {}; + # Stash _component_name in the config here, so that custom COMPONENT + # methods also pass it. local to avoid pointlessly shitting in config + # for the debug screen, as $component is already the key name. + local $config->{_component_name} = $component; my $instance = eval { $component->COMPONENT( $class, $config ); };