File Coverage

blib/lib/Statocles/Page/Document.pm
Criterion Covered Total %
statement 37 37 100.0
branch 8 8 100.0
condition n/a
subroutine 7 7 100.0
pod 3 3 100.0
total 55 55 100.0


line stmt bran cond sub pod time code
1             package Statocles::Page::Document;
2             our $VERSION = '0.084';
3             # ABSTRACT: Render document objects into HTML
4              
5 59     59   3991 use Statocles::Base 'Class';
  59         128  
  59         462  
6             with 'Statocles::Page';
7 59     59   421327 use Statocles::Template;
  59         179  
  59         1508  
8 59     59   352 use Statocles::Store;
  59         195  
  59         56922  
9              
10             #pod =attr document
11             #pod
12             #pod The L<document|Statocles::Document> this page will render.
13             #pod
14             #pod =cut
15              
16             has document => (
17             is => 'ro',
18             isa => InstanceOf['Statocles::Document'],
19             required => 1,
20             );
21              
22             #pod =attr title
23             #pod
24             #pod The title of the page.
25             #pod
26             #pod =cut
27              
28             has '+title' => (
29             lazy => 1,
30             default => sub { $_[0]->document->title || '' },
31             );
32              
33             #pod =attr author
34             #pod
35             #pod The author of the page.
36             #pod
37             #pod =cut
38              
39             around _build_author => sub {
40             my ( $orig, $self ) = @_;
41             return $self->document->author || $self->$orig;
42             };
43              
44             #pod =attr date
45             #pod
46             #pod Get the date of this page by checking the document.
47             #pod
48             #pod =cut
49              
50             has '+date' => (
51             lazy => 1,
52             default => sub {
53             my ( $self ) = @_;
54             $self->document->date || DateTime::Moonpig->now( time_zone => 'local' );
55             },
56             );
57              
58             #pod =attr tags
59             #pod
60             #pod The tag links for this document. An array of L<link objects|Statocles::Link>. The
61             #pod most important attributes are:
62             #pod
63             #pod text - The text of the link
64             #pod href - The page of the link
65             #pod
66             #pod =cut
67              
68             has _tags => (
69             is => 'rw',
70             isa => LinkArray,
71             default => sub { [] },
72             coerce => LinkArray->coercion,
73             init_arg => 'tags',
74             );
75              
76             has '+_links' => (
77             default => sub { $_[0]->document->links },
78             );
79              
80             has '+_images' => (
81             default => sub { $_[0]->document->images },
82             );
83              
84             #pod =attr data
85             #pod
86             #pod The C<data> hash for this page. Defaults to the C<data> attribute from the Document.
87             #pod
88             #pod =cut
89              
90             has '+data' => (
91             lazy => 1,
92             default => sub {
93             my ( $self ) = @_;
94             # Only allow hashref data attributes to come through.
95             # Non-hashref data attributes are deprecated and will be removed
96             # in v2.0. When that happens, remove this check as well
97             my $data = $self->document->data;
98             if ( $data && ref $data eq 'HASH' ) {
99             return $data;
100             }
101             return {};
102             },
103             );
104              
105             sub _render_content_template {
106 505     505   1484 my ( $self, $content, $vars ) = @_;
107 505         7716 my $tmpl = $self->site->theme->build_template( $self->path, $content );
108 505         60442 my $doc = $self->document;
109 505 100       2576 if ( $doc->store ) {
110 475         8851 my $document_path = $doc->store->path->child( $doc->path )->parent;
111 475         49805 push @{ $tmpl->include_stores }, Statocles::Store->new( path => $document_path );
  475         11201  
112             }
113 505         111782 my $rendered = $tmpl->render( %$vars, $self->vars, self => $doc, page => $self );
114 505         15386 return $rendered;
115             }
116              
117             #pod =method content
118             #pod
119             #pod my $html = $page->content( %vars );
120             #pod
121             #pod Generate the document HTML by processing template directives and converting
122             #pod Markdown. C<vars> is a set of name-value pairs to give to the template.
123             #pod
124             #pod =cut
125              
126             sub content {
127 346     346 1 1806 my ( $self, %vars ) = @_;
128 346         6388 my $content = $self->document->content;
129 346         3462 my $rendered = $self->_render_content_template( $content, \%vars );
130 346         20478 return $self->markdown->markdown( $rendered );
131             }
132              
133             #pod =method vars
134             #pod
135             #pod my %vars = $page->vars;
136             #pod
137             #pod Get the template variables for this page.
138             #pod
139             #pod =cut
140              
141             around vars => sub {
142             my ( $orig, $self ) = @_;
143             return (
144             $self->$orig,
145             doc => $self->document,
146             );
147             };
148              
149             #pod =method sections
150             #pod
151             #pod my @sections = $page->sections;
152             #pod my $number_of_sections = $page->sections;
153             #pod my @first_sections = $page->sections( 0, 1 );
154             #pod
155             #pod Get a list of rendered HTML content divided into sections. The Markdown "---"
156             #pod marker divides sections. In scalar context, returns the number of sections.
157             #pod You can also pass the indexes of the sections you want as arguments.
158             #pod
159             #pod For example, to loop over sections in the template:
160             #pod
161             #pod % for my $i ( 0..$page->sections ) {
162             #pod <%= $page->sections( $i ) %>
163             #pod % }
164             #pod
165             #pod =cut
166              
167             has _rendered_sections => (
168             is => 'rw',
169             isa => ArrayRef,
170             predicate => '_has_rendered_sections',
171             );
172              
173             sub sections {
174 1163     1163 1 17131 my ( $self, @indexes ) = @_;
175              
176 1163         1847 my @sections;
177 1163 100       4327 if ( $self->_has_rendered_sections ) {
178 1010         1937 @sections = @{ $self->_rendered_sections };
  1010         17122  
179             }
180             else {
181             @sections =
182 159         18861 map { $self->markdown->markdown( $_ ) }
183 153         2968 map { $self->_render_content_template( $_, {} ) }
  159         2245  
184             split /\n---\n/,
185             $self->document->content;
186              
187 153         333564 $self->_rendered_sections( \@sections );
188             }
189              
190 1163 100       15187 return @indexes ? @sections[ @indexes ] : @sections;
191             }
192              
193             #pod =method tags
194             #pod
195             #pod my @tags = $page->tags;
196             #pod
197             #pod Get the list of tags for this page.
198             #pod
199             #pod =cut
200              
201             sub tags {
202 1295     1295 1 58718 my ( $self, $new_tags ) = @_;
203 1295 100       2911 if ( $new_tags ) {
204 194         3024 return $self->_tags( $new_tags );
205             }
206 1101         1788 return @{ $self->_tags };
  1101         18897  
207             }
208              
209             #pod =method template
210             #pod
211             #pod my $tmpl = $page->template;
212             #pod
213             #pod The L<template object|Statocles::Template> for this page. If the document has a template,
214             #pod it will be used. Otherwise, the L<template attribute|Statocles::Page/template> will
215             #pod be used.
216             #pod
217             #pod =cut
218              
219             around template => sub {
220             my ( $orig, $self, @args ) = @_;
221             if ( $self->document->has_template ) {
222             return $self->site->theme->template( @{ $self->document->template } );
223             }
224             return $self->$orig( @args );
225             };
226              
227             #pod =method layout
228             #pod
229             #pod my $tmpl = $page->layout;
230             #pod
231             #pod The L<layout template object|Statocles::Template> for this page. If the document has a layout,
232             #pod it will be used. Otherwise, the L<layout attribute|Statocles::Page/layout> will
233             #pod be used.
234             #pod
235             #pod =cut
236              
237             around layout => sub {
238             my ( $orig, $self, @args ) = @_;
239             if ( $self->document->has_layout ) {
240             return $self->site->theme->template( @{ $self->document->layout } );
241             }
242             return $self->$orig( @args );
243             };
244              
245             #pod =attr next
246             #pod
247             #pod The path to the next document if it is part of a list.
248             #pod
249             #pod =attr prev
250             #pod
251             #pod The path to the previous document if it is part of a list.
252             #pod
253             #pod =cut
254              
255             has [qw( next prev )] => (
256             is => 'rw',
257             isa => Path,
258             coerce => Path->coercion,
259             );
260              
261             1;
262              
263             __END__
264              
265             =pod
266              
267             =encoding UTF-8
268              
269             =head1 NAME
270              
271             Statocles::Page::Document - Render document objects into HTML
272              
273             =head1 VERSION
274              
275             version 0.084
276              
277             =head1 DESCRIPTION
278              
279             This page class takes a single L<document|Statocles::Document> and renders it as HTML.
280              
281             =head1 ATTRIBUTES
282              
283             =head2 document
284              
285             The L<document|Statocles::Document> this page will render.
286              
287             =head2 title
288              
289             The title of the page.
290              
291             =head2 author
292              
293             The author of the page.
294              
295             =head2 date
296              
297             Get the date of this page by checking the document.
298              
299             =head2 tags
300              
301             The tag links for this document. An array of L<link objects|Statocles::Link>. The
302             most important attributes are:
303              
304             text - The text of the link
305             href - The page of the link
306              
307             =head2 data
308              
309             The C<data> hash for this page. Defaults to the C<data> attribute from the Document.
310              
311             =head2 next
312              
313             The path to the next document if it is part of a list.
314              
315             =head2 prev
316              
317             The path to the previous document if it is part of a list.
318              
319             =head1 METHODS
320              
321             =head2 content
322              
323             my $html = $page->content( %vars );
324              
325             Generate the document HTML by processing template directives and converting
326             Markdown. C<vars> is a set of name-value pairs to give to the template.
327              
328             =head2 vars
329              
330             my %vars = $page->vars;
331              
332             Get the template variables for this page.
333              
334             =head2 sections
335              
336             my @sections = $page->sections;
337             my $number_of_sections = $page->sections;
338             my @first_sections = $page->sections( 0, 1 );
339              
340             Get a list of rendered HTML content divided into sections. The Markdown "---"
341             marker divides sections. In scalar context, returns the number of sections.
342             You can also pass the indexes of the sections you want as arguments.
343              
344             For example, to loop over sections in the template:
345              
346             % for my $i ( 0..$page->sections ) {
347             <%= $page->sections( $i ) %>
348             % }
349              
350             =head2 tags
351              
352             my @tags = $page->tags;
353              
354             Get the list of tags for this page.
355              
356             =head2 template
357              
358             my $tmpl = $page->template;
359              
360             The L<template object|Statocles::Template> for this page. If the document has a template,
361             it will be used. Otherwise, the L<template attribute|Statocles::Page/template> will
362             be used.
363              
364             =head2 layout
365              
366             my $tmpl = $page->layout;
367              
368             The L<layout template object|Statocles::Template> for this page. If the document has a layout,
369             it will be used. Otherwise, the L<layout attribute|Statocles::Page/layout> will
370             be used.
371              
372             =head1 AUTHOR
373              
374             Doug Bell <preaction@cpan.org>
375              
376             =head1 COPYRIGHT AND LICENSE
377              
378             This software is copyright (c) 2016 by Doug Bell.
379              
380             This is free software; you can redistribute it and/or modify it under
381             the same terms as the Perl 5 programming language system itself.
382              
383             =cut