Catalyst-Runtime
view release on metacpan or search on metacpan
lib/Catalyst/Utils.pm view on Meta::CPAN
return $ns->new(@init_args);
} elsif(Class::Load::try_load_class("Plack::Middleware::$namespace")) { ## Act like Plack::Builder
return "Plack::Middleware::$namespace"->new(@init_args);
} else {
die "Can't load middleware via '$namespace'. It's not ".$class."::Middleware::".$namespace." or Plack::Middleware::$namespace";
}
}
return; ## be sure we can count on a proper return when valid
}
=head2 apply_registered_middleware ($psgi)
Given a $psgi reference, wrap all the L<Catalyst/registered_middlewares>
around it and return the wrapped version.
This exists to deal with the fact Catalyst registered middleware can be
either an object with a wrap method or a coderef.
=cut
sub apply_registered_middleware {
my ($class, $psgi) = @_;
my $new_psgi = $psgi;
foreach my $middleware ($class->registered_middlewares) {
$new_psgi = Scalar::Util::blessed $middleware ?
$middleware->wrap($new_psgi) :
$middleware->($new_psgi);
}
return $new_psgi;
}
=head2 inject_component
Used to add components at runtime:
into The Catalyst package to inject into (e.g. My::App)
component The component package to inject
traits (Optional) ArrayRef of L<Moose::Role>s that the component should consume.
as An optional moniker to use as the package name for the derived component
For example:
Catalyst::Utils::inject_component( into => My::App, component => Other::App::Controller::Apple )
The above will create 'My::App::Controller::Other::App::Controller::Apple'
Catalyst::Utils::inject_component( into => My::App, component => Other::App::Controller::Apple, as => Apple )
The above will create 'My::App::Controller::Apple'
Catalyst::Utils::inject_component( into => $myapp, component => 'MyRootV', as => 'Controller::Root' );
Will inject Controller, Model, and View components into your Catalyst application
at setup (run)time. It does this by creating a new package on-the-fly, having that
package extend the given component, and then having Catalyst setup the new component
(via $app->setup_component).
B<NOTE:> This is basically a core version of L<CatalystX::InjectComponent>. If you were using that
you can now use this safely instead. Going forward changes required to make this work will be
synchronized with the core method.
B<NOTE:> The 'traits' option is unique to the L<Catalyst::Utils> version of this feature.
B<NOTE:> These injected components really need to be a L<Catalyst::Component> and a L<Moose>
based class.
=cut
sub inject_component {
my %given = @_;
my ($into, $component, $as) = @given{qw/into component as/};
croak "No Catalyst (package) given" unless $into;
croak "No component (package) given" unless $component;
Class::Load::load_class($component);
$as ||= $component;
unless ( $as =~ m/^(?:Controller|Model|View)::/ || $given{skip_mvc_renaming} ) {
my $category;
for (qw/ Controller Model View /) {
if ( $component->isa( "Catalyst::$_" ) ) {
$category = $_;
last;
}
}
croak "Don't know what kind of component \"$component\" is" unless $category;
$as = "${category}::$as";
}
my $component_package = join '::', $into, $as;
unless ( Class::Load::is_class_loaded $component_package ) {
eval "package $component_package; use base qw/$component/; 1;" or
croak "Unable to build component package for \"$component_package\": $@";
Moose::Util::apply_all_roles($component_package, @{$given{traits}}) if $given{traits};
(my $file = "$component_package.pm") =~ s{::}{/}g;
$INC{$file} ||= 1;
}
my $_setup_component = sub {
my $into = shift;
my $component_package = shift;
$into->components->{$component_package} = $into->delayed_setup_component( $component_package );
};
$_setup_component->( $into, $component_package );
}
=head1 PSGI Helpers
Utility functions to make it easier to work with PSGI applications under Catalyst
=head2 env_at_path_prefix
Localize C<$env> under the current controller path prefix:
package MyApp::Controller::User;
use Catalyst::Utils;
( run in 0.539 second using v1.01-cache-2.11-cpan-39bf76dae61 )