File Coverage

lib/App/Followme/Guide.pm
Criterion Covered Total %
statement 22 22 100.0
branch n/a
condition n/a
subroutine 7 7 100.0
pod 1 2 50.0
total 30 31 96.7


line stmt bran cond sub pod time code
1             package App::Followme::Guide;
2              
3 1     1   728 use 5.008005;
  1         4  
4 1     1   5 use strict;
  1         2  
  1         19  
5 1     1   5 use warnings;
  1         2  
  1         22  
6 1     1   569 use integer;
  1         15  
  1         5  
7              
8 1     1   35 use base qw(Pod::Text);
  1         2  
  1         646  
9              
10             #----------------------------------------------------------------------
11             # Create a new object to display the pod in this document
12              
13             sub new {
14 1     1 1 1508 my ($pkg) = @_;
15              
16 1         6 my $self = Pod::Text->new();
17 1         165 return bless($self, $pkg);
18             }
19              
20             #----------------------------------------------------------------------
21             # Print the pod from this file into a string
22              
23             sub print {
24 1     1 0 955 my ($self) = @_;
25              
26 1         2 my $result;
27 1         7 $self->output_string(\$result);
28 1         2387 $self->parse_file(__FILE__);
29            
30 1         95019 return $result;
31             }
32              
33             1;
34              
35             =pod
36              
37             =encoding utf-8
38              
39             =head1 NAME
40              
41             App::Followme::Guide - How to install, configure, and run followme
42              
43             =head1 SYNOPSIS
44              
45             followme [directory]
46              
47             =head1 DESCRIPTION
48              
49             Updates a static website after changes. Constant portions of each page are
50             updated to match, text files are converted to html, indexes are created
51             for files in the archive, and changed files are uploaded to the remote server.
52              
53             The followme script is run on the directory or file passed as its argument. If
54             no argument is given, it is run on the current directory.
55              
56             If a file is passed, the script is run on the directory the file is in. In
57             addition, the script is run in quick mode, meaning that only the directory
58             the file is in is checked for changes. Otherwise, not only that directory, but
59             all directories below it are checked.
60              
61             =head1 CHANGES
62              
63             This version is version two of followme. In the past the code constructed a hash
64             and passed it to the template, which used the values in the hash to produce the
65             web page. In version two the code passes an object to the template, which calls
66             the build method for each variable in the template, passing the name of the
67             variable and a filename to retrieve it from as arguments. The module then
68             returns the value, which is used to fill in the template. The major user visible
69             change is that the template syntax has changed, the new syntax is a subset of the
70             previous syntax. Please see L<App::Followme::Template> for a description of the
71             template syntax.
72              
73             The second change is that the configuration parameters of some of the modules
74             has changed. The new configuration parameters are described in each module.
75             The motivation for the change is that placing the variable building in a separate
76             class allows more than one type of file to be handled by modules placed in the
77             configurarion file. Each class handles a type of file and the name of the class
78             which builds the variables is a configuration parameter.
79              
80             The third change is that the configuration file format has changed
81             to use a subset of yaml instead of . The new configuration file format is decribed
82             below. The biggest change is to how modules are assigned to run_before and
83             run_after. Previously this is how the configuration file would look:
84              
85             author = Your Name
86             run_before = App::Followme::FormatPage
87             run_before = App::Followme::ConvertPage
88             run_after = App::Followme::CreateSitemap
89              
90             This is how the same lines in the configuration file look now:
91              
92             author: Your Name
93             run_before:
94             - App::Followme::FormatPage
95             - App::Followme::ConvertPage
96             run_after:
97             - App::Followme::CreateSitemap
98              
99             =head1 INSTALLATION
100              
101             First, install the L<App::Followme> module from CPAN. It will copy the
102             followme script to /usr/local/bin, so it will be on your search path.
103              
104             sudo cpanm App::Followme
105              
106             Then create a folder to contain the new website. Run followme with the
107             init option in that directory
108              
109             mkdir website
110             cd website
111             followme --init
112              
113             When you run followme with the --init flag, it will install the initial
114             templates and configuration files. The initial setup is configured to update
115             pages to maintain a consistent look for the site and simplify the onboarding of
116             new content.
117              
118             The first page will serve as a prototype for the rest of your site. When you
119             look at the html page, you will see that it contains comments looking like
120              
121             <!-- section primary -->
122             <!-- endsection primary -->
123              
124             These comments mark the parts of the prototype that will change from page to
125             page from the parts that are constant across the entire site. Everything
126             outside the comments is the constant portion of the page. When you have
127             more than one html page in the folder, you can edit any page, run followme,
128             and the other pages will be updated to match it.
129              
130             So you should edit your first page and add any other files you need to create
131             the look of your site, such as the style sheets.
132              
133             You can also use followme on an existing site. Run the command
134              
135             followme --init
136              
137             in the top directory of your site. The init option will not overwrite any
138             existing files in your site. Then look at the convert page template it has
139             created:
140              
141             cat _templates/convert_page.htm
142              
143             Edit an existing page on your site to have all the section comments in this
144             template. In the template shipped with this package there are three section
145             names: meta, primary, and secondary. The meta section is in the html header
146             and contains the page metadata, although it may also contain other content
147             tht varies between pages. The primary section contains the page content that
148             is maintained by you. None of this package's modules will change it. The
149             secondary section contains content that is updated by the modules in this
150             package and you will not normally change it.
151              
152             After you edit a single page, you can place the App::Followme::EditSections
153             module in the configuration file, after the run_efore line:
154              
155             run_before:
156             - App::Followme::EditSections
157             - App::Followme::FormatPage
158             - App::Followme::ConvertPage
159              
160             If you then run followme, it will modify the other pages on your website to
161             match the page you have edited. Then remove the EditSections module from
162             the configuration file.
163              
164             =head1 CONFIGURATION
165              
166             The configuration file for followme is followme.cfg in the top directory of
167             your site. Configuration file lines are in a subset of yaml format. The format
168             is described in L<App::Followme::NestedText>. Briefy, the top level is a hash,
169             with name-value pairs in the format
170              
171             name: value
172              
173             There should be no space between the name and the colon and one space between
174             the colon and value. The value may also be an array. The array elements are listed
175             one per line preceded by a dash:
176              
177             name:
178             - first value
179             - second value
180              
181             Configuration files may also contain blank lines or comment lines
182             starting with a C<#>. Subdirectories of the top directory may also contain
183             configuration files. Values in these configuration files are combined with those
184             set in the configuration files in directories above it, If it has a parameter of
185             the same name as a configuration file in a higher directory, it overrides it for
186             that directory and its subdirectories.
187              
188             Configuration files contain the names of the Perl modules to be run by followme
189             in the parameters named run_before and run_after. These parameters should be
190             arrays, and thus are listed one per line indented from the field name and preceded
191             by a dash:
192              
193             run_before:
194             - App::Followme::FormatPage
195             - App::Followme::ConvertPage
196             run_after:
197             - App::Followme::CreateSitemap
198              
199             Perl modules are run in the order they appear in the configuration file. If they
200             are named run_before then they are run before modules in any configuration files
201             contained in subdirectories. If they are named run_after, they are run after
202             modules which are named in the configuration files in subdirectories. Other
203             parameters in the configuration files are written to a hash. This hash is passed
204             to the new method of each module as it loaded, overriding the default values of
205             the parameters when creating the new object.
206              
207             These modules are distributed with followme:
208              
209             =over 4
210              
211             =item L<App::Followme::FormatPage>
212              
213             This module updates the web pages in a folder to match the most recently
214             modified page. Each web page has sections that are different from other pages
215             and other sections that are the same. The sections that differ are enclosed in
216             html comments that look like
217              
218             <!-- section name-->
219             <!-- endsection name -->
220              
221             and indicate where the section begins and ends. When a page is changed, this
222             module checks the text outside of these comments. If that text has changed. the
223             other pages on the site are also changed to match the page that has changed.
224             Each page updated by substituting all its named blocks into corresponding block
225             in the changed page. The effect is that all the text outside the named blocks
226             are updated to be the same across all the web pages.
227              
228             In addition to normal section blocks, there are per folder section blocks.
229             The contents of these blocks is kept constant across all files in a folder and
230             all subfolders of it. If the block is changed in one file in the folder, it will
231             be updated in all the other files. Per folder section blocks look like
232              
233             <!-- section name in folder_name -->
234             <!-- endsection name -->
235              
236             where folder_name is the the folder the content is kept constant across. The
237             folder name is not a full path, it is the last folder in the path.
238              
239             =item L<App::Followme::ConvertPage>
240              
241             This module changes text files to html files. By default the text files are
242             in Markdown format, though other converters can be used. Markdown format is
243             described at:
244              
245             http://daringfireball.net/projects/markdown/
246              
247             It builds several variables and substitutes them into the page template. The
248             most significant variable is body, which is the contents of the text file
249             after it has been converted to html. The title is built from the title of
250             the file if one is put at the top of the file. If the file has no
251             title, it is built from the file name, replacing dashes with blanks and
252             capitalizing each word, The url and absolute_url are built from the html file
253             name. To change the look of the html page, edit the page template. Only blocks
254             inside the section comments will be in the resulting page, editing the text
255             outside it will have no effect on the resulting page. A complete listing of the
256             variables is given in the variables section.
257              
258             =item L<App::Followme::CreateIndex>
259              
260             This module builds an index for a directory containing links to all the files
261             with the specified extension contained in it. The same variables mentioned above
262             are calculated for each file, with the exception of body. Comments that look like
263              
264             <!-- for @files -->
265             <!-- endfor -->
266              
267             indicate the section of the template that is repeated for each file contained
268             in the index.
269              
270             =item L<App::Followme::CreateGallery>
271              
272             Create a photo gallery for images in a directory. Each image must have a
273             thumbnail image whose name has the suffix "-thumb". The suffix name is a
274             configuration parameter. The code is very similar to
275             L<App::Followme::CreateIndex>, but the template is more complex, so it is a
276             separate module.
277              
278             =item L<App::Followme::CreateRss>
279              
280             This module creates an rss file from the metadata of the most recently updated
281             files in a directory. It is a companion to App::Followme::CreateIndex and should
282             be used if you also want an rss file.
283              
284             =item L<App::Followme::CreateSitemap>
285              
286             This module creates a sitemap file, which is a text file containing the url of
287             every page on the site, one per line. It is also intended as a simple example of
288             how to write a module that can be run by followme.
289              
290             =item L<App::Followme::UploadSite>
291              
292             This module uploads changed files to a remote site. The default method to do the
293             uploads is local copy, but that can be changed by changing the parameter upload_pkg.
294             This package computes a checksum for every file in the site. If the checksum has
295             changed since the last time it was run, the file is uploaded to the remote site.
296             If there is a checksum, but no local file, the file is deleted from the remote
297             site. If followme is run in quick mode, only files whose modification date is
298             later then the last time it was run are checked.
299              
300             =back
301              
302             =head1 RUNNING
303              
304             The followme script is run on the directory or file passed as its argument. If
305             no argument is given, it is run on the current directory. If a file is passed,
306             the script is run on the directory the file is in and followme is run in
307             quick mode. Quick mode is an implicit promise that only the named file has
308             been changed since last time. Each module can make of this assumption what it
309             will, but it is supposed to shorten the list of files examined.
310              
311             Followme looks for its configuration files in all the directories above the
312             directory it is run from and runs all the modules it finds in them. But they are
313             are only run on the folder it is run from and subfolders of it. Followme only
314             looks at the folder it is run from to determine if other files in the folder
315             need to be updated. So after changing a file, followme should be run from the
316             directory containing the file.
317             Templates support the basic control structures in Perl: "for" loops and
318             "if-else" blocks. Creating output is a two step process. First you generate a
319             subroutine from one or more templates, then you call the subroutine with your
320             data to generate the output.
321              
322             The template format is line oriented. Commands are enclosed in html comments
323             (<!-- -->). A command may be preceded by white space. If a command is a block
324             command, it is terminated by the word "end" followed by the command name. For
325             example, the "for" command is terminated by an "endfor" command and the "if"
326             command by an "endif" command.
327              
328             All lines may contain variables. As in Perl, variables are a sigil character
329             ('$' or '@') followed by one or more word characters. For example, C<$name> or
330             C<@names>. To indicate a literal character instead of a variable, precede the
331             sigil with a backslash. When you run the subroutine that this module generates,
332             you pass it a metadata object. The subroutine replaces variables in the template
333             with the value in the field built by the metadata object.
334              
335             If the first non-white characters on a line are the command start string, the
336             line is interpreted as a command. The command name continues up to the first
337             white space character. The text following the initial span of white space is the
338             command argument. The argument continues up to the command end string.
339              
340             Variables in the template have the same format as ordinary Perl variables,
341             a string of word characters starting with a sigil character. for example,
342              
343             $body @files
344              
345             are examples of variables. Array variable names (variable names starting with
346             a C<@>) may have a suffix that indicates how the array is sorted. You can add
347             a suffix to a scalar variable (variable names strting with a C<$>) but it
348             will have no effect. The format for the name is:
349              
350             @data_field[_by_$sort_field][_reversed]
351              
352             the brackets are not part of the variable name. They are there to indicate that
353             these sections are optional. Two examples of variables with sort suffixes are
354              
355             @files_by_size
356             @all_files_by_mdate_reversed
357              
358             The second suffix, _reversed, indicates that the variable is sorted from
359             largest to smallest instead of the usual format, from smallest to largest.
360             When used with date fields _reversed indicates the variable is sorted from
361             most recent to oldest.
362              
363             The following commands are supported in templates:
364              
365             =over 4
366              
367             =item do
368              
369             The remainder of the line is interpreted as Perl code.
370              
371             =item for
372              
373             Expand the text between the "for" and "endfor" commands several times. The
374             argument to the "for" command should be an expression evaluating to a list. The
375             code will expand the text in the for block once for each element in the list.
376              
377             <ul>
378             <!-- for @files -->
379             <li><a href="$url">$title</a></li>
380             <!-- endfor -->
381             </ul>
382              
383             =item if
384              
385             The text until the matching C<endif> is included only if the expression in the
386             "if" command is true. If false, the text is skipped.
387              
388             <div class="column">
389             <!-- for @files -->
390             <!-- if $count % 20 == 0 -->
391             </div>
392             <div class="column">
393             <!-- endif -->
394             $title<br />
395             <!-- endfor -->
396             </div>
397              
398             =item else
399              
400             The "if" and "for" commands can contain an C<else>. The text before the "else"
401             is included if the expression in the enclosing command is true and the
402             text after the "else" is included if the "if" command is false or the "for"
403             command does not execute. You can also place an "elsif" command inside a block,
404             which includes the following text if its expression is true.
405              
406             =back
407              
408             =head1 TEMPLATES
409              
410             Templates are read either from the same directory as the configuration file
411             containing the name of the module being run or from the _templates subdirectory
412             of the top directory of the site. For more information about the use of
413             templates, see L<App::Followme::Template>.
414              
415             =head1 VARIABLES
416              
417             Templates contain if commands, for loops and variables. The following variables
418             are arrays that can be used as arguments to for loops:
419              
420             =over 4
421              
422             =item @files
423              
424             An array of files in a directory. The files in the list are controlled by the
425             configuration variables extension, exclude, and exclude_index.
426              
427             =item @all_files
428              
429             An array of all files in a directory and its subdirectories. The files are
430             controlled by the same configuration variables as @files.
431              
432             =item @top_files
433              
434             An array of the most recently modified files in a directory and its
435             subdirectories. The number of files in the array is controlled by configuration
436             variable list_length. The files in the list are controlled by the same
437             configuration variables as used by @files.
438              
439             =item @folders
440              
441             An array of subdirectories in a directory. The subdirectories in the list are
442             controlled by the configuration parameter exclude_dirs.
443              
444             =item @breadcrumbs
445              
446             An array of index file urls of the directories above the directory containing
447             the current file.
448              
449             =item @related_files
450              
451             A list of files with the same file root name as a specified file. This
452             list is not filtered by the configuration variables extension and exclude.
453              
454             =item @newest_file
455              
456             An array with one element, the most recently modified file in a directory
457             or its subdirectories. It is an array so that other variables can be used
458             inside its for loop.
459              
460             =back
461              
462             The following variables can only be used inside of loops:
463              
464             =over 4
465              
466             =item @loop
467              
468             A copy of the array in the enclosing for loop. This is used to build double
469             for loops over the same array.
470              
471             =item @thumb_file
472              
473             An array with only one element, the name of the thumbnail file for an image file.
474             It is an array so that other variables that are functions of the name can be used
475             inside its for loop.
476              
477             =item $is_first
478              
479             True for the first pass through the for loop, false for all following passes. Used
480             in if statements.
481              
482             =item $is_last
483              
484             True for the last pass through the for loop, false for all previous passes. Used in
485             if statements.
486              
487             =item $count
488              
489             The count of the pass through the loop. Starts at one and goes up to the number of
490             elements in the array.
491              
492             =item $target
493              
494             The count prefixed by a string, which is set by the configuration variable
495             target_prefix. It is used to construct tatgets for links within a web page.
496              
497             =item $target_previous
498              
499             The count of the previous pass through the for loop, prefixed by the configuration
500             variable target_prefix. It is a zero length string for the first pass through the
501             loop.
502              
503             =item $target_next
504              
505             The count of the next pass through the for loop, prefixed by the configuration
506             variable target_prefix. It is a zero length string for the last pass through the
507             loop.
508              
509             =item $url_previous
510              
511             The relative url of the previous file processed by the for loop. It is a zero
512             length string for the first pass through the for loop.
513              
514             =item $url_next
515              
516             The relative url of the next file to be processed by the for loop. It is a zero
517             length string for the last pass through the for loop.
518              
519             =back
520              
521             The following variables can be used inside or outside of for loop. If used inside,
522             the refer to the filename of the current iteration of the loop. If outside, they
523             refer to the current file being processed.
524              
525             =over 4
526              
527             =item $remote_url
528              
529             The absolute url of the top folder on the site on the remote system. Set by the
530             configuration variable of the same name.
531              
532             =item $site_url
533              
534             The absolute url of the top folder on the site on the local system. Set by the
535             configuration variable of the same name. If the configuration variable is not
536             set, it is constructed from the name of the top folder of the site.
537              
538             =item $url
539              
540             The url of a file, relative to the url of the top folder.
541              
542             =item $index_url
543              
544             The relative url of the index file in the same folder
545              
546             =item $absolute_url
547              
548             The relative url of a file prefixed by the site url.
549              
550             =item $url_base
551              
552             The relative url of a file without any file extension. Used to create the urls of
553             any related files.
554              
555             =item $name
556              
557             The name of a file.
558              
559             =item $extension
560              
561             The extension of a filename.
562              
563             =item $is_index
564              
565             True if a file is an index file, that is, its name minus the extension is "index".
566             Used in if statements.
567              
568             =item $date
569              
570             The creation date of a file, if available, the date of last modification, if not.
571             The format of this variable is set by the configuration variable date_format.
572              
573             =item $mdate
574              
575             The date of last modification of a file. The format of this variable is set by
576             the configuration variable date_format.
577              
578             =item $size
579              
580             The size of the file in bytes.
581              
582             =item $title
583              
584             The title of a file. Constructed from the filename if it is not otherwise
585             available.
586              
587             =item $body
588              
589             The body text of a file.
590              
591             =item $summary
592              
593             A summary of the file, constructed from the first paragraph of the body.
594              
595             =item $description
596              
597             A description of the contents of the file, constructed from the first sentence
598             of the body if it is not otherwise available.
599              
600             =item $keywords
601              
602             A comma separated list of keywords describing a file. Constructed from the name
603             of the folder containing the file if it is not otherwise available.
604              
605             =item $author
606              
607             The name of the author of a file. Taken from the configuration variable of the
608             same name if it is not otherwise available.
609              
610             =back
611              
612             =head1 MODULES
613              
614             New modules can be written and then invoked via the configuration file, exactly
615             like the modules that have been distributed with App::Followme. Each module to
616             be run must have new and run methods. An object of the module's class is created
617             by calling the new method with the a reference to a hash containing the
618             configuration parameters. The run method is then called with the directory as
619             its argument.
620              
621             The signature of the new method is
622              
623             $obj = $module_name->new($configuration);
624              
625             where $configuration is a reference to a hash containing the configuration
626             parameters. $module name is the same as the name in the configuration file.
627              
628             All the modules distributed with App::Followme subclass
629             App::Followme::Module to access its methods, which provide consistent
630             behavior, such as looping over files and template handling. It also supplies a
631             new method, so if you subclass it, you will not need to supply a new method in
632             your class.
633              
634             The signature of the run method is
635              
636             $obj->run($directory);
637              
638             where $obj is the object created by the new method and $directory is the name
639             of the directory the module is being run on. All modules included in
640             App::Followme use L<App::Followme::Module> as a base class, so they can use its
641             methods, such as visiting all files in a directory and compiling a template. If
642             you wish to write your own module, you can use L<App::Followme::CreateSitemap>
643             as a guide. If you use App::Followme::Module as a base class, you should not
644             supply your own new method, but rely on the new method in
645             L<App::Followme::ConfiguredObject>, which you will inherit.
646              
647             =head1 LICENSE
648              
649             Copyright (C) Bernie Simon.
650              
651             This library is free software; you can redistribute it and/or modify
652             it under the same terms as Perl itself.
653              
654             =head1 AUTHOR
655              
656             Bernie Simon E<lt>bernie.simon@gmail.comE<gt>
657              
658             =cut