Catalyst-Plugin-Navigation

 view release on metacpan or  search on metacpan

MANIFEST  view on Meta::CPAN

1
2
3
4
5
6
7
8
9
10
11
12
13
lib/Catalyst/Plugin/Navigation.pm
lib/CatalystX/NavigationMenu.pm
lib/CatalystX/NavigationMenuItem.pm
Changes
t/02-pod-coverage.t
t/01-pod.t
t/03-perlcritic.t
t/01-pragmas.t
t/perlcriticrc
Makefile.PL
MANIFEST
README
META.yml                                 Module meta-data (added by MakeMaker)

lib/Catalyst/Plugin/Navigation.pm  view on Meta::CPAN

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
 
use strict;
 
 
use vars qw($VERSION);
$VERSION = '1.002';
 
after setup_finalize => sub {
        my ($self, @args) = @_;
 
        $self->mk_classdata('navigation');
        $self->navigation(CatalystX::NavigationMenu->new());
        $self->navigation->populate($self);
};
 
1;
 
__END__
 
=head1 NAME
 
Catalyst::Plugin::Navigation - A navigation plugin for Catalyst

lib/Catalyst/Plugin/Navigation.pm  view on Meta::CPAN

31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
  use Catalyst(qw/
    Navigation
  /);
 
  # When navigation needed.
  my $menu = $c->navigation->get_navigation($c, {level => 0});
 
  ...
 
  # When defining an action.
  sub new_action : Local Menu('Menu Title') MenuTitle('Menu Mouse Over Title')
                   MenuParent('#Menu Parent') MenuArgs('$stash_arg') {
    # Do action items.
    ...
  }
 
=head1 DESCRIPTION
 
The Catalyst::Plugin::Navigation plugin provides a way to define the navigation elements
and hierarchy within the Catalyst controllers. By defining the menu structure from the
controller attributes a controller can then ask for any level of menu and be presented
with the current chain to the active page as well as all other visable menus from the

lib/Catalyst/Plugin/Navigation.pm  view on Meta::CPAN

54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
in an external source this can be done from the infomation available from the controllers
themselves.
 
=head1 METHODS
 
When using the Catalyst::Plugin::Navigation plugin the following methods are added to the
base Catalyst object.
 
=head2 navigation()
 
Returns the CatalystX::NavigationMenu object that relates to the existing menu structure
defined through the controller attributes. See the L(CatalystX::MenuNavigation) man page
for more details.
 
=head1 Attributes
 
The following attributes are understood by the Catalyst::Plugin::Navigation plugin. The
Menu() attribute is the only required attribute. Without this attribute the action element
will not be included in the navigation tree.
 
=head2 Menu('Label')
 
This provides the label to be used for the menu link. This is the actual text of the href.
This item is required in order to have the action appear in the menu navigation.
 
=head2 MenuParent('Path')
 
Provides the path to the parent item. If the parent doesn't exist then it will be created
in the tree structure so that the child can be accessed even if the parent is never
defined. For more information on the Path value that can be passed see the PATHS section
below.
 
=head2 MenuArgs('Arg')
 
Provides informaiton on what to use to populate arguments and URI placeholders for the current
action. If the current action is chained or requires arguments then these are used to populate
the URI accordingly. The arguments are passed in the order they appear in the attribute list.
More than one MenuArgs attribute can be attached to a single action. If the argument is preceeded
by a $ symbol then the name of the argument is pulled from the stash variable. Otherwise the
argument is included as plain text. For example the following entry MenuArgs('$stash_value') will
call out and get the stash value for the keyword 'stash_value' ($c->stash->{'stash_value'}).
 
URL arguments are also handled with the MenuArgs() attribute. These are defined by preceeding
the argument with the @ symbol. The same rules above apply, so the argument @$var will use the var
value from the stash as a URL argument and @var will use the literal string var as the URL
argument.
 
=head2 MenuCond('Cond')
 
In order for the menu item to be included in the navigation display the condition provided must
evaluate to a true value. The argument ('Cond') value passed in is evaluated in an eval, allowing
complex conditions to be executed. More than one condition can be passed as an attribute, in which
case all conditions must evaluate to true.
 
=head2 MenuOrder(int)
 
Defines the order in which the menu elements shoudl be displayed. If you would like your menu
items to show up in a particular order you can define that order using the MenuOrder attribute.
In the event that more than one action has the same order value then they are sorted alphabetically
by their Menu label value.
 
=head2 MenuRoles('Role')
 
