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

NAME

Wizard -- making multipart (e.g. wizard) actions: registering an user via several steps, submit something large (like application forms).

SYNOPSIS

    # if this called without previous wizard (i.e. new wizard) then
    # creating wizard with '/users/list' as first step and '/users/last' as second
    # otherwise append steps '/users/list' and '/users/last' if they wasn't added alread
    $c->wizard('/users/last', '/users/list');

    # going next step ('/users/list');
    $c->wizard->goto_next;

    # creating wizard with 'correct' (left to right) steps order
    $c->wizard(-first => '/users/list', '/users/last');
    $c->wizard->goto_next;

    # appending step '/users/list' and '+/users/list' -- this will add '/users/list' into wizard twice
    # you can prepend first '/' with any symbols you like -- just to make your step unique, so it will be added
    # into wizard
    $c->wizard(-first => '/users/list', '+/users/list', '/users/last');
    $c->wizard->goto_next; # to /users/list
    $c->wizard->goto_next; # again to /users/list

Something more real:

    package App;

    use strict;
    use warnings;

    use Catalyst qw/
        Session
        Session::Store::Dummy
        Session::State::Cookie

        Wizard
    /;

    # we assume stash automagically saves into wizard and restores from it
    __PACKAGE__->config({ wizard => { autostash => 1, autoactivate => 1 }});

    __PACKAGE__->setup;

    1;

    
    package App::C::First;

    use strict;
    use warnings;

    sub edit : Local {
        my ($self, $c) = @_;
        
        # goto 'login' wizard unless you are loggedin
        return $c->wizard(-first => '/first/login', '/first/edit')->goto_next unless $c->session->{loggedin};

        $c->res->body('OK!');
    }

    # draw login form
    sub login : Local {
        my ($self, $c) = @_;

        # adding destination of form as step
        $c->wizard('/first/login_submit');

        # dont forget to append wizard id into that form, and also use wizard->next call to
        # get action for form
        $c->res->body(<<EOF);
    <html>
        <head>
            <title>Test login</title>
        </head>
        <body>
            @{[delete $c->stash->{error} || '']}
            <form name="login" action="@{[ $c->wizard->next ]}">
                @{[ $c->wizard->id_to_form ]}
                <input name="username">
                <input name="password" type="password">
            </form>
        </body>
    </html>
    EOF

        $c->res->content_type('text/html');
    }

    # check login submited
    sub login_submit : Local {
        my ($self, $c) = @_;

        my $p = $c->req->params;

        # check if username and password are correct
        if ($p->{username} eq 'user' && $p->{password} eq 'userpassword') {
            $c->session->{loggedin} = 1;
            # ok, goto next ('/first/edit') in this example
            $c->wizard->goto_next;
        } else {
            $c->stash->{error} = 'Incorrect login'; 
            # incorrect, back to login page.
            $c->wizard->detach_prev(2);
        }
    }

    1;

DESCRIPTION

This plugin provides functionality for making multipart actions (wizards) more easily.

For example, you may need this plugin in following cases:

  • When you need to move some items into another folder, you may: 1) keep current folders select in session, 2) use it as wizard and keep that info in wizard (or stash)

  • When you need to deatch users into login page (see SYNOPSIS)

METHODS

CATALYST METHODS

$c->wizard(...)

Returns new wizard (Catalyst::Plugin::Wizard::Instance), existing one with steps you gave inserted into middle of flow, or undef, if no wizards are defined/seted.

When called without arguments it also 'activates' wizard (copying stash from wizard to catalyst if configured so, etc). You can configure plugin so your current active wizard will be autoactivated.

It takes step as an argument. Each step can be prefixed with keyword, which alerts plugin how to work out this step. E.g. you use '/first/step' with some -prefixes => '/first/step'.

Step prefixes:

Default behavior

Appends steps as an 'redirect' steps. Calling goto_next will cause 'redirect' jump into it.

NOTE: Last step in $c->wizard will be called first (like in stack), except for following case.

-first

MUST BE first in the chain. Signals that this $c->wizard call have steps arranged in left-to-right order.

-default

Addes -default target in step (called when all other steps are done).

-detach or -forward

Detaches or forwards to this step. Step can be either an simply string with action private path or arrayref within which $c->detach (or $c->forward) will be called.

-force

Forces adding step into wizard. Step will be added even if it already have been added into that wizard. Use carefully! It can cause bugs!

$c->start_wizard

Starts wizard with steps from arguments.

$c->stop_wizard

Stop current wizard.

$c->redirect_next_action($default_url)

Redirect to next action or to $default_url if no wizard exists or all wizard steps passed.

$c->detach_next_action($default_url)

Detaches to next action or to $default_url if no wizard exists or all wizard steps passed.

$c->forward_next_action($default_url)

Forwards to next action or to $default_url if no wizard exists or all wizard steps passed.

WIZARD METHODS (called via $c->wizard->...)

$c->wizard->add_steps(...)

Used to add steps (within $c->wizard(...) args). You can use it if you won't need to create new wizard. Args: same as for $c->wizard(...) call.

$c->wizard->detach/forward/redirect

Detaches forwards or redirects to next step. You explicity select jump type.

$c->wizard->goto_next

Goto to next step in wizard (jump type -- forward, deatch or redirect -- decided automagically).

$c->wizard->next

Returns next destination -- arrayref for forward/deatch or string with action path for redirects (returns URI via subwizard id attached in case of subwizard)

$c->wizard->next_or_default

Returns $c->wizard->next or default step.

$c->wizard->last

Returns last visited step (gets it from subwizard, if last step was from it).

$c->wizard->detach_prev($back)

Detaches $back steps back.

$c->wizard->redirect_prev($back)

Redirects $back steps back.

ACCESSORS

$c->wizard->data({...}) or $c->wizard->data->{...}

Data in wizard. Can be called within hashref as first argument to override current data. Returns hash with data.

$c->wizard->add(key1 => val1, key2 => val2) (synonym: $c->wizard->set)

Sets key/value pairs in wizard data hash.

$c->wizard->get(key)

Gets entry from data hash with key.

$c->wizard->stash({...}) or $c->wizard->stash->{...}

Stash in wizard. Can be copyed from $c via $c->wizard->copy_stash call (or automagically if configured so). Note that wizard stash will be copyed into $c only on next step.

$c->wizard->add_stash(key1 => val1, key2 => val2) (synonym: $c->wizard->set_stash())

Adds key/value pairs into wizard's stash.

$c->wizard->get_stash(key)

Gets stash value named key from wizard's stash.

$c->wizard->params({...} or $c->wizard->params->{...}

Params in wizard. Same as stash in wizard. Note that this will be copied into $c only on next step.

SEE ALSO

Catalyst::Plugin::Continuation, Catalyst::Plugin::Session.

AUTHOR

Pavel Boldin <boldin.pavel@gmail.com>