Provided by: libjifty-perl_1.10518+dfsg-1ubuntu2_all bug

NAME

       Jifty::Manual::Actions - eXX Jifty aaXXaeXX

DESCRIPTION

       "Jifty::Action" aeXXeXXaeXXeXXaeXXaeXXcXXeXaeXXaeXX (compile time)
       aaXXaaXXaaXXaeXXcXXaeXXaeXX ("parameters").

       aaXXaaXXeXXaeXXaeXX (runtime)ieXXaaXXaeXX (Action)
       aeXXaeXXeXXaeXXcXXeXXeXXaaXXeXXaeXXaaXXcXXaaXXaeXX ("arguments"),
       aeXXeXXcXXaeXXaeXXaeXXaeXXieXXaeXXaaXXaaXXaaXXcXXaeXXcXXaeXXcXXeXXa~XX

       aaXXaeXXeXXaeXXeXXeXXaeXXaaXXaaXXaaXXaeXXeXXieXXeXXaeXXaaX cXX --
       aaXXaeXX (Action) aaXXaaXXaaXXaeXXaaXXaeXXaaXX Jifty
       eXXcXXaeXXaeXXaeXXaeXXaeXXa~XX

       "Jifty::Action" aaXXaeXXaeXXaeXXcXXaeX aaXXaaXXaeXXcXXcXX HTML --
       aeXXeXXeXXeXXaaXXaeXXaaXXaaXX "<input>" aeXXcXX
       aeXXaeXXaeXXaaXXeXXcXXcXX GET aeXX POST aaXXaaXXcXXaaXXaeXXieXXaeXXaeXX
       Jifty aeXXeXXaaXXaaXXaeX aeXXaeXXaaXXcXXeXXaaXXaaXXaeXXaaXXcXXaaXXaeXX
       cXXaaXXaeXX (Action)a~XX "Jifty::Action"
       cXXaeX aaXXaeXXaeXXaeXXaeXXeXXaaXXcXXaeXXaeXXa~XX

aaXXaeXXaaXX Action

       Jifty aaXXcXXaeXXaeXXaeXXaeXXaeXXe XeXcXXeXXcXX (Action) cXXaeX  --
       aaXXaaXXeXX Jifty::Manual::ObjectModel aeXXaaXXaaXX
       Jifty::Action::Record aeXXaeXXaaXXaeXXcXXcXXcXXeXXcXX (Action)
       aaXXaaXXeXXaeXXaaXXaeXX Jifty::Action::Redirect,
       aeXXeXXaeXXaeXXaeXXcXXcXXcXXaaXXeXXaeXXeXXeXXaaXXcXXaeXXaaXXeXXaaXXeXXeXXcXXeXXcXX
       (Action).
       eXXaaXXaeXXeXXeXXaeX eXXaaXXaeXXaaXXaeX aaXXaeXXaeX cXXeXXcXX (Action).

       aeXXaeXXaaXXeXXcXXieXXeXXaeXX Jifty::Action cXXaa-
       XeXXaaXXieXXaaXXaaXXcXXaaXXaeXX AppName::Action.

       eXXcXXeXXaaXXeXXaeXXeXXaaXaeXXaaXX AppName::Action::
       cXXaaXXcXXcXXeXXaeX; while that's just a convention, it will make your
       life easier if you follow it.

       This, the simplest possible action, is:

           use warnings;
           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 parameters, and a "take_action"
       method.

   parameters
       Every "Jifty::Action" subclass should define a "schema", which contains
       some "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 "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 "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 "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 "name"
       on each element in $categories. Alternatively, if you set "value_from
       => 'id'", Jifty would automatically return the "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 Jifty::Action and Jifty::Web::Form::Field for more fields you can
       set in the "param" declaration, and see Jifty::Param::Schema for more
       about the syntax.

   validation
       "Jifty::Action" can automatically validate arguments for you, as
       appropriate. If an argument has "valid_values", then "Jifty::Action"
       will automatically verify if the given value matches one of them.
       However, you can also write your own validators. Just write a "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');
           }

       You can also do validation in the model -- see Jifty::Action::Record

   canonicalization
       If, instead of failing, you want to automatically modify invalid
       content to be valid, you want a canonicalizer, 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;
           }

       A canonicalizer can also change other parts of the action.  This lets
       you update the display dynamically in an AJAX-enabled browser based on
       what the user has entered.  For example, we can let a user use magic
       syntax to provide tags for their blog post by surrounding the tags with
       square brackets.  You can also let the user know you're doing something
       magical by using "canonicalization_note" which will display a message
       to the user.

           use Jifty::Param::Schema;
           use Jifty::Action schema {
               param title =>
                   label is 'Title',
                   hints is "You can provide tags like this [tag1 tag2]",
                   ajax canonicalizes;

               param tags =>
                   label is 'Tags';
           };

           sub canonicalize_title {
               my $self = shift;
               my $value = shift;

               if ($value =~ s/\[(.*?)\]//) {
                   # this clobbers, may want to merge
                   $self->argument_value( tags => $1 );
                   $self->canonicalization_note(
                       title => 'Removed tags from your title'
                   );
               }

               return $value;
           }

       If you set "ajax validates" or "ajax canonicalizes" for an argument,
       then Jifty will automatically validate or canonicalize it in an
       AJAX-enabled browser when the user stops typing and puts the focus out
       of the corresponding form field.

   take_action
       Once an action has arguments, it needs to do something with them. An
       action does so in its "take_action" sub, which will be called when an
       action is submitted, and only if its arguments validate.

       Inside "sub take_action", subclasses can access their arguments via
       "$self->argument_value('foo')". If you need to check whether you've
       been passed an argument or not (as opposed to being passed a true
       argument or not), use "$self->has_argument('foo')".

       Once an action has done its task, it needs to inform the caller whether
       or not it has succeeded, possibly with some status message. To this
       end, every "Jifty::Action" has a "Jifty::Result" associated with.
       "Jifty::Result" carries both a failure/sucess code, and a textual
       message describing the result of running the action.

       Thus, if your action failed for some reason, you would, in
       "take_action", write code like:

           $self->result->error('Could not write blog post');
           return;

       If, however, the action completed successfully, you might write:

           $self->result->message('Posted to your blog');

       Actions will default to successful with an empty message if you don't
       do anything with the result object. Additionally, if you need to return
       more semantic information than a simple message, you can set arbitrary
       content on the result, using $self->result->content, e.g:

           $self->result->content( id => $new_post->id);

       This information can be then used elsewhere to, for example,
       automatically redirect you to a view page for that new blog post. The
       view page template may have the following piece of code in it:

           <%args>
           $id => undef
           </%args>
           <%init>
           my $result = Jifty->web->response->result('post_blog');
           $id = $result->content('id') if $result and !defined $id;
           # load the record by $id and other stuff go here...
          </%init>

       where 'post_blog' is the moniker for your post page action object.  In
       fact, that's exactly how actions "return" values to other components in
       your application.

       Multiple action "return values" are possible and arbitrary data
       structures can be passed too:

           $self->result->content( keys   => $keys );
           $self->result->content( result => $collection);

       It should also be mentioned that the response object is "per request".
       That is, it usually can't live up to another user request. Therefore,
       when paging mechanism is applied to your view page, for example, you
       have to either pass some data to the link constructor or explicitly
       tell Jifty to preserve states for you.

       See "monikers", the Jifty Pony site's source, and
       Jifty::Request::Mapper for some more information.