If you are using the Authentication::Roles plugin then you can define which roles must be
provided in order to display the given action in the navigation tree. If more than one
MenuRoles are included in the attributes list all those roles must be found. If you want
to show the menu item depending on one of several roles then you can separate those roles
with a | character. So the following attribute: MenuRoles('role1|role2|role3') will allow
the action to be included in the navigation tree if the logged in user has a role of either
role1, role2 or role3.
 
=head2 MenuTitle('Title')
 
Provides the value to use for the title attribute of the a link.
 
=head1 PATHS
 
The Catalyst::Pugin::Navigation plugin defines the navigation menu structure using a path
system. This allows you to define a complex path to reach a particular action. There are
a few ways to define path elements. In most instances you will just want to use the
path to the controller item as the path to an action (ie; controller_name/action_name).

lib/Catalyst/Plugin/Navigation.pm  view on Meta::CPAN

140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
  #Parent
    #Child
           /controller/entry
                  new_entry
 
When items are added into the navigation tree their defined by their namespace and action
name. This defines the private path to the entry. So future elements can be added into the
tree under an item by referring to the path of the entry it shoudl appear under.
 
There should be no need to include multiple path details in the MenuPath variable unless you
are defining Labels to be used. A Label can occur anywhere in the navigation entry. So both
of these paths are valid: #Label/path/to/action or /path/to/action/#Label.
 
=head1 DEPENDENCIES
 
L<Catalyst>
 
=head1 SEE ALSO
 
L<CatalystX::NavigationMenu>, L<CatalystX::NavigationMenuItem>
 
=head1 AUTHORS
 
Derek Wueppelmann <derek@roaringpenguin.com>
 
=head1 LICENSE AND COPYRIGHT
 
Copyright (c) 2011 Roaring Penguin Software, Inc.
 
This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

lib/CatalystX/NavigationMenu.pm  view on Meta::CPAN

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
 
use strict;
 
use Moose;
 
=head1 NAME
 
CatalystX::NavigationMenu
 
=head1 SYNOPSIS
 
        my $nm = CatalystX::NavigationMenu->new();
        $nm->popupate($c);
 
        my $menu = $nm->get_navigation($c, {level => 0});
 
=head1 DESCRIPTION
 
CatalystX::NavigationMenu provides a menu object to be used when creating and
managing menus in Catalyst based on attribute data. For details of the Catalyst
attributes see the L(Catalyst::Plugin::Navigation) documentation.
 
=cut
 
has items => (
        traits => ['Array'],
        is => 'rw',
        isa => 'ArrayRef[CatalystX::NavigationMenuItem]',
        default => sub{[]},
        handles    => {
                all_items    => 'elements',
                insert_item  => 'push',
                shift_item   => 'shift',
                find_item    => 'first',
                count_items  => 'count',
                has_items    => 'is_empty',
                sort_items   => 'sort',
        },

lib/CatalystX/NavigationMenu.pm  view on Meta::CPAN

56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
        my $dispatcher = $c->dispatcher;
        foreach my $c_name ($c->controllers(qr//)) {
                my $controller = $c->controller($c_name);
                my @actions = $dispatcher->get_containers($controller->action_namespace($c));
                $c->log->debug("Looking at Controller $c_name for navigation entries") if $c->debug;
 
                foreach my $ac (@actions) {
                        my $acts = $ac->actions;
                        foreach my $key (keys(%$acts)) {
                                my $action = $acts->{$key};
                                if ($action->attributes->{Menu}) {
                                        # And get the menu to insert it into the right location.
                                        $c->log->debug("Adding action item for path: " . ($action->namespace || '') . '/' . ($action->name || '') . " with parent: " .
                                                ($action->attributes->{MenuParent}->[0] || '') ) if $c->debug;
                                        $self->add_action($action);
                                }
                        }
                }
        }
}
 
=head2 add_action($action)
 
Adds an element into the menu based on the Catalyst action provided.
 
=cut
 
sub add_action {
        my ($self, $action) = @_;
 
        # Create the items needed to build the item.
        my $parent = $action->attributes->{MenuParent}->[0] || '';
        my $action_args = $action->attributes->{MenuArgs} || [];
        my $conditions = $action->attributes->{MenuCond} || [];
        my $order = $action->attributes->{MenuOrder}->[0] || 0;
        my $roles = $action->attributes->{MenuRoles} || [];
        my $title = $action->attributes->{MenuTitle}->[0] || '';
 
        my $item = CatalystX::NavigationMenuItem->new(
                label => $action->attributes->{Menu}->[0],
                title => $title,
                action => $action,
                path => $action->namespace . '/' . $action->name,
                parent => $parent,
                action_args => $action_args,
                conditions => $conditions,
                order => $order,
                required_roles => $roles,
        );
 
        $self->add_item($item);
}
 
=head2 get_child_with_path($path)
 
Returns a child NavigationMenu item that contains the given path. If no child is found
then undef is returned.
 
=cut
 
sub get_child_with_path {
        my ($self, $path) = @_;
 
        return $self->find_item(sub {$_->contains_path($path)});
}

lib/CatalystX/NavigationMenu.pm  view on Meta::CPAN

149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
        my $parent_path = shift(@path_parts);
        # See if we can find the parent for the first part of the path.
        $p_item = $self->get_child_with_path($parent_path);
        if ($p_item) {
                # We have a parent.
                $item->_set_parent(join('', @path_parts));
        }
        else {
                if ($parent_path =~ /^#/) {
                        # The parent path is just a label. so create a dummy item.
                        $p_item = CatalystX::NavigationMenuItem->new(
                                label => $', #The label is everything after the # in the path.
                                parent => '', # No parent item.
                                path => $parent_path,
                        );
                }
                else {
                        # We need to create a new container item
                        my $label = $path_parts[0];
                        $label =~ s/^#//;
                        $p_item = CatalystX::NavigationMenuItem->new(
                                label => $label,
                                parent => $parent_path,
                                path => $label,
                        );
                }
                $item->_set_parent(join('', @path_parts));
                $self->add_item($p_item);
        }
        $p_item->add_item($item);
}

