]> Dogcows Code - chaz/p5-Catalyst-Plugin-Sitemap/blob - lib/Catalyst/Plugin/Sitemap.pm
v1.0.0
[chaz/p5-Catalyst-Plugin-Sitemap] / lib / Catalyst / Plugin / Sitemap.pm
1 package Catalyst::Plugin::Sitemap;
2
3 # ABSTRACT: Sitemap support for Catalyst.
4
5 =head1 SYNOPSIS
6
7 # in MyApp.pm
8
9 use Catalyst qw/ Sitemap /;
10
11 # in the controller
12
13 sub alone :Local :Sitemap {
14 ...
15 }
16
17 sub with_priority :Local :Sitemap(0.75) {
18 ...
19 }
20
21 sub with_args :Local
22 :Sitemap( lastmod => 2010-09-27, changefreq => daily ) {
23 ...
24 }
25
26 sub with_function :Local :Sitemap(*) {
27 ...
28 }
29
30 sub with_function_sitemap {
31 $_[2]->add( 'http://localhost/with_function' );
32 }
33
34 # and then...
35
36 sub sitemap : Path('/sitemap') {
37 my ( $self, $c ) = @_;
38
39 $c->res->body( $c->sitemap_as_xml );
40 }
41
42 =head1 DESCRIPTION
43
44 L<Catalyst::Plugin::Sitemap> provides a way to semi-automate the creation
45 of the sitemap of a Catalyst application.
46
47 =head1 CONTEXT METHOD
48
49 =head2 sitemap()
50
51 Returns a L<WWW::Sitemap::XML> object. The sitemap object is populated by
52 inspecting the controllers of the application for actions with the
53 sub attribute C<:Sitemap>.
54
55 =head2 sitemap_as_xml()
56
57 Returns the sitemap as a string containing its XML representation.
58
59 =head1 C<:Sitemap> Subroutine Attribute
60
61 The sitemap is populated by actions ear-marked with the <:Sitemap> sub
62 attribute. It can be invoked in different ways:
63
64 =over
65
66 =item C<:Sitemap>
67
68 sub alone :Local :Sitemap {
69 ...
70 }
71
72 Adds the url of the action to the sitemap.
73
74 If the action does not
75 resolves in a single url, this will results in an error.
76
77 =item C<:Sitemap($priority)>
78
79
80 sub with_priority :Local :Sitemap(0.9) {
81 ...
82 }
83
84 Adds the url, with the given number, which has to be between 1 (inclusive)
85 and 0 (exclusive), as its priority.
86
87 If the action does not
88 resolves in a single url, this will results in an error.
89
90 =item C<:Sitemap( %attributes )>
91
92 sub with_args :Local
93 :Sitemap( lastmod => 2010-09-27, changefreq => daily ) {
94 ...
95 }
96
97 Adds the url with the given entry attributes (as defined by
98 L<WWW::Sitemap::XML::URL>).
99
100 If the action does not
101 resolves in a single url, this will results in an error.
102
103 =item C<:Sitemap(*)>
104
105 sub with_function :Local :Sitemap(*) { }
106
107 sub with_function_sitemap {
108 my ( $self, $c, $sitemap ) = @_;
109
110 $sitemap->add( 'http://localhost/with_function' );
111 }
112
113 Calls the function 'I<action>_sitemap', if it exists, and passes it the
114 controller, context and sitemap objects.
115
116 This is currently the only way to invoke C<:Sitemap> on an action
117 resolving to many urls.
118
119 =back
120
121
122 =head1 SEE ALSO
123
124 =over
125
126 =item L<WWW::Sitemap::XML>
127
128 Module that C<Catalyst::Plugin::Sitemap> currently uses under the hood.
129
130 =item L<Search::Sitemap>
131
132 Original module that this plugin was using under the hood.
133
134
135 =item L<Dancer::Plugin::SiteMap>
136
137 Similar plugin for the L<Dancer> framework, which inspired
138 C<Catalyst::Plugin::Sitemap>.
139
140 =item http://babyl.dyndns.org/techblog/entry/catalyst-plugin-sitemap
141
142 Blog article introducing C<Catalyst::Plugin::Sitemap>.
143
144 =back
145
146 =cut
147
148 use strict;
149 use warnings;
150
151 use Moose::Role;
152
153 no warnings qw/uninitialized/;
154
155 use WWW::Sitemap::XML;
156 use List::Util qw/ first /;
157
158 has sitemap => (
159 is => 'ro',
160 builder => '_build_sitemap',
161 lazy => 1,
162 );
163
164 sub sitemap_as_xml {
165 my $self = shift;
166 return $self->sitemap->as_xml->toString;
167 }
168
169 sub _build_sitemap {
170 my $self = shift;
171
172 my $sitemap = WWW::Sitemap::XML->new;
173
174 for my $controller ( map { $self->controller($_) } $self->controllers ) {
175 ACTION:
176 for my $a ( $controller->get_action_methods ) {
177
178 my $action = $controller->action_for( $a->name );
179
180 my $attr = $action->attributes->{Sitemap} or next ACTION;
181
182 die "more than one attribute 'Sitemap' for sub ",
183 $a->fully_qualified_name
184 if @$attr > 1;
185
186 my @attr = split /\s*(?:,|=>)\s*/, $attr->[0];
187
188 my %uri_params;
189
190 if ( @attr == 1 ) {
191 if ( $attr[0] eq '*' ) {
192 my $sitemap_method = $action->name . "_sitemap";
193
194 if ( $controller->can($sitemap_method) ) {
195 $controller->$sitemap_method( $self, $sitemap );
196 next ACTION;
197 }
198 }
199
200 if ( $attr[0] + 0 > 0 ) {
201
202 # it's a number
203 $uri_params{priority} = $attr[0];
204 }
205
206 }
207 elsif ( @attr > 0 ) {
208 %uri_params = @attr;
209 }
210
211 $uri_params{loc} = $self->uri_for_action( $action->private_path );
212
213 $sitemap->add(%uri_params);
214 }
215
216 }
217
218 return $sitemap;
219 }
220
221 1;
222
223 __END__
This page took 0.042906 seconds and 4 git commands to generate.