Recipe Examples
These are examples for what can be done with A-A-P recipes.
This is not intended to teach you writing recipes, only a few things are
explained. See the Aap manual for a verbose explanation.
The tutorial is a good place to start learning Aap, it contains plenty of
examples that are explained.
Maintaining a web site
This example shows how to maintain a web site in an easy way. With an Aap
recipe you can:
-
Upload modified files to several servers.
-
Generate pages from building blocks.
-
Do version control of the modifications.
The recipe used for this can be found at the bottom. You might want to open
it in another window, so that can look at it while reading the text.
A similar recipe is used to maintain the A-A-P web site.
Uploading
The list of files to be published on the web site is assigned to the
$HTMLFiles variable. The "publish" attribute is used to specify what
sites to upload to. This can be a list of several sites and using different
methods for uploading:
# Files that are uploaded.
HTMLFiles =
index.html
design.html
documentation.html
download.html
$PlainFiles
:attr {publish = file:~/tmp/testsite/%file%
scp://myname@xxx.sourceforge.net/xxx/%file%
ftp://ftp.my.org//pub/site/%file%}
$HTMLFiles
|
These are fake server names, of course, thus it won't actually work. But you
can see what the possibilities are: "file:" for copying the files locally on
the machine, "scp://" to use secure copy or "ftp://" for an ftp server.
Uploading will be done with the command:
aap publish
Each file will be uploaded to each of the sites specified with the "publish"
attribute.
When you make changes to a file, you can run the command again. Only the
changed file will be uploaded. Thus you do not need to remember which files
you changed. You may also add a new file to $HTMLFiles.
When one of the servers is down, the files will still be uploaded to the
others. Once the server comes back online you can run aap again and it will
only upload the files that failed.
Generating HTML Files
HTML files can be generated in many ways. For this example we will simply
concatenate files. This is sufficient for simple sites. If you have a web
server that supports PHP or another server side solution you probably want to
use that instead.
Most of our HTML files are generated in the same way. These parts are used:
- start.part: Starting the HTML file
- xxx_title.part: The page title
- top.part: top bar of the page
- middle.part: navigation bar, starts the main area
- xxx.part: main contents of the page
- bottom.part: ends the main area
- end.part: footer of the page
These files must be concatenated for most of the generated HTML files. This
rule is defined for that:
:rule %.html : %.part %_title.part
:print generating $-target
:cat start.part
$(match)_title.part
top.part
middle.part
$(match).part
bottom.part
end.part
# Remove Vim modelines from the text.
| :eval re.sub('<!-- vim:set.*?-->', '', stdin)
>! $target
|
The ":cat" command is used to to the main work of concatenating the files.
A pipe is used to filter the generated page through the ":eval" command.
This uses the Python function "re.sub()" to remove some text that should not
be in the HTML (Vim modelines).
The index page is generated in a different way. It contains a different
header and an extra counter in the footer.
A depencency is specified for it, so that the rule defined above is not used.
A dependency with build commands always overrules a rule.
index.html: index.part index_title.part index_top.part counter.part
:print generating $-target
:cat start.part
index_title.part
index_top.part
middle.part
index.part
bottom.part
counter.part
end.part
# Remove Vim modelines from the text.
| :eval re.sub('<!-- vim:set.*?-->', '', stdin)
>! $target
|
As you can see, this is nearly the same as the rule, but with a few important
differences.
This command will generate the HTML files:
aap
Can't make it any simpler than that!
Version Control
When making a lot of changes something might go wrong. Then it is good to
have your files in a version control system. If you have a local (or remote)
CVS server then doing this with Aap is very simple:
CVSFiles =
*.part
main.aap
$PlainFiles
:attr {commit = cvs://} $CVSFiles
|
The $CVSFiles variable is set to the list of files that are under version
control. Wildcards are used to include all files that end in
".part". This is a simplistic method, you might prefer listing the files
explicitly to avoid including obsolete files.
The "commit" attribute specifies what version control system to use. It is
also possible to specify the location of the repository. In this example it
is left empty, which means that the default server will be used (the server
the files were checked out from or $CVSROOT). Note that the recipe itself is
also under version control.
This command will update the files in CVS:
aap revise
Aap will go through the list of files and do the following:
- a file present in CVS is updated; when it really changed you will be
prompted to enter a changelog message
- a file not present in CVS is added to CVS
- a file not in the list but present in CVS is deleted from CVS
All this is done automatically, thus you don't need to know the cvs arguments
to be used. And you don't need to remember what files you added or
deleted.
This assumes that the directory was checked out from CVS in the past. The
User manual chapter on version control contains instructions how to start a
new project in CVS.
The Recipe
# A-A-P recipe for maintaining a web site
#
# "all" target: Create .html files from .part files. (default)
# "publish" target: upload the files.
# "revise" target: update the files in CVS
# Files that are both uploaded and kept in CVS.
PlainFiles =
images/*.png
files/presentation.pdf
# Files that are uploaded.
HTMLFiles =
index.html
design.html
documentation.html
download.html
$PlainFiles
# Files that are version-managed.
# There is no need to put the generated files in CVS, they can be generated
# again.
# There might be a few *.part files that are obsolete, but it doesn't hurt to
# keep them in CVS.
CVSFiles =
*.part
main.aap
$PlainFiles
#
# HTML GENERATION
#
# Default target: generate the .html files.
all: $HTMLFiles
# Default rule which works for most .part -> .html files, exceptions are below.
:rule %.html : %.part %_title.part
:print generating $-target
:cat start.part
$(match)_title.part
top.part
middle.part
$(match).part
bottom.part
end.part
# Remove Vim modelines from the text.
| :eval re.sub('<!-- vim:set.*?-->', '', stdin)
>! $target
# All .html files depend on these sources.
:rule %.html : start.part top.part middle.part bottom.part end.part
# Generate index.html separately, it uses a different layout.
index.html: index.part index_title.part index_top.part counter.part
:print generating $-target
:cat start.part
index_title.part
index_top.part
middle.part
index.part
bottom.part
counter.part
end.part
# Remove Vim modelines from the text.
| :eval re.sub('<!-- vim:set.*?-->', '', stdin)
>! $target
#
# UPLOADING
#
:attr {publish = file:~/tmp/testsite/%file%
scp://myname@xxx.sourceforge.net/xxx/%file%
ftp://ftp.my.org//pub/site/%file%}
$HTMLFiles
#
# VERSION MANAGEMENT
#
:attr {commit = cvs://} $CVSFiles
# vim: set sw=4 sts=4 :
|
top
|