some more doc patches
[catagits/Reaction.git] / lib / Reaction / UI / ViewPort / Role / Actions.pm
1 package Reaction::UI::ViewPort::Role::Actions;
2
3 use Reaction::Role;
4 use Reaction::UI::ViewPort::URI;
5
6 use namespace::clean -except => [ qw(meta) ];
7
8 has actions => (
9   is => 'ro',
10   isa => 'ArrayRef',
11   lazy_build => 1
12 );
13
14 has action_order => (
15   is => 'ro',
16   isa => 'ArrayRef'
17 );
18
19 has action_prototypes => (
20   is => 'ro',
21   isa => 'HashRef',
22   required => 1,
23   default => sub{ {} }
24 );
25
26 has computed_action_order => (
27   is => 'ro',
28   isa => 'ArrayRef',
29   lazy_build => 1
30 );
31
32 sub _build_computed_action_order {
33   my $self = shift;
34   my $ordered = $self->sort_by_spec(
35     ($self->has_action_order ? $self->action_order : []),
36     [ keys %{ $self->action_prototypes } ]
37   );
38   return $ordered ;
39 }
40
41 sub _build_actions {
42   my ($self) = @_;
43   my (@act, $i);
44   my $ctx = $self->ctx;
45   my $loc = $self->location;
46   my $target = $self->model;
47
48   foreach my $proto_name ( @{ $self->computed_action_order } ) {
49     my $proto = $self->action_prototypes->{$proto_name};
50     my $uri = $proto->{uri} or confess('uri is required in prototype action');
51     my $label = exists $proto->{label} ? $proto->{label} : $proto_name;
52
53     my $action = Reaction::UI::ViewPort::URI->new(
54       location => join ('-', $loc, 'action', $i++),
55       uri => ( ref($uri) eq 'CODE' ? $uri->($target, $ctx) : $uri ),
56       display => ( ref($label) eq 'CODE' ? $label->($target, $ctx) : $label ),
57     );
58     push(@act, $action);
59   }
60   return \@act;
61 }
62
63 1;
64
65 __END__;
66
67 =head1 NAME
68
69 Reaction::UI::ViewPort::Role::Actions
70
71 =head1 DESCRIPTION
72
73 A role to ease attaching actions to L<Reaction::InterfaceModel::Object>s
74
75 =head1 ATTRIBUTES
76
77 =head2 actions
78
79 Automatically built ArrayRef of URI objects pointing to actions
80
81 =head2 action_prototypes
82
83 A HashRef of prototypes for building the Action links. The prototypes should be
84 composed like these:
85
86     my %action_prototypes = (
87       example_action => { label => 'Example Action', uri => $uri_obj },
88     );
89
90     #or you can get fancy and do something like what is below:
91     sub make_label{
92       my($im, $ctx) =  @_; #InterfaceModel::Object/Collection, Catalyst Context
93       return 'label_text';
94     }
95     sub make_uri{
96       my($im, $ctx) =  @_; #InterfaceModel::Object/Collection, Catalyst Context
97       return return $ctx->uri_for('some_action');
98     }
99     my %action_prototypes = (
100       example_action => { label => \&make_label, uri => \&make_uri },
101     );
102
103 =head2 action_order
104
105 User-provided ArrayRef with how the actions should be ordered eg
106
107      action_order => [qw/view edit delete/]
108
109 =head2 computed_action_order
110
111 The final computed action order. This may differ from the action_order provided
112 if you didn't list all of the actions in that.
113
114 =head1 AUTHORS
115
116 See L<Reaction::Class> for authors.
117
118 =head1 LICENSE
119
120 See L<Reaction::Class> for the license.
121
122 =cut