Jifty

 view release on metacpan or  search on metacpan

lib/Jifty/Manual/Actions.pod  view on Meta::CPAN

    use strict;

    package MyApp::Action::DoNothing;
    use base qw/MyApp::Action Jifty::Action/;

    1;

(Instead of copying-and-pasting that, or typing it in, though, you
could just run:

    jifty action --name DoNothing

in your application's directory, and Jifty would create a skeleton for
you. )

However, if you want to actually do something with your actions, you
need to define two things: their L<parameters|/parameters>, and a
L</take_action> method.

=head2 parameters

Every C<Jifty::Action> subclass should define a C<schema>, which contains
some C<param> declarations that describe what arguments it takes.
Supposing we were writing an action to post a blog article, we might start
out with parameters like thus:

    use Jifty::Param::Schema;
    use Jifty::Action schema {

    param 'title';
    param 'category';
    param 'body';

    };

However, we've only scratched the surface of the power the
C<param> API offers.  Parameters can have types, labels,
validators, canonicalizers, and even more. To start with, let's add
some types and labels:

    use Jifty::Param::Schema;
    use Jifty::Action schema {

    param title =>
        label is 'Title',
        max_length is 50,
        is mandatory;

    param category => 
        label is 'Category',
        max_length is 30;

    param body =>
        label is 'Entry',
        render as 'Textarea';

    };

Now, we can ask the action to render form fields, and it will know how
to display them. But, we can do even better. Let's improve the look of
that C<category> field, by making it a combobox (a combination
dropdown/text field), with some default values available:

    # ...
    param category => 
        label is 'Category',
        render as 'Combobox',
        available are qw( Personal Work Block );
    # ...

But a static list is lame. What we really want is a C<Category> model,
and to keep track of all the categories users have entered:

    # ...
    param categories => 
        label is 'Category',
        render as 'Select',
        available are defer {
            my $categories = MyBlog::Model::CategoryCollection->new;
            $categories->unlimit;
            [{
                display_from => 'name',
                value_from   => 'name',
                collection   => $categories,
            }];
        }
    ...

Now, Jifty will populate the combobox with the result of calling C<name>
on each element in C<$categories>. Alternatively, if you set
C<< value_from => 'id' >>, Jifty would automatically return the C<id> of
the category, for easy database reference. We don't do this with the
combobox, however, since a combobox displays the selected value in its
text field.

See L<Jifty::Action> and L<Jifty::Web::Form::Field> for more fields
you can set in the C<param> declaration, and see L<Jifty::Param::Schema>
for more about the syntax.

=head2 validation

C<Jifty::Action> can automatically validate arguments for you, as
appropriate. If an argument has C<valid_values>, then C<Jifty::Action>
will automatically verify if the given value matches one of
them. However, you can also write your own validators. Just write a
C<< sub validate_<parameter> >>, and it will be called as appropriate:

    use Regexp::Common 'profanity_us';

    sub validate_body {
       my $self = shift;
       my $body = shift;

       if ( $body =~ /$RE{profanity}/i) {
           return $self->validation_error(
               body => 'Would you speak like that in front of your mother? *cough*'
           );
       }
       return $self->validation_ok('body');
    }


Your C<< validate_<parameter> >> method will be called with the value of C<<
<parameter> >> followed by two hash references. The first is a hash reference
of the full set of arguments passed along with C<< <parameter> >> to permit
more advanced validation. For example you could forbid profanity only if the
content is C<rated> for all ages. The final parameter is another hash reference
of extra metadata. The C<for> key will be set to C<create> or C<update> to give
you still more control.

You can also do validation in the model -- see L<Jifty::Action::Record>.

=head2 canonicalization

If, instead of failing, you want to automatically modify
invalid content to be valid, you want a
L<canonicalizer|Jifty::Manual::Glossary/canonicalize>, not a
validator.

    use Regexp::Common 'profanity_us';

    sub canonicalize_body {
       my $self = shift;
       my $body = shift;
       $body =~ s/$RE{profanity}/**expletives**/gi;
       return $body;
    }

Note that the parameters (value, all parameters, metadata) are the same as in
L</validation>.

A L<canonicalizer|Jifty::Manual::Glossary/canonicalize> can also
change other parts of the action.  This lets you update the display



( run in 1.289 second using v1.01-cache-2.11-cpan-5a3173703d6 )