Python Web Publishing System

Here is a software package I have put together for my own use and for the use of my customers; I am releasing it as open source for all to use.

There are two related tools here, which can be used together or separately:, the site-assembler (a simple templating system), and, a website publisher using FTP.


NOTICE: Effective 2013-06-20, the development versions of these scripts have been moved to Previous downloads have been retained below for historical purposes. 1.6 uses a template file and one or more source files to build standardized web pages; variables may be set in the template and/or the source file, and then substituted in text in either file using <!--%VariableName%--> syntax.

Version 1.6:  Sorts the file listing.
Version 1.5:  Now loads additional items into the default context from the file .default in the project directory.
Version 1.4:  This is a major rewrite, adding the ability to be used as a module to dynamically create pages (i.e. CGI).  Read the docstring for more info.
Version 1.1:  Now uses time-stamps from the files to determine whether or not to build the file, similar to the standard make command.  This results in less unnecessary uploading! 2.3, a site publisher using FTP.

Version 1.8:  Sorted the file listing. Version 1.7:  Enhanced error handling (in particular, will usually pause at the end if requested even in the case of an error).
Version 1.6:  Now uses if present, with a setting of 60 seconds.
Version 1.5:  Added a 'chmod =' option to allow file modes on the current system to be applied to the target filesystem.
Version 1.4:  Fixed a pernicious bug affecting nested directories.
Version 1.3:  Emulates the "magic .site file" by automatically calling os.chdir("..") if there is not a ./.site file but there is a ../.site file.
Version 1.2:  Adds a passive option to .site (to allow control of whether or not to use passive FTP mode).
Version 1.1:  Uses a time-stamp file for more accurate (and faster) upload decisions.

.site, a sample ".site" file for


Generally, I create a directory for the website, and under that I create a directory named .master to contain the template sources.  I might also have an images folder, etc.  In the .master folder is the a template file (by default and one or more source files (with .src extensions).  The script needs a .site file in the website directory.  It generally looks like this:


Assuming I am using a Unixoid OS, I might install and in /usr/local/bin; in this case I would edit the and/or the source files, and type

~/website/.master $ with no options loads the file, then looks for files with the .src extension, and combines them, putting the results in the target directory.  The file and the source files are formatted similar to rfc822 messages: header lines formatted as: key: value, a blank line, and body text.  The body section is substituted into the template file where a "magic comment" is found:

Other magic comments are substituted with header values from the source file.  If the name cannot be found in the source file dictionary, it is searched in the template directory, and then in an internal dictionary (presently containing only date).  Further, values are themselves substituted from these dictionaries, so that values can contain "magic comments" also.  (While I am proud of this particular recursive feature I can't say that I've ever used it...)

The main benefit of all these gyrations is that my entire site can have a standardized appearance.

Anyway, after I have built the target files, I publish them:

~/website/.master $
The main .site file (in the ~/website directory in this example) contains the username, password, hostname, and remote directory to publish into. recursively publishes all subdirectories, but it specifically ignores directories and files starting with a period (so that the .master directory, .site file, etc. are not published).  A normal .site file looks like this:
# sample .site file for
# fill in required values as shown.
# use "." for directory if no
# directory change is needed on the remote
# server. use "" for source
# if the current directory is the source
# directory.
# save as .site in the top directory of
# the local web site copy.

user = "username"
pwd = "password"
host = "hostname"
directory = "directory"
source = "source-directory"

# end of file.