File Coverage

blib/lib/Statocles/App.pm
Criterion Covered Total %
statement 22 22 100.0
branch 6 6 100.0
condition 3 3 100.0
subroutine 5 5 100.0
pod 3 3 100.0
total 39 39 100.0


line stmt bran cond sub pod time code
1             package Statocles::App;
2             our $VERSION = '0.085';
3             # ABSTRACT: Base role for Statocles applications
4              
5 59     59   30393 use Statocles::Base 'Role', 'Emitter';
  59         140  
  59         506  
6 59     59   3368 use Statocles::Link;
  59         222  
  59         36954  
7             requires 'pages';
8              
9             #pod =attr site
10             #pod
11             #pod The site this app is part of.
12             #pod
13             #pod =cut
14              
15             has site => (
16             is => 'rw',
17             isa => InstanceOf['Statocles::Site'],
18             );
19              
20             #pod =attr data
21             #pod
22             #pod A hash of arbitrary data available to theme templates. This is a good place to
23             #pod put extra structured data like social network links or make easy customizations
24             #pod to themes like header image URLs.
25             #pod
26             #pod =cut
27              
28             has data => (
29             is => 'ro',
30             isa => HashRef,
31             default => sub { {} },
32             );
33              
34             #pod =attr url_root
35             #pod
36             #pod The URL root of this application. All pages from this app will be under this
37             #pod root. Use this to ensure two apps do not try to write the same path.
38             #pod
39             #pod =cut
40              
41             has url_root => (
42             is => 'ro',
43             isa => Str,
44             required => 1,
45             );
46              
47             #pod =attr templates
48             #pod
49             #pod The templates to use for this application. A mapping of template names to
50             #pod template paths (relative to the theme root directory).
51             #pod
52             #pod Developers should get application templates using L<the C<template>
53             #pod method|/template>.
54             #pod
55             #pod =cut
56              
57             has _templates => (
58             is => 'ro',
59             isa => HashRef,
60             default => sub { {} },
61             init_arg => 'templates',
62             );
63              
64             #pod =attr template_dir
65             #pod
66             #pod The directory (inside the theme directory) to use for this app's templates.
67             #pod
68             #pod =cut
69              
70             has template_dir => (
71             is => 'ro',
72             isa => Str,
73             );
74              
75             #pod =method pages
76             #pod
77             #pod my @pages = $app->pages;
78             #pod
79             #pod Get the pages for this app. Must return a list of L<Statocles::Page> objects.
80             #pod
81             #pod =cut
82              
83             around pages => sub {
84             my ( $orig, $self, @args ) = @_;
85             my @pages = $self->$orig( @args );
86              
87             # Add the url_root
88             my $url_root = $self->url_root;
89             for my $page ( @pages ) {
90             my @url_attrs = qw( path );
91              
92             if ( $page->isa( 'Statocles::Page::List' ) ) {
93             push @url_attrs, qw( next prev );
94             }
95              
96             for my $attr ( @url_attrs ) {
97             if ( $page->$attr && $page->$attr !~ /^$url_root/ ) {
98             $page->$attr( join "/", $url_root, $page->$attr );
99             }
100             }
101             }
102              
103             $self->emit( 'build' => class => 'Statocles::Event::Pages', pages => \@pages );
104              
105             return @pages;
106             };
107              
108             #pod =method url
109             #pod
110             #pod my $app_url = $app->url( $path );
111             #pod
112             #pod Get a URL to a page in this application. Prepends the app's L<url_root
113             #pod attribute|/url_root> if necessary. Strips "index.html" if possible.
114             #pod
115             #pod =cut
116              
117             sub url {
118 1814     1814 1 17098 my ( $self, $url ) = @_;
119 1814         3322 my $base = $self->url_root;
120 1814         3692 $url =~ s{/index[.]html$}{/};
121              
122             # Remove the / from both sides of the join so we don't double up
123 1814         3219 $base =~ s{/$}{};
124 1814         2784 $url =~ s{^/}{};
125              
126 1814         6068 return join "/", $base, $url;
127             }
128              
129             #pod =method link
130             #pod
131             #pod my $link = $app->link( %args )
132             #pod
133             #pod Create a link to a page in this application. C<%args> are attributes to be
134             #pod given to L<Statocles::Link> constructor. The app's L<url_root
135             #pod attribute|/url_root> is prepended, if necessary.
136             #pod
137             #pod =cut
138              
139             sub link {
140 2713     2713 1 47154 my ( $self, %args ) = @_;
141 2713         7186 my $url_root = $self->url_root;
142 2713 100       12137 if ( $args{href} !~ /^$url_root/ ) {
143 1757         4945 $args{href} = $self->url( $args{href} );
144             }
145 2713         52999 return Statocles::Link->new( %args );
146             }
147              
148             #pod =method template
149             #pod
150             #pod my $template = $app->template( $tmpl_name );
151             #pod
152             #pod Get a L<template object|Statocles::Template> for the given template
153             #pod name. The default template is determined by the app's class name and the
154             #pod template name passed in.
155             #pod
156             #pod Applications should list the templates they have and describe what L<page
157             #pod class|Statocles::Page> they use.
158             #pod
159             #pod =cut
160              
161             sub template {
162 1686     1686 1 17597 my ( $self, $name ) = @_;
163              
164             # Allow the site object to set the default layout
165 1686 100 100     7085 if ( $name eq 'layout.html' && !$self->_templates->{ $name } ) {
166 755         13809 return $self->site->template( $name );
167             }
168              
169             my $path = $self->_templates->{ $name }
170 931 100       4080 ? $self->_templates->{ $name }
171             : join "/", $self->template_dir, $name;
172              
173 931         15422 return $self->site->theme->template( $path );
174             }
175              
176             1;
177              
178             __END__
179              
180             =pod
181              
182             =encoding UTF-8
183              
184             =head1 NAME
185              
186             Statocles::App - Base role for Statocles applications
187              
188             =head1 VERSION
189              
190             version 0.085
191              
192             =head1 SYNOPSIS
193              
194             package MyApp;
195             use Statocles::Base 'Class';
196             with 'Statocles::App';
197              
198             sub pages {
199             return Statocles::Page::Content->new(
200             path => '/index.html',
201             content => 'Hello, World',
202             );
203             }
204              
205             =head1 DESCRIPTION
206              
207             A Statocles App creates a set of L<pages|Statocles::Pages> that can then be
208             written to the filesystem (or served directly, if desired).
209              
210             Pages can be created from L<documents|Statocles::Documents> stored in a
211             L<store|Statocles::Store> (see L<Statocles::Page::Document>), files stored in a
212             store (see L<Statocles::Page::File>), lists of content (see
213             L<Statocles::Page::List>), or anything at all (see
214             L<Statocles::Page::Content>).
215              
216             =head1 ATTRIBUTES
217              
218             =head2 site
219              
220             The site this app is part of.
221              
222             =head2 data
223              
224             A hash of arbitrary data available to theme templates. This is a good place to
225             put extra structured data like social network links or make easy customizations
226             to themes like header image URLs.
227              
228             =head2 url_root
229              
230             The URL root of this application. All pages from this app will be under this
231             root. Use this to ensure two apps do not try to write the same path.
232              
233             =head2 templates
234              
235             The templates to use for this application. A mapping of template names to
236             template paths (relative to the theme root directory).
237              
238             Developers should get application templates using L<the C<template>
239             method|/template>.
240              
241             =head2 template_dir
242              
243             The directory (inside the theme directory) to use for this app's templates.
244              
245             =head1 METHODS
246              
247             =head2 pages
248              
249             my @pages = $app->pages;
250              
251             Get the pages for this app. Must return a list of L<Statocles::Page> objects.
252              
253             =head2 url
254              
255             my $app_url = $app->url( $path );
256              
257             Get a URL to a page in this application. Prepends the app's L<url_root
258             attribute|/url_root> if necessary. Strips "index.html" if possible.
259              
260             =head2 link
261              
262             my $link = $app->link( %args )
263              
264             Create a link to a page in this application. C<%args> are attributes to be
265             given to L<Statocles::Link> constructor. The app's L<url_root
266             attribute|/url_root> is prepended, if necessary.
267              
268             =head2 template
269              
270             my $template = $app->template( $tmpl_name );
271              
272             Get a L<template object|Statocles::Template> for the given template
273             name. The default template is determined by the app's class name and the
274             template name passed in.
275              
276             Applications should list the templates they have and describe what L<page
277             class|Statocles::Page> they use.
278              
279             =head1 EVENTS
280              
281             All apps by default expose the following events:
282              
283             =head2 build
284              
285             This event is fired after the app pages have been prepares and are ready to
286             be rendered. This event allows for modifying the pages before they are rendered.
287              
288             The event will be a
289             L<Statocles::Event::Pages|Statocles::Event/Statocles::Event::Pages> object
290             containing all the pages prepared by the app.
291              
292             =head1 INCLUDED APPS
293              
294             These applications are included with the core Statocles distribution.
295              
296             =over 4
297              
298             =item L<Statocles::App::Blog>
299              
300             =item L<Statocles::App::Basic>
301              
302             =item L<Statocles::App::Static>
303              
304             =item L<Statocles::App::Perldoc>
305              
306             =back
307              
308             =head1 SEE ALSO
309              
310             =over 4
311              
312             =item L<Statocles::Store>
313              
314             =item L<Statocles::Page>
315              
316             =back
317              
318             =head1 AUTHOR
319              
320             Doug Bell <preaction@cpan.org>
321              
322             =head1 COPYRIGHT AND LICENSE
323              
324             This software is copyright (c) 2016 by Doug Bell.
325              
326             This is free software; you can redistribute it and/or modify it under
327             the same terms as the Perl 5 programming language system itself.
328              
329             =cut