File Coverage

blib/lib/Maypole/Plugin/LinkTools.pm
Criterion Covered Total %
statement 6 47 12.7
branch 0 24 0.0
condition 0 25 0.0
subroutine 2 7 28.5
pod 5 5 100.0
total 13 108 12.0


line stmt bran cond sub pod time code
1             package Maypole::Plugin::LinkTools;
2              
3 1     1   26039 use warnings;
  1         2  
  1         32  
4 1     1   6 use strict;
  1         2  
  1         3692  
5              
6             our $VERSION = '0.21';
7              
8             =head1 NAME
9              
10             Maypole::Plugin::LinkTools - convenient link construction
11              
12             =head1 SYNOPSIS
13              
14             use Maypole::Application qw( LinkTools );
15            
16             #...
17            
18             print $request->maybe_link_view( $thing );
19            
20             print $request->maybe_many_link_views( @things );
21            
22             print $request->link( table => $table,
23             action => $action, # called 'command' in the original link template
24             additional => $additional, # optional - generally an object ID
25             label => $label,
26             );
27            
28             print $request->make_path( table => $table,
29             action => $action, # called 'command' in the original link template
30             additional => $additional, # optional - generally an object ID
31             );
32            
33            
34             =head1 DESCRIPTION
35              
36             Provides convenient replacements for the C and C templates, and a new
37             C method.
38              
39             Centralises all path manipulation, so that a new URI scheme can be implemented site-wide by
40             overriding just two methods (C and C).
41              
42             For ease of use with the Template Toolkit, C, C and
43             C will also accept a hashref of arguments. For example:
44              
45             print $request->make_path({ table => $table,
46             action => $action,
47             additional => $additional,
48             });
49              
50             =head1 METHODS
51              
52             =over 4
53              
54             =item make_path( %args or \%args )
55              
56             This is the counterpart to C. It generates a path to use in links,
57             form actions etc. To implement your own path scheme, just override this method and C.
58              
59             %args = ( table => $table,
60             action => $action, # called 'command' in the original link template
61             additional => $additional, # optional - generally an object ID
62             );
63              
64             C can be used as an alternative key to C.
65              
66             =cut
67              
68             # TODO:
69             # C<$additional> can be a string, an arrayref, or a hashref. An arrayref is expanded into extra
70             # path elements, whereas a hashref is translated into a query string.
71             sub make_path
72             {
73 0     0 1   my $r = shift;
74 0 0 0       my %args = (@_ == 1 && ref $_[0] && ref $_[0] eq 'HASH') ? %{$_[0]} : @_;
  0            
75              
76 0 0         do { die "no $_" unless $args{ $_ } } for qw( table
  0            
77             action
78             );
79              
80 0           my $base = $r->config->uri_base;
81 0 0         $base = '' if $base eq '/';
82              
83 0   0       $args{additional} ||= $args{id};
84 0 0         my $add = $args{additional} ? "/$args{additional}" : '';
85            
86 0           return sprintf '%s/%s/%s%s', $base, $args{table}, $args{action}, $add;
87             }
88            
89             =item link( %args or \%args )
90              
91             Returns a link, calling C to generate the path.
92              
93             %args = ( table => $table,
94             action => $action, # called 'command' in the original link template
95             additional => $additional, # optional - generally an object ID
96             label => $label,
97             );
98              
99             The table can be omitted and defaults to that of the request's model.
100             C can be used as an alternative key to C.
101              
102             =cut
103              
104             sub link
105             {
106 0     0 1   my $r = shift;
107 0 0 0       my %args = (@_ == 1 && ref $_[0] && ref $_[0] eq 'HASH') ? %{$_[0]} : @_;
  0            
108            
109 0   0       $args{table} ||= $r->model_class->table;
110 0   0       $args{label} ||= '...'; # in case a stringify column is left empty
111            
112 0           foreach my $key ( qw( table action ) )
113             {
114 0 0 0       die sprintf "link: no %s (got table: %s action: %s label: %s)",
      0        
      0        
115             $key, $args{table} || '', $args{action} || '', $args{label} || ''
116             unless $args{ $key };
117             }
118            
119 0           my $path = $r->make_path( %args );
120            
121 0           return sprintf '%s', $path, $args{label};
122             }
123              
124             =item link_view( $thing or %args or \%args )
125              
126             Build a link to the C action of the given item.
127             If passed a Maypole request object, builds a link to its C action.
128              
129             print $request->link_view( $maypole_request );
130            
131             print $request->link_view( table => $table,
132             label => $label,
133             additional => $id,
134             );
135            
136             =cut
137              
138             sub link_view
139             {
140 0     0 1   my $r = shift;
141            
142 0           my %args;
143            
144 0 0         if ( @_ == 1 )
145             {
146 0 0         die "single argument to link_view() must be a reference (got $_[0])" unless ref $_[0];
147            
148 0 0         if ( ref $_[0] eq 'HASH' )
    0          
149             {
150 0           %args = %{ $_[0] };
  0            
151             }
152             elsif ( UNIVERSAL::isa( $_[0], 'Maypole::Model::Base' ) )
153             {
154 0           my $object = shift;
155            
156 0           my $str = ''.$object;
157 0 0         warn sprintf "%s (id: %s) object has no data for stringification", ref($object), $object->id unless $str;
158 0   0       $str ||= '...';
159            
160 0           %args = ( table => $object->table,
161             additional => $object->id,
162             label => $str,
163             );
164             }
165             else
166             {
167 0           die "unsuitable single argument to link_view (got $_[0]) - need hashref or Maypole/CDBI object";
168             }
169             }
170             else
171             {
172 0           %args = @_;
173             }
174            
175 0           return $r->link( %args, action => 'view' );
176             }
177              
178             =item maybe_link_view( $thing )
179              
180             Returns stringified C<$thing> unless it isa C object, in which case
181             a link to the view template for the object is returned.
182              
183             =cut
184              
185             sub maybe_link_view
186             {
187 0     0 1   my ( $r, $thing ) = @_;
188            
189 0 0 0       if ( ref $thing and UNIVERSAL::isa( $thing, 'Maypole::Model::Base' ) )
190             {
191 0           return $r->link_view( $thing );
192             }
193             else
194             {
195 0           return ''.$thing;
196             }
197             }
198              
199             =item maybe_many_link_views
200              
201             Runs multiple items through C, returning a list.
202              
203             =cut
204              
205             # if the accessor is for a has_many relationship, it might return multiple items, which
206             # would each be passed individually to maybe_link_view(), and then each would go in its
207             # own column. Instead, we want a list of items to put in a single cell.
208             sub maybe_many_link_views
209             {
210 0     0 1   my ( $r, @values ) = @_;
211            
212 0           return map { $r->maybe_link_view( $_ ) } @values;
  0            
213             }
214              
215              
216              
217             =back
218              
219             =head1 AUTHOR
220              
221             David Baird, C<< >>
222              
223             =head1 BUGS
224              
225             Please report any bugs or feature requests to
226             C, or through the web interface at
227             L.
228             I will be notified, and then you'll automatically be notified of progress on
229             your bug as I make changes.
230              
231             =head1 ACKNOWLEDGEMENTS
232              
233             =head1 COPYRIGHT & LICENSE
234              
235             Copyright 2005 David Baird, All Rights Reserved.
236              
237             This program is free software; you can redistribute it and/or modify it
238             under the same terms as Perl itself.
239              
240             =cut
241              
242             1; # End of Maypole::Plugin::LinkTools