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.086';
3             # ABSTRACT: Base role for Statocles applications
4              
5 59     59   31253 use Statocles::Base 'Role', 'Emitter';
  59         155  
  59         671  
6 59     59   3858 use Statocles::Link;
  59         529  
  59         39802  
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 =attr disable_content_template
76             #pod
77             #pod This disables processing the content in this application as a template.
78             #pod This can speed up processing when the content is not using template
79             #pod directives.
80             #pod
81             #pod This can be also set in the document
82             #pod (L<Statocles::Document/disable_content_template>), or for the entire site
83             #pod (L<Statocles::Site/disable_content_template>).
84             #pod
85             #pod =cut
86              
87             has disable_content_template => (
88             is => 'ro',
89             isa => Bool,
90             lazy => 1,
91             default => 0,
92             predicate => 'has_disable_content_template',
93             );
94              
95             #pod =method pages
96             #pod
97             #pod my @pages = $app->pages;
98             #pod
99             #pod Get the pages for this app. Must return a list of L<Statocles::Page> objects.
100             #pod
101             #pod =cut
102              
103             around pages => sub {
104             my ( $orig, $self, @args ) = @_;
105             my @pages = $self->$orig( @args );
106              
107             # Add the url_root
108             my $url_root = $self->url_root;
109             for my $page ( @pages ) {
110             my @url_attrs = qw( path );
111              
112             if ( $page->isa( 'Statocles::Page::List' ) ) {
113             push @url_attrs, qw( next prev );
114             }
115              
116             for my $attr ( @url_attrs ) {
117             if ( $page->$attr && $page->$attr !~ /^$url_root/ ) {
118             $page->$attr( join "/", $url_root, $page->$attr );
119             }
120             }
121             }
122              
123             $self->emit( 'build' => class => 'Statocles::Event::Pages', pages => \@pages );
124              
125             return @pages;
126             };
127              
128             #pod =method url
129             #pod
130             #pod my $app_url = $app->url( $path );
131             #pod
132             #pod Get a URL to a page in this application. Prepends the app's L<url_root
133             #pod attribute|/url_root> if necessary. Strips "index.html" if possible.
134             #pod
135             #pod =cut
136              
137             sub url {
138 1810     1810 1 15284 my ( $self, $url ) = @_;
139 1810         3015 my $base = $self->url_root;
140 1810         3645 $url =~ s{/index[.]html$}{/};
141              
142             # Remove the / from both sides of the join so we don't double up
143 1810         3180 $base =~ s{/$}{};
144 1810         2563 $url =~ s{^/}{};
145              
146 1810         5674 return join "/", $base, $url;
147             }
148              
149             #pod =method link
150             #pod
151             #pod my $link = $app->link( %args )
152             #pod
153             #pod Create a link to a page in this application. C<%args> are attributes to be
154             #pod given to L<Statocles::Link> constructor. The app's L<url_root
155             #pod attribute|/url_root> is prepended, if necessary.
156             #pod
157             #pod =cut
158              
159             sub link {
160 2709     2709 1 45013 my ( $self, %args ) = @_;
161 2709         6703 my $url_root = $self->url_root;
162 2709 100       11728 if ( $args{href} !~ /^$url_root/ ) {
163 1753         4479 $args{href} = $self->url( $args{href} );
164             }
165 2709         51103 return Statocles::Link->new( %args );
166             }
167              
168             #pod =method template
169             #pod
170             #pod my $template = $app->template( $tmpl_name );
171             #pod
172             #pod Get a L<template object|Statocles::Template> for the given template
173             #pod name. The default template is determined by the app's class name and the
174             #pod template name passed in.
175             #pod
176             #pod Applications should list the templates they have and describe what L<page
177             #pod class|Statocles::Page> they use.
178             #pod
179             #pod =cut
180              
181             sub template {
182 1686     1686 1 19141 my ( $self, $name ) = @_;
183              
184             # Allow the site object to set the default layout
185 1686 100 100     6551 if ( $name eq 'layout.html' && !$self->_templates->{ $name } ) {
186 755         13355 return $self->site->template( $name );
187             }
188              
189             my $path = $self->_templates->{ $name }
190 931 100       3798 ? $self->_templates->{ $name }
191             : join "/", $self->template_dir, $name;
192              
193 931         14655 return $self->site->theme->template( $path );
194             }
195              
196             1;
197              
198             __END__
199              
200             =pod
201              
202             =encoding UTF-8
203              
204             =head1 NAME
205              
206             Statocles::App - Base role for Statocles applications
207              
208             =head1 VERSION
209              
210             version 0.086
211              
212             =head1 SYNOPSIS
213              
214             package MyApp;
215             use Statocles::Base 'Class';
216             with 'Statocles::App';
217              
218             sub pages {
219             return Statocles::Page::Content->new(
220             path => '/index.html',
221             content => 'Hello, World',
222             );
223             }
224              
225             =head1 DESCRIPTION
226              
227             A Statocles App creates a set of L<pages|Statocles::Pages> that can then be
228             written to the filesystem (or served directly, if desired).
229              
230             Pages can be created from L<documents|Statocles::Documents> stored in a
231             L<store|Statocles::Store> (see L<Statocles::Page::Document>), files stored in a
232             store (see L<Statocles::Page::File>), lists of content (see
233             L<Statocles::Page::List>), or anything at all (see
234             L<Statocles::Page::Content>).
235              
236             =head1 ATTRIBUTES
237              
238             =head2 site
239              
240             The site this app is part of.
241              
242             =head2 data
243              
244             A hash of arbitrary data available to theme templates. This is a good place to
245             put extra structured data like social network links or make easy customizations
246             to themes like header image URLs.
247              
248             =head2 url_root
249              
250             The URL root of this application. All pages from this app will be under this
251             root. Use this to ensure two apps do not try to write the same path.
252              
253             =head2 templates
254              
255             The templates to use for this application. A mapping of template names to
256             template paths (relative to the theme root directory).
257              
258             Developers should get application templates using L<the C<template>
259             method|/template>.
260              
261             =head2 template_dir
262              
263             The directory (inside the theme directory) to use for this app's templates.
264              
265             =head2 disable_content_template
266              
267             This disables processing the content in this application as a template.
268             This can speed up processing when the content is not using template
269             directives.
270              
271             This can be also set in the document
272             (L<Statocles::Document/disable_content_template>), or for the entire site
273             (L<Statocles::Site/disable_content_template>).
274              
275             =head1 METHODS
276              
277             =head2 pages
278              
279             my @pages = $app->pages;
280              
281             Get the pages for this app. Must return a list of L<Statocles::Page> objects.
282              
283             =head2 url
284              
285             my $app_url = $app->url( $path );
286              
287             Get a URL to a page in this application. Prepends the app's L<url_root
288             attribute|/url_root> if necessary. Strips "index.html" if possible.
289              
290             =head2 link
291              
292             my $link = $app->link( %args )
293              
294             Create a link to a page in this application. C<%args> are attributes to be
295             given to L<Statocles::Link> constructor. The app's L<url_root
296             attribute|/url_root> is prepended, if necessary.
297              
298             =head2 template
299              
300             my $template = $app->template( $tmpl_name );
301              
302             Get a L<template object|Statocles::Template> for the given template
303             name. The default template is determined by the app's class name and the
304             template name passed in.
305              
306             Applications should list the templates they have and describe what L<page
307             class|Statocles::Page> they use.
308              
309             =head1 EVENTS
310              
311             All apps by default expose the following events:
312              
313             =head2 build
314              
315             This event is fired after the app pages have been prepares and are ready to
316             be rendered. This event allows for modifying the pages before they are rendered.
317              
318             The event will be a
319             L<Statocles::Event::Pages|Statocles::Event/Statocles::Event::Pages> object
320             containing all the pages prepared by the app.
321              
322             =head1 INCLUDED APPS
323              
324             These applications are included with the core Statocles distribution.
325              
326             =over 4
327              
328             =item L<Statocles::App::Blog>
329              
330             =item L<Statocles::App::Basic>
331              
332             =item L<Statocles::App::Static>
333              
334             =item L<Statocles::App::Perldoc>
335              
336             =back
337              
338             =head1 SEE ALSO
339              
340             =over 4
341              
342             =item L<Statocles::Store>
343              
344             =item L<Statocles::Page>
345              
346             =back
347              
348             =head1 AUTHOR
349              
350             Doug Bell <preaction@cpan.org>
351              
352             =head1 COPYRIGHT AND LICENSE
353              
354             This software is copyright (c) 2016 by Doug Bell.
355              
356             This is free software; you can redistribute it and/or modify it under
357             the same terms as the Perl 5 programming language system itself.
358              
359             =cut