File Coverage

blib/lib/Fir.pm
Criterion Covered Total %
statement 1 3 33.3
branch n/a
condition n/a
subroutine 1 1 100.0
pod n/a
total 2 4 50.0


line stmt bran cond sub pod time code
1             package Fir;
2 1     1   1114 use Moose;
  0            
  0            
3             use Fir::Major;
4             use Fir::Minor;
5             use Tree::DAG_Node;
6             our $VERSION = '0.33';
7              
8             has 'root' => (
9             is => 'ro',
10             isa => 'Tree::DAG_Node',
11             default => sub {
12             my $root = Tree::DAG_Node->new();
13             $root->name('root');
14             return $root;
15             }
16             );
17              
18             sub add_major {
19             my ( $self, $major, @minors ) = @_;
20             my $root = $self->root;
21             $root->add_daughter($major);
22             foreach my $minor (@minors) {
23             $major->add_daughter($minor);
24             }
25             }
26              
27             sub path {
28             my ( $self, $path ) = @_;
29             my $root = $self->root;
30             foreach my $node ( $root->descendants ) {
31             $node->is_selected(0);
32             }
33             foreach my $node ( $root->daughters ) {
34             $node->is_open(0);
35             }
36             foreach my $node ( sort { length( $b->path ) <=> length( $a->path ) }
37             $root->descendants )
38             {
39             my $node_path = $node->path;
40             next unless $path =~ /^$node_path/;
41             $node->is_selected(1);
42             $node->is_open(1) if $node->isa('Fir::Major');
43             $node->mother->is_open(1) unless $node->mother == $root;
44             last;
45             }
46             }
47              
48             sub as_string {
49             my $self = shift;
50             my $root = $self->root;
51             my $string = '';
52             foreach my $major ( $root->daughters ) {
53             if ( $major->is_selected ) {
54             $string .= '*' . $major->name . '* ' . $major->path . "\n";
55             } else {
56             $string .= $major->name . ' ' . $major->path . "\n";
57             }
58             if ( $major->is_open ) {
59             foreach my $minor ( $major->daughters ) {
60             if ( $minor->is_selected ) {
61             $string
62             .= ' *' . $minor->name . '* ' . $minor->path . "\n";
63             } else {
64             $string
65             .= ' ' . $minor->name . ' ' . $minor->path . "\n";
66             }
67             }
68             }
69             }
70             return $string;
71             }
72              
73             1;
74              
75             __END__
76              
77             =head1 NAME
78              
79             Fir - a Tree::DAG_Node subclass for menu nagivation
80              
81             =head1 SYNOPSIS
82              
83             # set up the following navigation structure:
84             # Home (/)
85             # \-- About (/about/)
86             # \-- Leon (/about/leon/)
87             # \-- Jake (/about/jake/)
88             my $fir = Fir->new;
89             my $home = Fir::Major->new();
90             $home->name('Home');
91             $home->path('/');
92             my $about = Fir::Major->new();
93             $about->name('About');
94             $about->path('/about/');
95             my $leon = Fir::Minor->new();
96             $leon->name('Leon');
97             $leon->path('/about/leon/');
98             my $jake = Fir::Minor->new();
99             $jake->name('Jake');
100             $jake->path('/about/jake/');
101             $fir->add_major($home);
102             $fir->add_major( $about, $leon, $jake );
103              
104             # and select a path
105             $fir->path('/about/');
106              
107             # now traverse the tree
108             my $root = $fir->root;
109             foreach my $major ( $root->daughters ) {
110             if ( $major->is_selected ) {
111             print '*' . $major->name . '* ' . $major->path . "\n";
112             } else {
113             print $major->name . ' ' . $major->path . "\n";
114             }
115             if ( $major->is_open ) {
116             foreach my $minor ( $major->daughters ) {
117             if ( $minor->is_selected ) {
118             print $minor->name . '* ' . $minor->path . "\n";
119             } else {
120             print $minor->name . ' ' . $minor->path . "\n";
121             }
122             }
123             }
124             }
125             # that prints:
126             # Home /
127             # *About* /about/
128             # Leon /about/leon/
129             # Jake /about/jake/
130            
131              
132             =head1 DESCRIPTION
133              
134             Fir is a Tree::DAG_Node subclass for menu nagivation. Menu navigation
135             on a web application is fiddly code and this module hides that away
136             from you. Note that this module only handles the logic, not the
137             display of the navigation.
138              
139             There are two kinds of nodes L<Fir::Major> nodes are allowed to have
140             subnodes, while L<Fir::Minor> nodes are not.
141              
142             =head1 METHODS
143              
144             =head2 new
145              
146             The constructor:
147              
148             my $fir = Fir->new;
149              
150             =head2 add_major
151              
152             Adds a major navigation node, and possibly some minor navigation
153             nodes below it:
154              
155             my $about = Fir::Major->new();
156             $about->name('About');
157             $about->path('/about/');
158             my $leon = Fir::Minor->new();
159             $leon->name('Leon');
160             $leon->path('/about/leon/');
161             my $jake = Fir::Minor->new();
162             $jake->name('Jake');
163             $jake->path('/about/jake/');
164             $fir->add_major($home);
165             $fir->add_major( $about, $leon, $jake );
166              
167             =head2 path
168              
169             Given a path, opens and selects nodes for the naviation::
170              
171             $fir->path('/about/');
172              
173             =head2 as_string
174              
175             A debugging method to help you visualise your tree:
176              
177             die $fir->as_string;
178              
179             =head1 SEE ALSO
180              
181             L<Fir::Major>, L<Fir::Minor>
182              
183             =head1 AUTHOR
184              
185             Leon Brocard E<lt>F<acme@astray.com>E<gt>
186              
187             =head1 COPYRIGHT
188              
189             =head1 LICENSE
190              
191             Copyright (C) 2008, Leon Brocard
192              
193             This module is free software; you can redistribute it or modify it
194             under the same terms as Perl itself.