---
name: "CGI::Application::Plugin::Forward"
section: "3pm"
platform: "linux"
package: "libcgi-application-plugin-forward-perl"
version: "1.06-3"
release: "Debian 13 (Trixie)"
platforms: ["linux"]
url: "https://new.carta.tech/CGI::Application::Plugin::Forward"
---

# CGI::Application::Plugin::Forward(3pm)

Pass control from one run mode to another

## NAME

CGI::Application::Plugin::Forward - Pass control from one run mode to another

## VERSION

Version 1.06

## SYNOPSIS

```
    use base 'CGI::Application';
    use CGI::Application::Plugin::Forward;
    sub setup {
        my $self = shift;
        $self->run_modes([qw(
            start
            second_runmode
        )]);
    }
    sub start {
        my $self = shift;
        return $self->forward('second_runmode');
    }
    sub second_runmode {
        my $self = shift;
        my $rm = $self->get_current_runmode;  # 'second_runmode'
    }
```

## DESCRIPTION

The forward method passes control to another run mode and returns its output.  This is equivalent to calling `"$self->$other_runmode"`, except that CGI::Application's internal value of the current run mode is updated.

This means that calling `"$self->get_current_runmode"` after calling `"forward"` will return the name of the new run mode.  This is useful for modules that depend on the name of the current run mode such as CGI::Application::Plugin::AnyTemplate.

For example, here's how to pass control to a run mode named `"other_action"` from `"start"` while updating the value of `"current_run_mode"`:

```
    sub setup {
        my $self = shift;
        $self->run_modes({
            start         => 'start',
            other_action  => 'other_method',
        });
    }
    sub start {
        my $self = shift;
        return $self->forward('other_action');
    }
    sub other_method {
        my $self = shift;
        my $rm = $self->get_current_runmode;  # 'other_action'
    }
```

Note that forward accepts the *name* of the run mode (in this case *'other\_action'*), which might not be the same as the name of the method that handles the run mode (in this case *'other\_method'*)

You can still call `"$self->other_method"` directly, but `"current_run_mode"` will not be updated:

```
    sub setup {
        my $self = shift;
        $self->run_modes({
            start         => 'start',
            other_action  => 'other_method',
        });
    }
    sub start {
        my $self = shift;
        return $self->other_method;
    }
    sub other_method {
        my $self = shift;
        my $rm = $self->get_current_runmode;  # 'start'
    }
```

Forward will work with coderef-based runmodes as well:

```
    sub setup {
        my $self = shift;
        $self->run_modes({
            start         => 'start',
            anon_action   => sub {
                my $self = shift;
                my $rm = $self->get_current_runmode;  # 'anon_action'
            },
        });
    }
    sub start {
        my $self = shift;
        return $self->forward('anon_action');
    }
```

## FORWARD vs. REDIRECT

Calling `"forward"` changes the run mode of your application, but it stays within the same HTTP request.

To redirect to a new runmode using a completely new web request, you might consider using the `"redirect"` method provided by CGI::Application::Plugin::Redirect.

The advantage of using an external redirect as opposed to an internal forward is that it provides a 'clean break' between pages.

For instance, in a typical BREAD application (Browse, Read, Edit, Add, Delete), after the user completes an action, you usually return the user to the Browse list.  For instance, when the user adds a new record via a POST form, and your app returns them to the list of records.

If you use `"forward"`, then you are still in the same request as the original *add record*.  The user might hit *reload*, expecting to refresh the list of records.  But in fact, *reload* will attempt to repost the *add record* form.  The user's browser might present a warning about reposting the same data.  The browser may refuse to redisplay the page, due for caching reasons.

So in this case, it may make more sense to do a fresh HTTP redirect back to the Browse list.

## METHODS

### forward

Runs another run mode passing any parameters you supply.  Returns the output of the new run mode.

```
    return $self->forward('run_mode_name', @run_mode_params);
```

## HOOKS

Before the forwarded run mode is called, the `"forward_prerun"` hook is called. You can use this hook to do any prep work that you want to do before any new run mode gains control.

This is similar to CGI::Application's built in `"cgiapp_prerun"` method, but it is called each time you call forward; not just the when your application starts.

```
    sub setup {
        my $self = shift;
        $self->add_callback('forward_prerun' => \&prepare_rm_stuff);
    }
    sub prepare_rm_stuff {
        my $self = shift;
        # do any necessary prep work here....
    }
```

Note that your hooked method will only be called when you call forward.  If you never call `"forward"`, the hook will not be called. In particuar, the hook will not be called for your application's `"start_mode"`.  For that, you still use `"cgiapp_prerun"`.

If you want to have a method run for every run mode *including* the `"start_mode"`, then you can call the hook directly from `"cgiapp_prerun"`.

```
    sub setup {
        my $self = shift;
        $self->add_callback('forward_prerun' => \&prepare_rm_stuff);
    }
    sub cgiapp_prerun {
        my $self = shift;
        $self->prepare_rm_stuff;
    }
    sub prepare_rm_stuff {
        my $self = shift;
        # do any necessary prep work here....
    }
```

Alternately, you can hook `"cgiapp_prerun"` to the `"forward_prerun"` hook:

```
    sub setup {
        my $self = shift;
        $self->add_callback('forward_prerun' => \&cgiapp_prerun);
    }
    sub cgiapp_prerun {
        my $self = shift;
        # do any necessary prep work here....
    }
```

This is a less flexible solution, since certain things that can be done in `"cgiapp_prerun"` (like setting `"prerun_mode"`) won't work when the method is called from the `"forward_prerun"` hook.

## AUTHOR

Michael Graham, `"<mag-perl@occamstoothbrush.com>"`

## BUGS

Please report any bugs or feature requests to `"bug-cgi-application-plugin-forward@rt.cpan.org"`, or through the web interface at \<http://rt.cpan.org\>.  I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.

## ACKNOWLEDGEMENTS

Thanks to Mark Stosberg for the idea and...well...the implementation as well.

## COPYRIGHT & LICENSE

Copyright 2005 Michael Graham, All Rights Reserved.

This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
