File Coverage

blib/lib/Statocles/Document.pm
Criterion Covered Total %
statement 9 9 100.0
branch n/a
condition n/a
subroutine 3 3 100.0
pod n/a
total 12 12 100.0


line stmt bran cond sub pod time code
1             package Statocles::Document;
2             our $VERSION = '0.086';
3             # ABSTRACT: Base class for all Statocles documents
4              
5 68     68   437 use Statocles::Base 'Class';
  68         145  
  68         520  
6 68     68   499761 use Statocles::Image;
  68         235  
  68         2641  
7 68     68   592 use Statocles::Util qw( derp );
  68         148  
  68         53207  
8              
9             #pod =attr path
10             #pod
11             #pod The path to this document. This is not settable from the frontmatter.
12             #pod
13             #pod =cut
14              
15             has path => (
16             is => 'rw',
17             isa => Path,
18             coerce => Path->coercion,
19             );
20              
21             #pod =attr store
22             #pod
23             #pod The Store this document comes from. This is not settable from the
24             #pod frontmatter.
25             #pod
26             #pod =cut
27              
28             has store => (
29             is => 'ro',
30             isa => Store,
31             coerce => Store->coercion,
32             );
33              
34             #pod =attr title
35             #pod
36             #pod ---
37             #pod title: My First Post
38             #pod ---
39             #pod
40             #pod The title of this document. Used in the template and the main page
41             #pod title. Any unsafe characters in the title (C<E<lt>>, C<E<gt>>, C<">, and
42             #pod C<&>) will be escaped by the template, so no HTML allowed.
43             #pod
44             #pod =cut
45              
46             has title => (
47             is => 'rw',
48             isa => Str,
49             );
50              
51             #pod =attr author
52             #pod
53             #pod ---
54             #pod author: preaction <doug@example.com>
55             #pod ---
56             #pod
57             #pod The author of this document. Optional. Either a simple string containing
58             #pod the author's name and optionally, in E<gt>E<lt>, the author's e-mail address,
59             #pod or a hashref of L<Statocles::Person attributes|Statocles::Person/ATTRIBUTES>.
60             #pod
61             #pod ---
62             #pod # Using Statocles::Person attributes
63             #pod author:
64             #pod name: Doug Bell
65             #pod email: doug@example.com
66             #pod ---
67             #pod
68             #pod =cut
69              
70             has author => (
71             is => 'rw',
72             isa => Person,
73             coerce => Person->coercion,
74             );
75              
76             #pod =attr status
77             #pod
78             #pod The publishing status of this document. Optional. Statocles apps can
79             #pod examine this to determine whether to turn a document into a page. The
80             #pod default value is C<published>; other reasonable values could include
81             #pod C<draft> or C<private>.
82             #pod
83             #pod =cut
84              
85             has status => (
86             is => 'rw',
87             isa => Str,
88             default => 'published',
89             );
90              
91             #pod =attr content
92             #pod
93             #pod The raw content of this document, in markdown. This is everything below
94             #pod the ending C<---> of the frontmatter.
95             #pod
96             #pod =cut
97              
98             has content => (
99             is => 'rw',
100             isa => Str,
101             );
102              
103             #pod =attr tags
104             #pod
105             #pod ---
106             #pod tags: recipe, beef, cheese
107             #pod tags:
108             #pod - recipe
109             #pod - beef
110             #pod - cheese
111             #pod ---
112             #pod
113             #pod The tags for this document. Tags are used to categorize documents.
114             #pod
115             #pod Tags may be specified as an array or as a comma-separated string of
116             #pod tags.
117             #pod
118             #pod =cut
119              
120             has tags => (
121             is => 'rw',
122             isa => ArrayRef,
123             default => sub { [] },
124             coerce => sub {
125             return [] unless $_[0];
126             if ( !ref $_[0] ) {
127             return [ split /\s*,\s*/, $_[0] ];
128             }
129             return $_[0];
130             },
131             );
132              
133             #pod =attr links
134             #pod
135             #pod ---
136             #pod links:
137             #pod stylesheet:
138             #pod - href: /theme/css/extra.css
139             #pod alternate:
140             #pod - href: http://example.com/blog/alternate
141             #pod title: A contributed blog
142             #pod ---
143             #pod
144             #pod Related links for this document. Links are used to build relationships
145             #pod to other web addresses. Link categories are named based on their
146             #pod relationship. Some possible categories are:
147             #pod
148             #pod =over 4
149             #pod
150             #pod =item stylesheet
151             #pod
152             #pod Additional stylesheets for the content of this document.
153             #pod
154             #pod =item script
155             #pod
156             #pod Additional scripts for the content of this document.
157             #pod
158             #pod =item alternate
159             #pod
160             #pod A link to the same document in another format or posted to another web site
161             #pod
162             #pod =back
163             #pod
164             #pod Each category contains an arrayref of hashrefs of L<link objects|Statocles::Link>.
165             #pod See the L<Statocles::Link|Statocles::Link> documentation for a full list of
166             #pod supported attributes. The most common attributes are:
167             #pod
168             #pod =over 4
169             #pod
170             #pod =item href
171             #pod
172             #pod The URL for the link.
173             #pod
174             #pod =item text
175             #pod
176             #pod The text of the link. Not needed for stylesheet or script links.
177             #pod
178             #pod =back
179             #pod
180             #pod =cut
181              
182             has links => (
183             is => 'rw',
184             isa => LinkHash,
185             default => sub { +{} },
186             coerce => LinkHash->coercion,
187             );
188              
189             #pod =attr images
190             #pod
191             #pod ---
192             #pod images:
193             #pod title:
194             #pod src: title.jpg
195             #pod alt: A title image for this post
196             #pod banner: banner.jpg
197             #pod ---
198             #pod
199             #pod Related images for this document. These are used by themes to display
200             #pod images in appropriate templates. Each image has a category, like C<title>,
201             #pod C<banner>, or C<thumbnail>, mapped to an L<image object|Statocles::Image>.
202             #pod See the L<Statocles::Image|Statocles::Image> documentation for a full
203             #pod list of supported attributes. The most common attributes are:
204             #pod
205             #pod =over 4
206             #pod
207             #pod =item src
208             #pod
209             #pod The source path of the image. Relative paths will be resolved relative
210             #pod to this document.
211             #pod
212             #pod =item alt
213             #pod
214             #pod The alternative text to display if the image cannot be downloaded or
215             #pod rendered. Also the text to use for non-visual media.
216             #pod
217             #pod =back
218             #pod
219             #pod =cut
220              
221             has images => (
222             is => 'ro',
223             isa => HashRef[InstanceOf['Statocles::Image']],
224             default => sub { +{} },
225             coerce => sub {
226             my ( $ref ) = @_;
227             my %img;
228             for my $name ( keys %$ref ) {
229             my $attrs = $ref->{ $name };
230             if ( !ref $attrs ) {
231             $attrs = { src => $attrs };
232             }
233             $img{ $name } = Statocles::Image->new(
234             %{ $attrs },
235             );
236             }
237             return \%img;
238             },
239             );
240              
241             #pod =attr date
242             #pod
243             #pod ---
244             #pod date: 2015-03-27
245             #pod date: 2015-03-27 12:04:00
246             #pod ---
247             #pod
248             #pod The date/time this document is for. For pages, this is the last modified date.
249             #pod For blog posts, this is the post's date.
250             #pod
251             #pod Should be in C<YYYY-MM-DD> or C<YYYY-MM-DD HH:MM:SS> format.
252             #pod
253             #pod =cut
254              
255             has date => (
256             is => 'rw',
257             isa => DateTimeObj,
258             coerce => DateTimeObj->coercion,
259             predicate => 'has_date',
260             );
261              
262             #pod =attr template
263             #pod
264             #pod ---
265             #pod template: /blog/recipe.html
266             #pod ---
267             #pod
268             #pod The path to a template override for this document. If set, the L<document
269             #pod page|Statocles::Page::Document> will use this instead of the template provided
270             #pod by the application.
271             #pod
272             #pod The template path should not have the final extention (by default C<.ep>).
273             #pod Different template parsers will have different extentions.
274             #pod
275             #pod =cut
276              
277             has template => (
278             is => 'rw',
279             isa => Maybe[ArrayRef[Str]],
280             coerce => sub {
281             return $_[0] if ref $_[0];
282             return [ grep { $_ ne '' } split m{/}, $_[0] ];
283             },
284             predicate => 'has_template',
285             );
286              
287             #pod =attr layout
288             #pod
289             #pod ---
290             #pod layout: /site/layout-dark.html
291             #pod ---
292             #pod
293             #pod The path to a layout template override for this document. If set, the L<document
294             #pod page|Statocles::Page::Document> will use this instead of the layout provided
295             #pod by the application.
296             #pod
297             #pod The template path should not have the final extention (by default C<.ep>).
298             #pod Different template parsers will have different extentions.
299             #pod
300             #pod =cut
301              
302             has layout => (
303             is => 'rw',
304             isa => Maybe[ArrayRef[Str]],
305             coerce => sub {
306             return $_[0] if ref $_[0];
307             return [ grep { $_ ne '' } split m{/}, $_[0] ];
308             },
309             predicate => 'has_layout',
310             );
311              
312             #pod =attr data
313             #pod
314             #pod ---
315             #pod data:
316             #pod ingredients:
317             #pod - Eggs
318             #pod - Milk
319             #pod - Cheese
320             #pod ---
321             #pod % for my $item ( @{ $self->data->{ingredients} } ) {
322             #pod <%= $item %>
323             #pod % }
324             #pod
325             #pod A hash of extra data to attach to this document. This is available
326             #pod immediately in the document content, and later in the page template.
327             #pod
328             #pod Every document's content is parsed as a template. The C<data> attribute can be
329             #pod used in the template to allow for some structured data that would be cumbersome
330             #pod to have to mark up time and again.
331             #pod
332             #pod =cut
333              
334             has data => (
335             is => 'rw',
336             );
337              
338             #pod =attr disable_content_template
339             #pod
340             #pod ---
341             #pod disable_content_template: true
342             #pod ---
343             #pod
344             #pod This disables processing the content as a template. This can speed up processing
345             #pod when the content is not using template directives.
346             #pod
347             #pod This can be also set in the application
348             #pod (L<Statocles::App/disable_content_template>), or for the entire site
349             #pod (L<Statocles::Site/disable_content_template>).
350             #pod
351             #pod =cut
352              
353             has disable_content_template => (
354             is => 'ro',
355             isa => Bool,
356             lazy => 1,
357             default => 0,
358             predicate => 'has_disable_content_template',
359             );
360              
361             around BUILDARGS => sub {
362             my ( $orig, $self, @args ) = @_;
363             my $args = $self->$orig( @args );
364             if ( defined $args->{data} && ref $args->{data} ne 'HASH' ) {
365             derp qq{Invalid data attribute in document "%s". Data attributes that are not hashes are deprecated and will be removed in v2.0. Please use a hash instead.},
366             $args->{path};
367             }
368             return $args;
369             };
370              
371             1;
372              
373             __END__
374              
375             =pod
376              
377             =encoding UTF-8
378              
379             =head1 NAME
380              
381             Statocles::Document - Base class for all Statocles documents
382              
383             =head1 VERSION
384              
385             version 0.086
386              
387             =head1 DESCRIPTION
388              
389             A Statocles::Document is the base unit of content in Statocles.
390             L<Applications|Statocles::App> take documents to build
391             L<pages|Statocles::Page>.
392              
393             Documents are usually written as files, with the L<content|/content> in Markdown,
394             and the other attributes as frontmatter, a block of YAML at the top of the file.
395              
396             An example file with frontmatter looks like:
397              
398             ---
399             title: My Blog Post
400             author: preaction
401             links:
402             stylesheet:
403             - href: /theme/css/extra.css
404             ---
405             In my younger and more vulnerable years, my father gave me some
406              
407             =head1 ATTRIBUTES
408              
409             =head2 path
410              
411             The path to this document. This is not settable from the frontmatter.
412              
413             =head2 store
414              
415             The Store this document comes from. This is not settable from the
416             frontmatter.
417              
418             =head2 title
419              
420             ---
421             title: My First Post
422             ---
423              
424             The title of this document. Used in the template and the main page
425             title. Any unsafe characters in the title (C<E<lt>>, C<E<gt>>, C<">, and
426             C<&>) will be escaped by the template, so no HTML allowed.
427              
428             =head2 author
429              
430             ---
431             author: preaction <doug@example.com>
432             ---
433              
434             The author of this document. Optional. Either a simple string containing
435             the author's name and optionally, in E<gt>E<lt>, the author's e-mail address,
436             or a hashref of L<Statocles::Person attributes|Statocles::Person/ATTRIBUTES>.
437              
438             ---
439             # Using Statocles::Person attributes
440             author:
441             name: Doug Bell
442             email: doug@example.com
443             ---
444              
445             =head2 status
446              
447             The publishing status of this document. Optional. Statocles apps can
448             examine this to determine whether to turn a document into a page. The
449             default value is C<published>; other reasonable values could include
450             C<draft> or C<private>.
451              
452             =head2 content
453              
454             The raw content of this document, in markdown. This is everything below
455             the ending C<---> of the frontmatter.
456              
457             =head2 tags
458              
459             ---
460             tags: recipe, beef, cheese
461             tags:
462             - recipe
463             - beef
464             - cheese
465             ---
466              
467             The tags for this document. Tags are used to categorize documents.
468              
469             Tags may be specified as an array or as a comma-separated string of
470             tags.
471              
472             =head2 links
473              
474             ---
475             links:
476             stylesheet:
477             - href: /theme/css/extra.css
478             alternate:
479             - href: http://example.com/blog/alternate
480             title: A contributed blog
481             ---
482              
483             Related links for this document. Links are used to build relationships
484             to other web addresses. Link categories are named based on their
485             relationship. Some possible categories are:
486              
487             =over 4
488              
489             =item stylesheet
490              
491             Additional stylesheets for the content of this document.
492              
493             =item script
494              
495             Additional scripts for the content of this document.
496              
497             =item alternate
498              
499             A link to the same document in another format or posted to another web site
500              
501             =back
502              
503             Each category contains an arrayref of hashrefs of L<link objects|Statocles::Link>.
504             See the L<Statocles::Link|Statocles::Link> documentation for a full list of
505             supported attributes. The most common attributes are:
506              
507             =over 4
508              
509             =item href
510              
511             The URL for the link.
512              
513             =item text
514              
515             The text of the link. Not needed for stylesheet or script links.
516              
517             =back
518              
519             =head2 images
520              
521             ---
522             images:
523             title:
524             src: title.jpg
525             alt: A title image for this post
526             banner: banner.jpg
527             ---
528              
529             Related images for this document. These are used by themes to display
530             images in appropriate templates. Each image has a category, like C<title>,
531             C<banner>, or C<thumbnail>, mapped to an L<image object|Statocles::Image>.
532             See the L<Statocles::Image|Statocles::Image> documentation for a full
533             list of supported attributes. The most common attributes are:
534              
535             =over 4
536              
537             =item src
538              
539             The source path of the image. Relative paths will be resolved relative
540             to this document.
541              
542             =item alt
543              
544             The alternative text to display if the image cannot be downloaded or
545             rendered. Also the text to use for non-visual media.
546              
547             =back
548              
549             =head2 date
550              
551             ---
552             date: 2015-03-27
553             date: 2015-03-27 12:04:00
554             ---
555              
556             The date/time this document is for. For pages, this is the last modified date.
557             For blog posts, this is the post's date.
558              
559             Should be in C<YYYY-MM-DD> or C<YYYY-MM-DD HH:MM:SS> format.
560              
561             =head2 template
562              
563             ---
564             template: /blog/recipe.html
565             ---
566              
567             The path to a template override for this document. If set, the L<document
568             page|Statocles::Page::Document> will use this instead of the template provided
569             by the application.
570              
571             The template path should not have the final extention (by default C<.ep>).
572             Different template parsers will have different extentions.
573              
574             =head2 layout
575              
576             ---
577             layout: /site/layout-dark.html
578             ---
579              
580             The path to a layout template override for this document. If set, the L<document
581             page|Statocles::Page::Document> will use this instead of the layout provided
582             by the application.
583              
584             The template path should not have the final extention (by default C<.ep>).
585             Different template parsers will have different extentions.
586              
587             =head2 data
588              
589             ---
590             data:
591             ingredients:
592             - Eggs
593             - Milk
594             - Cheese
595             ---
596             % for my $item ( @{ $self->data->{ingredients} } ) {
597             <%= $item %>
598             % }
599              
600             A hash of extra data to attach to this document. This is available
601             immediately in the document content, and later in the page template.
602              
603             Every document's content is parsed as a template. The C<data> attribute can be
604             used in the template to allow for some structured data that would be cumbersome
605             to have to mark up time and again.
606              
607             =head2 disable_content_template
608              
609             ---
610             disable_content_template: true
611             ---
612              
613             This disables processing the content as a template. This can speed up processing
614             when the content is not using template directives.
615              
616             This can be also set in the application
617             (L<Statocles::App/disable_content_template>), or for the entire site
618             (L<Statocles::Site/disable_content_template>).
619              
620             =head1 SEE ALSO
621              
622             =over 4
623              
624             =item L<Statocles::Help::Content>
625              
626             The content guide describes how to edit content in Statocles sites, which are
627             represented by Document objects.
628              
629             =back
630              
631             =head1 AUTHOR
632              
633             Doug Bell <preaction@cpan.org>
634              
635             =head1 COPYRIGHT AND LICENSE
636              
637             This software is copyright (c) 2016 by Doug Bell.
638              
639             This is free software; you can redistribute it and/or modify it under
640             the same terms as the Perl 5 programming language system itself.
641              
642             =cut