lib/CatalystX/NavigationMenu.pm  view on Meta::CPAN

193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
                }
                else {
                        $self->insert_item($child);
                }
        }
}
 
=head2 get_navigation($c, $attrs)
 
Returns an array reference to a menu entry. This will only show one level of a
menu. The values of the array are the values returned by the L(NavigationMenuItem)
nav_entry() method.
 
=cut
 
sub get_navigation {
        my ($self, $c, $attrs) = @_;
 
        my $nav = [];
 
        # see if we need to get a particular level of menu or not.

lib/CatalystX/NavigationMenu.pm  view on Meta::CPAN

286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
1;
 
__END__
 
=head1 DEPENDENCIES
 
L<Catalyst>
 
=head1 SEE ALSO
 
L<CatalystX::NavigationMenuItem>
 
=head1 AUTHORS
 
Derek Wueppelmann <derek@roaringpenguin.com>
 
=head1 LICENSE AND COPYRIGHT
 
Copyright (c) 2011 Roaring Penguin Software, Inc.
 
This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

lib/CatalystX/NavigationMenuItem.pm  view on Meta::CPAN

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
 
use strict;
 
use Moose;
 
=head1 NAME
 
CatalystX::NavigationMenuItem
 
=head1 SYNOPSIS
 
  my $mi = CatalystX::NavigationMenuItem->new(
        ...
  );
 
  my $entry = $mi->nav_entry($c);
  my $link = $mi->get_link($c);
 
=head1 DESCRIPTION
 
CatalystX::NavigationMenuItem represents a menu item in a L(CatalystX::NavigationMenu).
This object does all the work of determining if the menu item can be displayed, what
link to use and if there are sub menus.
 
=cut
 
has label => (
        is => 'rw',
        isa => 'Str',
);

lib/CatalystX/NavigationMenuItem.pm  view on Meta::CPAN

88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
        isa => 'ArrayRef[Str]',
        default => sub{ [] },
        handles => {
                count_roles => 'count',
                all_roles => 'elements',
        },
);
 
has children => (
        is => 'rw',
        isa => 'CatalystX::NavigationMenu',
        predicate => 'has_children'
);
 
=head1 METHODS
 
=head2 contains_path($path)
 
Returns true if this menu item or any of its children contain the given
path.

lib/CatalystX/NavigationMenuItem.pm  view on Meta::CPAN

198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
=head2 add_item($item)
 
Add the given item to the sub tree for this item. If no subtree exists create one.
 
=cut
 
sub add_item {
        my ($self, $item) = @_;
 
        if (!$self->has_children) {
                $self->children(CatalystX::NavigationMenu->new());
        }
        if ($item->parent eq $self->path) {
                $self->children->insert_item($item);
        }
        else {
                $self->children->add_item($item);
        }
}
 
=head2 get_link($c)

lib/CatalystX/NavigationMenuItem.pm  view on Meta::CPAN

284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
1;
 
__END__
 
=head1 DEPENDENCIES
 
L<Catalyst>
 
=head1 SEE ALSO
 
L<CatalystX::NavigationMenu>
 
=head1 AUTHORS
 
Derek Wueppelmann <derek@roaringpenguin.com>
 
=head1 LICENSE AND COPYRIGHT
 
Copyright (c) 2011 Roaring Penguin Software, Inc.
 
This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.



( run in 0.363 second using v1.01-cache-2.11-cpan-26ccb49234f )