The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Catalyst::Plugin::ForwardChained - Forwarding to "Chain"-Actions in Catalyst

DESCRIPTION

Forwarding to the end point of a couple of chain methods ..

In most cases: dont use - better user redirect instead

This is a hackaround, not a clean solution.

Experimental.

SYNOPSIS

    # In your application class 
    use Catalyst qw/ ForwardChained /;
    
    # ... somwhere else:
    $c->forward_to_chained( [ qw/ chained endpoint /, [ qw/ args / ] );
    $c->forward_to_chained( 'chained/endpoint', [ qw/ args / ] );

Example 1

Having some controller:

    package MyApp::Controller::Test;
    
    # ..
    # to be clear :
    __PACKAGE__->config->{ namespace } = 'test';
    
    # url would be "/one/*"
    sub my_index : PathPart( 'one' ) : Chained( '/' ) : CaptureArgs( 1 ) {
        # do some..
    }
    
    # url would be "/one/*/two/*"
    sub my_other : PathPart( 'two') : Chained( 'my_index' ) : Args( 1 ) {
        # do some..
    }

You would use:

    # somewhere
    #   this would call: "/namespace/one/111/two/222"
    $c->forward_to_chained( [ qw/ namespace two / ], [ "111", "222 ] );
    
    # same as above
    $c->forward_to_chained( "namespace/two", [ "111", "222 ] );

Example 2

it's not always obvious which path to choose when calling "forward_to_chained" ..

An example testing controller

    package MyApp::Controller::Testing;
    
    use strict;
    use warnings;
    
    use base qw/ Catalyst::Controller /;
    use Data::Dumper;
    
    __PACKAGE__->config->{ namespace } = 'testing';
    
    sub one : PathPart( 'testing/one' ) : Chained( '/' ) : CaptureArgs( 1 ) {
        my ( $self, $c, @args ) = @_;
        push @{ $c->stash->{ called } ||= [] }, {
            name => 'one',
            args => \@args
        };
    }
    
    sub two : Chained( 'one' ) : CaptureArgs( 1 ) {
        my ( $self, $c, @args ) = @_;
        push @{ $c->stash->{ called } ||= [] }, {
            name => 'two',
            args => \@args
        };
    }
    
    sub three : Chained( 'two' ) {
        my ( $self, $c, @args ) = @_;
        push @{ $c->stash->{ called } ||= [] }, {
            name => 'three',
            args => \@args
        };
    }
    
    
    sub right : PathPart( 'testing/right' ) : Chained( '/' ) : CaptureArgs( 0 ) {
        my ( $self, $c, @args ) = @_;
        push @{ $c->stash->{ called } ||= [] }, {
            name => 'right',
            args => \@args
        };
    }
    
    sub again : Chained( 'right' ) : Args( 1 ) {
        my ( $self, $c, @args ) = @_;
        push @{ $c->stash->{ called } ||= [] }, {
            name => 'again',
            args => \@args
        };
    }
    
    
    sub chainor : Local {
        my ( $self, $c ) = @_;
        
        # calling chained:
        
        # 1) WRONG:
        #$c->forward_to_chained( 'testing/one/arg1/two/arg2/three/arg3' );
        
        # 2) WRONG:
        #$c->forward_to_chained( 'testing/one/two/three', [ qw/ arg1 arg2 arg3 arg4 / ] );
        
        # 3) CORRECT:
        $c->forward_to_chained( 'testing/three', [qw/ arg1 arg2 arg3 arg4 /] );
        
        $c->forward_to_chained( 'testing/again', [qw/ arg /] );
        
        $c->res->content_type( 'text/plain' );
        $c->res->body( "Called: \n". Dumper( $c->stash->{ called } ) );
    }
    
    1;

would produce something like this:

    Called: 
    $VAR1 = [
          {
            'args' => [
                        'arg1'
                      ],
            'name' => 'one'
          },
          {
            'args' => [
                        'arg2'
                      ],
            'name' => 'two'
          },
          {
            'args' => [
                        'arg3',
                        'arg4'
                      ],
            'name' => 'three'
          },
          {
            'args' => [],
            'name' => 'right'
          },
          {
            'args' => [
                        'arg'
                      ],
            'name' => 'again'
          }
        ];

and catalyst debug out:

    .----------------------------------------------------------------+-----------.
    | Action                                                         | Time      |
    +----------------------------------------------------------------+-----------+
    | /begin                                                         | 0.064814s |
    | /testing/chainor                                               | 0.002931s |
    | /testing/one                                                   | 0.000588s |
    | /testing/two                                                   | 0.000208s |
    | /testing/three                                                 | 0.000197s |
    | /testing/right                                                 | 0.000061s |
    | /testing/again                                                 | 0.000055s |
    | /end                                                           | 0.000495s |
    '----------------------------------------------------------------+-----------'

METHODS

forward_to_chained

forwards to a certain chained action endpoint ..

    $c->forward_to_chained( "some/path", [ qw/ arg1 arg2 arg3 / ] );
    $c->forward_to_chained( [qw/ some path /], [ qw/ arg1 arg2 arg3 / ] );

get_chained_action_endpoints

returns array or arrayref of endpoints.. to help you find the one you need

    my @endpoints = $c->get_chained_action_endpoints;
    my $endpoints_ref = $c->get_chained_action_endpoints;

AUTHOR

Ulrich Kautz, uk@fortrabbit.de