USING ACTIONS

       At their simplest, you can create and run actions yourself, e.g.:

           Jifty->web->new_action(
               class     => 'PostBlogEntry',
               arguments => {
                   title    => 'A boring blog entry',
                   category => 'Jifty',
                   body     => 'This blog entry is lame.'
               }
           )->run;

       Note that "Jifty->web->new_action", and all similar methods (e.g.
       Jifty::Request::add_action, Jifty::Web::Form::add_action), will
       automatically qualify the "class" with either "Jifty::Action::" or
       "AppName::Action::" as necessary (I've told you putting actions in
       AppName::Action:: would make your life easier!)

       In practice, you'll rarely provide actions with arguments yourself.
       Instead, you'll create an action with no or partial arguments, often in
       the dispatcher, or a Mason component's "<%init%>" block (See
       "constructor arguments" for details about passing arguments to actions
       on creation).

           my $create = Jifty->web->new_action(
               class   => 'PostBlogEntry',
               moniker => 'post_blog'
           );

       Having created the action, you will, in one of your Mason components,
       output a form where the user can fill in the action's arguments:

           <% Jifty->web->form->start %>
           <div class="post-metadata">
             <% $create->form_field('title') %>
             <% $create->form_field('category') %>
           </div>
             <% $create->form_field('body') %>
           <% Jifty->web->form->submit(label => "Post") %>
           %# or <% Jifty->web->link(label => "Post", submit => $create) %>
           %# or <% $action->button(label => "Post"); %>
           <% Jifty->web->form->end %>

       "form_field" will render the field, along with the "label" as an HTML
       "<input>" tag that Jifty knows how to interpret to feed back to your
       action as an argument when the form is submitted. If you need to change
       the appearance of the field, Jifty outputs classes on the fields, as
       well as providing some semantic "<div>"s you can style using CSS. (See
       Jifty::Manual::UsingCSSandJS for some more details.)

       See "submit" in Jifty::Web::Form, "link" in Jifty::Web and "button" in
       Jifty::Action for details on the different ways to generate a submit
       button.

       Additionally, instead of "form_field", you can use "hidden" to generate
       a "hidden" input, which will not be viewable or editable in a web
       browser. (Note that a knowledgeable user can still submit a form with a
       different value for that hidden input; If this concerns you, make sure
       you have appropriate ACLs in place. If it still worries you, you
       probably want a continuation here.)

   monikers
       You probably noticed the "moniker => 'post_blog'". Every action you
       create in Jifty has an associated moniker. A "moniker" is simply a
       unique identifier for the action (unique per request, which in practice
       typically means per HTML page). Since actions are constantly being
       serialized (over HTTP, or Javascript AJAX calls, and so on), and
       unpacked, we need a way refer to specific actions other than just
       object identity, e.g. to extract its arguments or results in the
       dispatcher or a template. Monikers give us that. Given a moniker, you
       can pull information about the associated action out of a request or
       response.

       If a moniker is unspecified, it will be autogenerated.

       (XXX TODO Note about action registration here)

   Argument Folding
       If you write out more than one "form_field" for a given argument in the
       same form, and more than one is filled in, Jifty will "fold" the
       arguments into an array before filling them in to the action. This
       provides a way to do, e.g. a "BulkEdit" action that applies some set of
       changes to many records at once.

       (XXX TODO Note about "constructor" parameters)

ACTIONS AS WEB SERVICES

       Your actions are also automatically published as web services.  Clients
       can POST requests, usually using the YAML or JSON request format.  See
       "bin/service" for a trivial generic webservice client.

       (XXX TODO More about webservices)

SEE ALSO

       Jifty::Action, Jifty::Manual::Tutorial