File Coverage

blib/lib/Statocles/Page/Document.pm
Criterion Covered Total %
statement 41 41 100.0
branch 10 10 100.0
condition n/a
subroutine 7 7 100.0
pod 3 3 100.0
total 61 61 100.0


line stmt bran cond sub pod time code
1             package Statocles::Page::Document;
2             our $VERSION = '0.086';
3             # ABSTRACT: Render document objects into HTML
4              
5 59     59   4057 use Statocles::Base 'Class';
  59         134  
  59         474  
6             with 'Statocles::Page';
7 59     59   422446 use Statocles::Template;
  59         260  
  59         1503  
8 59     59   346 use Statocles::Store;
  59         136  
  59         64257  
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             #pod =attr disable_content_template
106             #pod
107             #pod If true, disables the processing of the content as a template. This will
108             #pod improve performance if you're not using any template directives in your content.
109             #pod
110             #pod This can be set in the document (L<Statocles::Document/disable_content_template>),
111             #pod the application (L<Statocles::App/disable_content_template>), or the site
112             #pod (L<Statocles::Site/disable_content_template>).
113             #pod
114             #pod =cut
115              
116             has disable_content_template => (
117             is => 'ro',
118             isa => Str,
119             lazy => 1,
120             default => sub {
121             my ( $self ) = @_;
122             return $self->document && $self->document->has_disable_content_template ? $self->document->disable_content_template && "document"
123             : $self->app && $self->app->has_disable_content_template ? $self->app->disable_content_template && "application"
124             : $self->site && $self->site->has_disable_content_template ? $self->site->disable_content_template && "site"
125             : "";
126             },
127             );
128              
129             sub _render_content_template {
130 504     504   1493 my ( $self, $content, $vars ) = @_;
131 504 100       8275 if ( my $by = $self->disable_content_template ) {
132 3         329 $self->site->log->debug( $self->path . ' content template processing disabled by ' . $by );
133 3         193 return $content;
134             }
135 501         31096 $self->site->log->debug( $self->path . ' processing content template ' );
136 501         43082 my $tmpl = $self->site->theme->build_template( $self->path, $content );
137 501         61204 my $doc = $self->document;
138 501 100       2510 if ( $doc->store ) {
139 478         9368 my $document_path = $doc->store->path->child( $doc->path )->parent;
140 478         50226 push @{ $tmpl->include_stores }, Statocles::Store->new( path => $document_path );
  478         11937  
141             }
142 501         111749 my $rendered = $tmpl->render( %$vars, $self->vars, self => $doc, page => $self );
143 501         15085 return $rendered;
144             }
145              
146             #pod =method content
147             #pod
148             #pod my $html = $page->content( %vars );
149             #pod
150             #pod Generate the document HTML by processing template directives and converting
151             #pod Markdown. C<vars> is a set of name-value pairs to give to the template.
152             #pod
153             #pod =cut
154              
155             sub content {
156 345     345 1 1435 my ( $self, %vars ) = @_;
157 345         6454 my $content = $self->document->content;
158 345         3521 my $rendered = $self->_render_content_template( $content, \%vars );
159 345         20277 return $self->markdown->markdown( $rendered );
160             }
161              
162             #pod =method vars
163             #pod
164             #pod my %vars = $page->vars;
165             #pod
166             #pod Get the template variables for this page.
167             #pod
168             #pod =cut
169              
170             around vars => sub {
171             my ( $orig, $self ) = @_;
172             return (
173             $self->$orig,
174             doc => $self->document,
175             );
176             };
177              
178             #pod =method sections
179             #pod
180             #pod my @sections = $page->sections;
181             #pod my $number_of_sections = $page->sections;
182             #pod my @first_sections = $page->sections( 0, 1 );
183             #pod
184             #pod Get a list of rendered HTML content divided into sections. The Markdown "---"
185             #pod marker divides sections. In scalar context, returns the number of sections.
186             #pod You can also pass the indexes of the sections you want as arguments.
187             #pod
188             #pod For example, to loop over sections in the template:
189             #pod
190             #pod % for my $i ( 0..$page->sections ) {
191             #pod <%= $page->sections( $i ) %>
192             #pod % }
193             #pod
194             #pod =cut
195              
196             has _rendered_sections => (
197             is => 'rw',
198             isa => ArrayRef,
199             predicate => '_has_rendered_sections',
200             );
201              
202             sub sections {
203 1163     1163 1 22276 my ( $self, @indexes ) = @_;
204              
205 1163         1953 my @sections;
206 1163 100       3990 if ( $self->_has_rendered_sections ) {
207 1010         1787 @sections = @{ $self->_rendered_sections };
  1010         16645  
208             }
209             else {
210             @sections =
211 159         18632 map { $self->markdown->markdown( $_ ) }
212 153         2989 map { $self->_render_content_template( $_, {} ) }
  159         2028  
213             split /\n---\n/,
214             $self->document->content;
215              
216 153         323811 $self->_rendered_sections( \@sections );
217             }
218              
219 1163 100       15087 return @indexes ? @sections[ @indexes ] : @sections;
220             }
221              
222             #pod =method tags
223             #pod
224             #pod my @tags = $page->tags;
225             #pod
226             #pod Get the list of tags for this page.
227             #pod
228             #pod =cut
229              
230             sub tags {
231 1295     1295 1 63178 my ( $self, $new_tags ) = @_;
232 1295 100       3163 if ( $new_tags ) {
233 194         3068 return $self->_tags( $new_tags );
234             }
235 1101         1777 return @{ $self->_tags };
  1101         17521  
236             }
237              
238             #pod =method template
239             #pod
240             #pod my $tmpl = $page->template;
241             #pod
242             #pod The L<template object|Statocles::Template> for this page. If the document has a template,
243             #pod it will be used. Otherwise, the L<template attribute|Statocles::Page/template> will
244             #pod be used.
245             #pod
246             #pod =cut
247              
248             around template => sub {
249             my ( $orig, $self, @args ) = @_;
250             if ( $self->document->has_template ) {
251             return $self->site->theme->template( @{ $self->document->template } );
252             }
253             return $self->$orig( @args );
254             };
255              
256             #pod =method layout
257             #pod
258             #pod my $tmpl = $page->layout;
259             #pod
260             #pod The L<layout template object|Statocles::Template> for this page. If the document has a layout,
261             #pod it will be used. Otherwise, the L<layout attribute|Statocles::Page/layout> will
262             #pod be used.
263             #pod
264             #pod =cut
265              
266             around layout => sub {
267             my ( $orig, $self, @args ) = @_;
268             if ( $self->document->has_layout ) {
269             return $self->site->theme->template( @{ $self->document->layout } );
270             }
271             return $self->$orig( @args );
272             };
273              
274             #pod =attr next
275             #pod
276             #pod The path to the next document if it is part of a list.
277             #pod
278             #pod =attr prev
279             #pod
280             #pod The path to the previous document if it is part of a list.
281             #pod
282             #pod =cut
283              
284             has [qw( next prev )] => (
285             is => 'rw',
286             isa => Path,
287             coerce => Path->coercion,
288             );
289              
290             1;
291              
292             __END__
293              
294             =pod
295              
296             =encoding UTF-8
297              
298             =head1 NAME
299              
300             Statocles::Page::Document - Render document objects into HTML
301              
302             =head1 VERSION
303              
304             version 0.086
305              
306             =head1 DESCRIPTION
307              
308             This page class takes a single L<document|Statocles::Document> and renders it as HTML.
309              
310             =head1 ATTRIBUTES
311              
312             =head2 document
313              
314             The L<document|Statocles::Document> this page will render.
315              
316             =head2 title
317              
318             The title of the page.
319              
320             =head2 author
321              
322             The author of the page.
323              
324             =head2 date
325              
326             Get the date of this page by checking the document.
327              
328             =head2 tags
329              
330             The tag links for this document. An array of L<link objects|Statocles::Link>. The
331             most important attributes are:
332              
333             text - The text of the link
334             href - The page of the link
335              
336             =head2 data
337              
338             The C<data> hash for this page. Defaults to the C<data> attribute from the Document.
339              
340             =head2 disable_content_template
341              
342             If true, disables the processing of the content as a template. This will
343             improve performance if you're not using any template directives in your content.
344              
345             This can be set in the document (L<Statocles::Document/disable_content_template>),
346             the application (L<Statocles::App/disable_content_template>), or the site
347             (L<Statocles::Site/disable_content_template>).
348              
349             =head2 next
350              
351             The path to the next document if it is part of a list.
352              
353             =head2 prev
354              
355             The path to the previous document if it is part of a list.
356              
357             =head1 METHODS
358              
359             =head2 content
360              
361             my $html = $page->content( %vars );
362              
363             Generate the document HTML by processing template directives and converting
364             Markdown. C<vars> is a set of name-value pairs to give to the template.
365              
366             =head2 vars
367              
368             my %vars = $page->vars;
369              
370             Get the template variables for this page.
371              
372             =head2 sections
373              
374             my @sections = $page->sections;
375             my $number_of_sections = $page->sections;
376             my @first_sections = $page->sections( 0, 1 );
377              
378             Get a list of rendered HTML content divided into sections. The Markdown "---"
379             marker divides sections. In scalar context, returns the number of sections.
380             You can also pass the indexes of the sections you want as arguments.
381              
382             For example, to loop over sections in the template:
383              
384             % for my $i ( 0..$page->sections ) {
385             <%= $page->sections( $i ) %>
386             % }
387              
388             =head2 tags
389              
390             my @tags = $page->tags;
391              
392             Get the list of tags for this page.
393              
394             =head2 template
395              
396             my $tmpl = $page->template;
397              
398             The L<template object|Statocles::Template> for this page. If the document has a template,
399             it will be used. Otherwise, the L<template attribute|Statocles::Page/template> will
400             be used.
401              
402             =head2 layout
403              
404             my $tmpl = $page->layout;
405              
406             The L<layout template object|Statocles::Template> for this page. If the document has a layout,
407             it will be used. Otherwise, the L<layout attribute|Statocles::Page/layout> will
408             be used.
409              
410             =head1 AUTHOR
411              
412             Doug Bell <preaction@cpan.org>
413              
414             =head1 COPYRIGHT AND LICENSE
415              
416             This software is copyright (c) 2016 by Doug Bell.
417              
418             This is free software; you can redistribute it and/or modify it under
419             the same terms as the Perl 5 programming language system itself.
420              
421             =cut