| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package App::Followme::Guide; |
|
2
|
|
|
|
|
|
|
|
|
3
|
1
|
|
|
1
|
|
686
|
use 5.008005; |
|
|
1
|
|
|
|
|
4
|
|
|
4
|
1
|
|
|
1
|
|
5
|
use strict; |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
20
|
|
|
5
|
1
|
|
|
1
|
|
5
|
use warnings; |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
23
|
|
|
6
|
1
|
|
|
1
|
|
561
|
use integer; |
|
|
1
|
|
|
|
|
15
|
|
|
|
1
|
|
|
|
|
5
|
|
|
7
|
|
|
|
|
|
|
|
|
8
|
1
|
|
|
1
|
|
35
|
use base qw(Pod::Text); |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
599
|
|
|
9
|
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
#---------------------------------------------------------------------- |
|
11
|
|
|
|
|
|
|
# Create a new object to display the pod in this document |
|
12
|
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
sub new { |
|
14
|
1
|
|
|
1
|
1
|
1283
|
my ($pkg) = @_; |
|
15
|
|
|
|
|
|
|
|
|
16
|
1
|
|
|
|
|
6
|
my $self = Pod::Text->new(); |
|
17
|
1
|
|
|
|
|
146
|
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
|
1043
|
my ($self) = @_; |
|
25
|
|
|
|
|
|
|
|
|
26
|
1
|
|
|
|
|
2
|
my $result; |
|
27
|
1
|
|
|
|
|
8
|
$self->output_string(\$result); |
|
28
|
1
|
|
|
|
|
2339
|
$self->parse_file(__FILE__); |
|
29
|
|
|
|
|
|
|
|
|
30
|
1
|
|
|
|
|
94986
|
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 |