NAME
    CatalystX::Controller::Sugar - Sugar for Catalyst controller

VERSION
    0.09

DESCRIPTION
    This module is written to simplify the way controllers are written. I
    personally think that shifting off $c and $self in every action is
    tidious. I also wanted a simpler API to created chained actions, since I
    rarely use any other actions - except of "private".

SYNOPSIS
      package MyApp::Controller::Root;
      use CatalystX::Controller::Sugar;
 
      __PACKAGE__->config->{'namespace'} = q();
 
      # Private action
      private authenticate => sub {
        c->user_exists and return 1;
      };
 
      # Chain /
      chain sub {
        report debug => 'Someone tries to access %s', c->action;
      };

      # Endpioint /*
      chain '' => sub {
        res->body('not found');
      };

      # Endpoint /login
      chain login => {
        get => sub {}, # show template
        post => sub {
          forward 'authenticate' and go '';
        },
      };
 
      # Chain /user/[id]/*
      chain user => ['id'], sub {
        stash user => c->model('DB::User')->find($_[0]);
      };
 
      # Endpoint /user/[id]/view/*
      chain 'user:1' => view => sub {
        res->body(
          sprintf 'Person is called: %s', stash->{'user'}->name
        );
      };

  Same with standard Catalyst syntax
      package MyApp::Controller::Root;
      use Moose;
      BEGIN { extends 'Catalyst::Controller' }
 
      __PACKAGE__->config->{'namespace'} = q();
 
      # Private action
      sub authenticate :Private {
        my($self, $c) = @_;
        $c->user_exists and return 1;
      }
 
      # Chain /
      sub root :Chained("/") PathPart("") CaptureArgs(0) {
        my($self, $c) = @_;
        $c->log->debug(sprintf 'Someone tries to access %s', $c->action);
      }

      # Endpioint /*
      sub default :Chained("/root") PathPart("") Args {
        my($self, $c) = @_;
        $c->res->body('not found');
      }

      # Endpoint /login
      sub login :Chained("/root") PathPart Args {
        my($self, $c) = @_;

        if(lc $c->req->method eq 'get') {
          return; # show template
        }
        elsif(lc $c->req->method eq 'post') {
          $c->forward('authenticate') and go('');
        }
      }
 
      # Chain /user/[id]/*
      sub user :Chained("/root") PathPart CaptureArgs(1) {
        my($self, $c, $id) = @_;

        $c->stash->{'id'} = $id; # alternative to captured('id');
        $c->stash->{'user'} = $c->model('DB::User')->find($id);
      }
 
      # Endpoint /user/[id]/view/*
      sub user_view :Chained("/user") PathPart('view') Args {
        my($self, $c) = @_;
        $c->res->body(sprintf 'Person is called: %s', $c->stash->{'user'}->name);
      }

  NOTE
    $self and $c is not part of the argument list inside a chain() or
    private() action. $c is acquired by calling c(), and $self is available
    by calling controller().

EXPORTED FUNCTIONS
  chain
     1. chain sub { };

     2. chain $PathPart => sub { };
     3. chain $PathPart => $Int, sub { };
     4. chain $PathPart => \@CaptureArgs, sub { };

     5. chain $Chained => $PathPart => sub { };
     6. chain $Chained => $PathPart => $Int, sub { };
     7. chain $Chained => $PathPart => \@CaptureArgs, sub { };

     8. chain ..., \%method_map;

     9. chain ANY => \%extra_args => sub { };

    Same as:

     1. sub root : Chained('/') PathPart('') CaptureArgs(0) { }

     2. sub $PathPart : Chained('/root') Args { }
     3. sub $PathPart : Chained('/root') Args($Int) { }
     4. sub $PathPart : Chained('/root') CaptureArgs($Int) { }

     5. sub $PathPart : Chained($Chained) Args { }
     6. sub $PathPart : Chained($Chained) Args($Int) { }
     7. sub $PathPart : Chained($Chained) CaptureArgs($Int) { }

     8. Special case: See below
     9. Special case: See below

    @CaptureArgs is a list of names of the captured arguments, which can be
    retrieved using captured().

    $Int is a number of Args to capture at the endpoint of a chain. These
    cannot be aquired using captured(), but is instead available in @_.

    %method_map can be used if you want to dispatch to a specific method,
    for a certain HTTP method: (The HTTP method is in lowercase)

     %method_map = (
        post => sub { ... },
        get => sub { ... },
        delete => sub { ... },
        default => sub { ... },
        #...
     );

    %extra_args can be used to override information. Example:

        { name => 'foo' }

    Specifying "name" will replace the default name for this action, with
    "foo" (or something else).

  private
     private $name => sub {};

    Same as:

     sub $name :Private {}

  forward
     @Any = forward $action;
     @Any = forward $action, \@arguments;

    See Catalyst::forward().

  go
     go $action;
     go $action, \@arguments;

    See Catalyst::go().

  c
     $context_obj = c;

    Returns the context object for this request, an instance of Catalyst.

  controller
     $controller_obj = controller;

    Returns the current controller object.

  req
     $request_obj = req;

    Returns the request object for this request, an instance of
    Catalyst::Request.

  res
     $response_obj = res;

    Returns the response object for this request, an instance of
    Catalyst::Response.

  captured
     $value = captured($name);

    Retrieve data captured in a chain, using the names set with chain().

     chain '/' => 'user' => ['id'], sub {
       res->body( captured('id') );
     };

  stash
     $value = stash $key;
     $hash_ref = stash $key => $value, ...;
     $hash_ref = stash;

    Set/get data from the stash. The $hash_ref is a reference to what the
    stash is holding.

    This will be the same as:

     $c->stash->{$key} = $value;

  session
     $value = session $key;
     $hash_ref == session $key => $value;
     $hash_ref == session;

    Set/get data from the session. The $hash_ref is a reference to what the
    session is holding.

    This function will only work if a session module/plugin is loaded into
    Catalyst.

  report
     report $level, $format, @args;

    Almost the same as:

     $c->log->$level(sprintf $format, @args);

    But undef values from @args are turned into "__UNDEF__", and objects
    and/or datastructructures are flatten, using Data::Dumper.

  METHODS
  init_meta
    See Moose::Exporter.

BUGS
    Please report any bugs or feature requests to
    "bug-catalystx-controller-sugar at rt.cpan.org". I will be notified, and
    then you'll automatically be notified of progress on your bug as I make
    changes.

COPYRIGHT & LICENSE
    Copyright 2007 Jan Henning Thorsen, all rights reserved.

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

AUTHOR
    Jan Henning Thorsen, "<jhthorsen at cpan.org>"

