The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Posy::Docs::UserGuide - a guide for users of Posy.

VERSION

This describes version 0.99 of Posy::Docs::UserGuide.

SYNOPSIS

        perldoc Posy::Docs::UserGuide

DESCRIPTION

Posy is a simple website content management system inspired by the design of blosxom. The filesystem is the database, there are flavour templates, and plugins. However, this system doesn't require one to write one's entry files in one particular format; one can choose from pure HTML, plain text, or blosxom format. And other formats can be dealt with if one writes a plugin to deal with them.

This is a guide to how to get your system running after you've installed it.

GUIDE

Make sure you've read the Posy and posy.cgi documentation, which tell you (a) a few terms (b) how to install the Posy modules and (c) how to install the posy.cgi CGI script (d) how to do the "bootstrap" configuration of the CGI script.

When you have followed the above instructions, you should have a Posy setup with a script and modules. It's not ready to roll yet -- you have no content!

Adding Content

With Posy, you don't need to have no fancy databases, you don't need to have web applications, you don't have to use a special format. All your content is files. Just files. Just ordinary files. Which you can edit with your favourite editor.

Every "entry" in your site is a text file saved under Posy's document "data directory". Every page on your site is composed of either one "entry" or of multiple entries stuck together.

So, to add an entry, add a file to the data directory. What sort of file? Well, you have a choice. You can make it a plain text file, which has the file extension '.txt' by default. You can make it a proper HTML file, which has the file extension '.html'. Or, for those of you who prefer something terser than HTML and more powerful than plain text, you can use the "blosxom" format (with file extension '.blx'). Blosxom format is taken from the blosxom weblogging software (http://www.blosxom.com) -- it consists of a first line which is the entry's title, and the rest of the file is basically HTML body-content (that is, what you would put between the <body> tags of a full HTML file).

All these input file formats will be converted to HTML when displayed by Posy. The text conversion is very rudimentary in the Posy core (it just sticks PRE around everything). If you want more sophisticated text-to-HTML conversion for your plain text files, you can use the Posy::Plugin::TextToHTML plugin. Or you choose not to use plain text files at all if you prefer.

This makes it very easy to change an existing site over to using Posy. Just move your files into the data directory. And then customise as you want it.

Indexes and Indexes

You probably already know that when you point your web browser at a URL that doesn't point to a specific file (such as http://www.example.com/tools/) then the browser serves up an "index" file, which is either (a) a list of all the files in that directory, (b) the contents of the "index" file, which is usually named "index.html" or "index.php" or whatever.

Posy does something similar. If you have an entry-file in a directory under the data_dir which has a base-name of "index" (for example, index.html) then Posy will display that file when the category/directory is requested. If there is no such file, then Posy will display the content of all the entries below that directory. (This behaviour can be configured in various ways - see "Flavours", "Changing Defaults", Posy::Plugin::ShortBody and Posy::Plugin::LocalDepth as a start).

So be aware, when making your entries, that "index" is a special name.

Viewing

Of course, you've got to be able to view your content. Posy has various ways of presenting the content: by path/category, by date, and a combination of the two.

To start with, look at the site/sub-site you have just created an entry for.

Now, each site's base URL is slightly different, depending on whether it lives at a domain, is hosted on an ISP's web-server, sits on your local PC, or whatever. Here are a few examples:

on your own computer

If you installed Posy on your own computer, running its own web-server, then the URL to look at is probably

        http://localhost/cgi-bin/posy.cgi

(depending on where you actually installed the script, of course!)

at your ISP

If you installed Posy in a special cgi-bin directory on your ISP's web server, you'll probably need to look at

        http://www.example.com/~username/cgi-bin/posy.cgi

(where www.example.com is your ISP and "username" is your username)

web-host with domain

If you installed Posy on you web-host's web server, but have your own domain name, then, if your domain is www.example.com, then use at something like

        http://www.example.com/posy.cgi or http://www.example.com/cgi-bin/posy.cgi

If all goes to plan, this will show the default Posy view -- not very pretty, but we can soon fix that -- displaying whatever entries you may already have created.

Viewing By Date

By default, Posy sorts the list of entries in reverse chronological order (like a weblog). If you have set a limited number of entries to display, you can't see them all -- so where did the old entries go? You can see entries for a particular date (year, month, or day) by appending the numerical values of your preferred date to your URL. This is known as a 'chrono' path-type.

Like so:

year

For a whole year's worth of entries, append the 4-digit year to the URL.

        http://www.example.com/posy.cgi/2004
(the year 2004)
month

For a month's worth of entries, append the 4-digit year and the 2-digit month to the URL.

        http://www.example.com/posy.cgi/2004/03

(March 2004)

day

For a particular day's worth of entries, append the 4-digit year, the 2-digit month, and the 2-digit day to the URL.

        http://www.example.com/posy.cgi/2004/03/22

(22nd March 2004)

Viewing By Path

You aren't just limited to looking at the top index of the site. One can select by category (aka sub-directory) just by putting the name on the end of the URL.

        http://www.example.com/posy.cgi/tools/
        http://www.example.com/posy.cgi/tools/posy/
        http://www.example.com/posy.cgi/tools/posy/plugins/

(This is known as a 'category' path-type)

And you can look at individual entries too.

        http://www.example.com/posy.cgi/tools/posy/Changes.html

(This is known as an 'entry' path-type.)

You can also indicate the path by using the 'path' parameter.

        http://www.example.com/posy.cgi?path=/tools/posy/plugins/

Viewing By Path and Date

And one can combine the two -- put the path first, then the date.

        http://www.example.com/posy.cgi/tools/posy/plugins/2004

Index Cache

The first time you run posy.cgi, you will see your first post. However, if you add another post and run the script again, you won't find it. This is because Posy uses a cached index of all entry files, and for the sake of speed, Posy doesn't update this cache until you tell it to. So how do you tell it?

The posy.cgi script takes a number of reindexing parameters, which will trigger it to rebuild and/or update the entry index cache.

reindex_all
        http://www.example.com/posy.cgi?reindex_all=1

Setting this parameter to true (1) will trigger a re-index of the whole site, clearing all values and starting from scratch. For larger sites, this can take a while.

reindex
        http://www.example.com/posy.cgi?reindex=1

Setting this parameter to true (1) will trigger a re-index of the whole site; while this does go through every file, it only updates the data for new files. For larger sites, this can take a while.

reindex_cat
        http://www.example.com/posy.cgi?reindex_cat=updates
        http://www.example.com/posy.cgi?reindex_cat=tools/posy

If you have only updated a particular category, then you may wish to just update the index cache for that particular category. Setting the 'reindex_cat' parameter to the category in question will update and add files to the entry index cache.

delindex
        http://www.example.com/posy.cgi?delindex=1

If you have just deleted some files, then setting 'delindex' to true will cause Posy to go through the entry index cache and delete from its listing, those files which are no longer there. Thus, a combination of 'reindex_cat' and 'delindex' will allow you to move and rename files without having to reindex the whole site.

If you have just added one file, then you can "magically" add it to the index cache by pointing your browser at it. For example, if you added the file 'wibble.txt' (or 'wibble.html' or 'wibble.blx') to the data directory, then if your domain is www.example.com, then

        http://www.example.com/wibble.html

will add 'wibble' to your index.

If you really hate the idea of a cached index, you can turn caching off by setting 'use_caching' to off (0) in the global config file (see "Changing Defaults").

Flavours

You may have noticed that the displayed pages are very plain. This is because Posy comes with one built-in default "flavour" (a collection of template files making up one page), which is, well, very plain.

There are also a couple of sets of example flavour files given in the Posy distribution under data/flavours: a plain "html" flavour, and an "rss" flavour. Yes, the HTML flavour is crying out to be redesigned -- that is what you are supposed to do, to customise the site to look the way that is "you".

So how do you do that? Two things you need to understand: template files and template variables.

Template Files

When Posy builds a web-page, it takes the entry data (from one or more entry files) and pastes it together with five template files (chunks) which it interpolates to create the final page.

The flavour files are put in the flavour directory (by default "data/flavours") where the most generic flavour file is called chunk.flavour (such as "head.html").

Here are the different chunks:

content_type

The MIME-type of the output page. Usually this is text/html, but some variations may call for text/plain or something else.

The "head" part of the page; which usually includes the opening <html> tag, the <head> content, and the opening <body> tag and any initial content required.

A header part of a page; it is re-generated for every entry, but if the new one is the same as the old one, it won't be repeated. This can be used, for example, to cluster together all entries written on the same date, if this template file uses the date-related variables in it (and the entries were sorted by date).

A footer part of a page; this is re-generated when a header is re-generated, but only added to the page when a header-change occurrs (as the footer part of the section begun with the previous header) or at the end of the page just before the "foot" part of the page. This can be used, for example, if one wishes to place entries inside tables or lists (and need the table or list to be closed before the next header).

entry

The template for the actual page content; for pages which source multiple entry-files per page, this is repeated for each entry file. An entry file is just an individual input content file.

The "foot" part of the page; usually contains trailing content, and the closing </body> and </html> tags.

To allow for much finer control of flavours, they can be created on a per-path, per path-type, per basename level.

For example, if you want your "tools" directory to have a different ".html" look, then create a "tools" subdirectory in the flavours directory, and create your new flavour files there. Likewise, if you want your 'chrono' pages to look different to your 'entry' pages (for example, just list a link to the entries they refer to) then you can make separate 'chrono' flavours.

For the most fine-grained approach, you can even make a flavour template for a specific file. For example, if you want a special entry flavour template for the default flavour (.html) for the tools/posy/Changes.blx entry file, you can make a flavour template file in the flavour directory called "tools/posy/entry.Changes.html".

Posy also looks for alternative path-types (that is 'top_entry' => 'entry', 'top_category' => 'category').

The template files are called:

  • chunk.basename.flavour

  • chunk.path_type.flavour

  • chunk.flavour

Template Variables

Okay, so you have your files, what do you put in them? You put template variables in them. There are basically four types of template variables -- global variables, entry variables, flow variables, and config variables.

Also see "set_vars" in Posy::Core for more information about how the template variables are set.

Global Variables

Global variables are available in any template files.

These include:

url

The URL of the posy.cgi (the URL of the site).

path_info

The full "PATH_INFO" of the path.

path_type

The type of the path (e.g 'entry', 'category').

path_cat_id

The ID of the category this path is in.

dynamic

True if the page is being generated by CGI script on a web-server.

static

True if the page is being generated by the static generation plugin Posy::Plugin::GenStatic which is used by the posy_static script to generate static pages. It is possible for both dynamic and static to be false, if the CGI script is called from the command-line.

There are also the parameter variables, which are the names of any parameters to the script, prefixed with 'param_'

Thus, the 'reindex' parameter would be called '$param_reindex'.

See "parse_path" in Posy::Core for more detailed informtation about the '$path_' variables.

Entry Variables

Entry variables are specific to the particular entry being processed, and so change from entry to entry. These have an "entry_" prefix.

These include:

entry_basename

The "basename" of this entry.

entry_title

The title of this entry.

entry_body

The contents of this entry, converted to HTML if need be.

entry_raw

The raw, unprocessed contents of this entry.

entry_path

The path of this entry.

entry_ext

The file extension of the original source entry file.

entry_html_head

The contents of the <head> tag of a HTML (.html) entry, minus the <title> tag.

entry_body_attrib

The attributes of the <body> tag of a HTML (.html) entry. That way, you can put this in the flavour template and not lose it from the original file.

        <body $entry_body_attrib>
entry_dw

The day of the week this entry was last modified.

entry_da

The day of the month this entry was last modified.

entry_month

The month this entry was last modified.

entry_year

The year this entry was last modified.

Flow Variables

These are somewhere between Global variables and Entry variables, because they are variables which are set during the Posy processing, (and thus may not be available at the start) but are not reset for each entry. In Posy::Core, these tend to be used more as part of Posy's processing, rather than for use inside flavour templates. These include things such as the list of entry-identifiers, the content of each flavour template, the interpolated content of each chunk, and the content of the page as it is being built up.

$flow_entry_count

The number of the current entry.

Note, however, that many plugins set flow variables to be used as flavour template variables, especially things designed to be put into the head of a page, such as the CSS links of Posy::Plugin::DynamicCss or Posy::Plugin::ThemeCss.

Config Variables

Config variables are caught betwixt and between, because some are available globally, and some are available only in a particular entry, because of the very flexible way in which you, the user, are able to set up config files -- see "Changing Defaults". All config variables have a prefix of 'config_'.

Here are some of them:

config_site_title

The default title for the site.

config_flavour

The default "flavour" to use if one is not given.

config_num_entries

The maximum number of entries to display per page.

There are others which are generally just used by plugins.

You can also create your very own config variables, and use them in your templates. This can be very useful for customising things, and even more powerful if you use a more sophisticated interpolator, such as that in Posy::Plugin::TextTemplate.

See "Changing Defaults" for more information.

Changing Defaults

There are two main ways of changing the look and feel of your site. One is flavours, as discussed above. The other is changing the config settings. Please don't confuse this with the "bootstrap" configuration settings inside the posy.cgi script. The general config settings are given in config files, which by default live in the data directory (but you can give them their own separate directory if you wish).

IMPORTANT NOTE: The "config variables" used inside flavour templates have a one-to-one correspondence with the config variables set inside config files, but they do not have the same names. When used inside flavour templates they have a name prefixed with 'config_'. Thus, if a config variable is called 'flavour' inside the config file, it will be called '$config_flavour' inside the template file.

The global config file is just called 'config'. The values in this file can be overridden by other files which are more specific to the context in which they are used. Thus, one can set defaults for a whole site, and then change them on a per-path, per-path-type, per-flavour and/or per-file basis.

The config files are called

  • path_type.basename.flavour.config

  • path_type.basename.config

  • path_type.flavour.config

  • basename.flavour.config

  • basename.config

  • flavour.config

  • path_type.config

  • config

Don't be daunted by the huge amount of flexibility in this: most of the time you're just going to be putting config settings in the top level most general config file: 'config'.

Okay, so what's in these config files? Very simple -- name:value pairs.

For example:

        site_title: Posy Demo Site
        num_entries: 40

Some plugins require more elaborate configuration setting, and so they depend on Posy::Plugin::YamlConfig which replaces the default configuration file format with the YAML format, a simple but powerful (and human-readable) data format.

Configurable Values

Here are some of the values which are settable for Posy. Plugins will also have their own additional config variables.

body_attrib

Default attributes of the <body> tag, for entry pages. For example,

        body_attrib: class="smooth" 

would set the BODY CSS class to "smooth", which could be the default style for the site -- useful if you have a mixture of text and HTML files and want to give them all the same look and feel.

To use this in your flavour template, you would give

        <body $config_body_attrib>

Note that this of course conflicts with the $entry_body_attrib flavour variable -- you will either have to choose one or the other, or use a more sophisticated interpolator plugin such as Posy::Plugin::TextTemplate which would enable you to use these variables conditionally.

For example, if you were using Posy::Plugin::TextTemplate you could do it this way:

        <body [==($entry_body_attrib ? $entry_body_attrib : $config_body_attrib)==]>

The above will give the entry body_attrib if it exists, otherwise it gives the config body_attrib.

flavour

The "flavour" to use if no flavour is given. (default: html)

num_entries

The maximum number of entries to display per category/chrono page. If zero, display all entries. (default: zero)

show_future_entries

Should one include entries which are dated in the future?

site_title

For flavour templates, to enable use of $config_site_title inside the template file. This is an example of the kind of config variable which is only used inside flavour templates.

sort_type

The type of sorting to do of entries (when displaying more than one). The possible types are:

time

Sort by the modification time of the entry.

time_reversed

Like 'time', but in reverse order (latest first).

name

Sort by the base-name of the entry.

name_reversed

Like 'name', but reversed.

path

Sort by the path (category + name) of the entry.

path_reversed

Like 'path', but reversed.

Default is 'time_reversed'.

use_caching

Whether or not to use entry-index cache files. (default: true) Only turn this off if you have a small site and you find caching annoying.

Plugins

Posy supports a plugin architecture, allowing the core of Posy to remain unaffected by feeping creaturitis, and allowing the features to be added to plugins instead, extending Posy to suit different environments and needs.

Plugins are generally of three kinds: those which override existing behaviour, those which add new actions, and those which provide supporting data or functions. For example, Posy::Plugin::TextTemplate overrides the interpolation mechanism of Posy, but doesn't add any new actions; Posy::Plugin::LocalDepth adds a 'filter_by_localdepth' action; Posy::Plugin::FileStats builds a file statistics cache which is used by Posy::Plugin::BinFile and by Posy::Plugin::LinkExtra; and Posy::Plugin::Categories provides the 'category_tree' and 'breadcrumb' functions which can be called from within flavour template files (if one is using Posy::Plugin::TextTemplate as the interpolator).

In order to use a plugin, three things are needed: (1) installation (2) activation (3) configuration.

Installing Plugins

Posy plugins are straightforward Perl modules, which are just installed into your system like any other Perl module. See "INSTALLATION" in Posy for different scenarios for this.

Because the plugins are standard Perl modules, then the best place to actually look for Posy plugins is on CPAN, the Comprehensive Perl Archive Network, searching at http://search.cpan.org for them. All the "standard" plugins are there, plus at least a few which other people have written.

Activating Plugins

A Posy plugin module isn't actually used by Posy unless you tell it to. This means that you can install modules on a trial basis and don't have to worry about having to remove them in order to deactivate them.

Activation consists simply of telling Posy which plugin modules to use. In the posy.cgi script, there is a "bootstrap" configuration setting which is the list of plugins to use. In the posy_static script, one gives the list of plugins either on the command-line, or in an argument file.

The order of the modules in this list is significant. This is because, for plugins which override behaviour, a plugin which comes later in the list overrides a plugin which comes earlier in the list. Look at the documentation for the individual plugins to see whether the given plugin is one for which the order is important.

The second level of activation is for those plugins which add new actions to the actions which Posy performs. If you don't add the action, then even though Posy knows about the module, it won't actually do anything with it. There are two kinds of actions, "action" actions, and "entry" actions. The individual plugin will say which type of action, if any, it provides a new action for.

Important note: Posy has a default set of actions which it performs when no list of actions is given. If you wish to add a new action, you need to supply a list of all the actions which Posy is to perform, not just the new action, since Posy has no way of knowing how this action relates to all the other actions. Instead of trying to guess, Posy simply takes any list of actions it is given, as a replacement list of actions. So when adding the first new action, one needs to take the list of default actions (which is given in the posy.cgi documentation, or one can look inside the Posy::Core module), and then add the new action in the position where it is meant to go.

Configuring Plugins

Some plugins require additional configuration, either by setting "bootstrap" settings, or by putting required settings into a config file. For example, Posy::Plugin::Pod requires one to set the 'file_extensions' "bootstrap" setting, as it adds a new type of entry file to the set of known entry files. While Posy::Plugin::ThemeCss, for example, requires a lot of information to be given in a config file.

Static Rendering

While the main orientation of Posy is to be run as a CGI script (posy.cgi) there is also a command-line script posy_static for rendering the main index, category indexes, entries and/or date indexes as regular files on your filesystem.

Static rendering is useful for those who either prefer to or are only able to (they cannot run CGI scripts) serve up files from their web server. You can render your site from the command-line on your server, or you can render your site locally (for example, on your PC or laptop) and then copy the files up to your server (with FTP or rsync for example).

You can also take a hybrid approach, statically rendering only part of your site or certain types of files, while leaving the CGI script available to do search, alternate flavours, or other plugin-related functionality.

Setup

While all the arguments to posy_static are described in its documentation, there are a few things which need to be set up first.

static_dir

You need to have a directory into which the files will be rendered. Where this is depends a lot on your particular setup. The two main choices are (a) a particular (sub)-directory on your actual website, where your server will find the files, or (b) a (temporary) staging directory, from which the files will be copied to their final destination.

state_dir

While you can reuse the state_dir which is used by dynamic rendering, some setups preclude this. For example, if you are running your own web-server which runs as a different user, if you try to use the same state_dir, it could be rendered useless as posy_static will be run as your login, not as the web-server's login, and the file permissions would be different.

config_dir

You may find it useful to use different config settings for static versus dynamic rendering. While some things can be achieved simply by checking the value of the $dynamic or $static variables, if you want something more, you could make a separate config_dir containing all the configuration files to be used when doing static rendering.

argument config file

Because you don't want to type in all those arguments (especially the lists of all the plugins and actions) at the command-line every time, it is advisable to use an argument configuration file, which contains all the common arguments you want to use. This can be referenced by adding "@argfile" to the command line. See Getopt::ArgvFile for more information.

TIPS

Here are a few tips and helpful hints for different ways of using Posy.

Hiding the Posy Script

The simplest way of using Posy is to put the CGI script somewhere, and making all your URLS refer to the posy script.

If you are using Posy for your whole site, a URL might be:

        http://www.example.com/posy.cgi/my/dir/file.html

If you are using Posy for one particular sub-directory on your site, a URL might be:

        http://www.example.com/archive/posy.cgi/my/dir/file.html

This isn't particularly transparent -- ideally you would like all your URLS to look as if Posy wasn't there, as if there were no special processing, because (a) it makes it easier to convert your site without breaking things (b) it looks nicer.

There are a number of different ways of doing this, which depend on (a) whether it is a whole site or a subdirectory (b) how much your site is amenable to server configuration, and which web-server you are using.

No matter which method you use, you will have to alter the 'url' "bootstrap" configuration variable so that it shows the "hidden" version of the base URL, because the one calculated by the script includes the path of the script.

Hiding For a Subdirectory

If you just want to run Posy for a sub-directory of your site, say, an archive, then there are a few simpler methods available.

Rename the Script

If you are able to run CGI scripts in directories other than cgi-bin, place posy.cgi into your chosen subdirectory, and rename it to index.cgi. This may or may not work for all the URLs, but it will at least work for the top entry.

ScriptAlias

If your web-server is Apache, and you have access to the global configuration file, you can set a script alias directive which applies to the given sub-directory.

        ScriptAlias /archive /var/www/cgi-bin/posy.cgi

Note that this will process all requests for things under "/archive" through Posy, and therefore you will need to use something like Posy::Plugin::BinFile if you want to have anything there besides just entries. However, it is also important to note that if you have a lot of binary files (such as images), it is more efficient to have your webserver serve them directly, rather than using the Posy::Plugin::BinFile plugin.

Apache Rewrite

If you don't have access to your web server's global configuration file, or your sysadmin/provider can't/won't make changes for you, but the web server is Apache, and you are allowed to write .htaccess files, then you can use Apache's mod_rewrite facility.

Create a .htaccess file in your HTML document directory (where all your usual web files are kept). The contents should be similar to this example:

        RewriteEngine on
        RewriteRule ^archive/?(.*)$ /~kat/cgi-bin/posy.cgi/$1

As with the ScriptAlias above, this will process all requests for that sub-directory through Posy, so you may wish to use Posy::Plugin::BinFile if you want to have anything there besides just entries.

Zeus Rewrite

The Zeus webserver also has Rewrite rules, but you can only access these if you have configuration access to the server -- in other words, if you are running it yourself. See the Zeus manual for how Zeus rewrite rules are different from Apache ones.

Static Rendering

If all else fails, one could render the contents for that sub-directory statically, and copy the files where they need to go.

Hiding For The Whole Site

Your whole site is powered by Posy, and you have your own domain.

ScriptAlias

If your web-server is Apache, and you have access to the global configuration file, you can set a script alias directive which applies to your whole site.

        ScriptAlias / /var/www/cgi-bin/posy.cgi

Note that this will process all requests through Posy, and therefore you will need to use something like Posy::Plugin::BinFile to serve up binary files such as images.

Apache Rewrite

If you don't have access to your web server's global configuration file, or your sysadmin/provider can't/won't make changes for you, but the web server is Apache, and you are allowed to write .htaccess files, then you can use Apache's mod_rewrite facility.

Put the posy.cgi script into your DOCUMENT_ROOT directory, calling it index.cgi (this is assuming that you can put CGI scripts anywhere).

Create a .htaccess file in your DOCUMENT_ROOT directory (where all your usual web files are kept). The contents should be similar to this example:

        RewriteEngine on
        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteCond %{REQUEST_FILENAME} !-d
        RewriteRule ^(.*)$ index.cgi/$1 [L,QSA]

This is different to the ScriptAlias solution, because it enables you to have a hybrid site: any files which already exist in your web directory will be served up as usual, but if it doesn't exist, then the request is passed to Posy for processing. This means that you can, for example, put all your site images in the /images directory, and they will be served up faster. It also means that you can transparently change your site (or parts of it) to static rendering, and if the static pages exist, the server will serve them without calling Posy, and if you want to change back again, all you have to do is delete the static rendered files from the web directory.

Zeus Rewrite

The Zeus webserver also has Rewrite rules, but you can only access these if you have configuration access to the server -- in other words, if you are running it yourself.

There is information on the web on how to write Zeus rewrite rules, but they are beyond the scope of this document (because I don't have control of a Zeus webserver).

Error Document

If you don't have access to the Apache mod_rewrite mechanism, but you do have a web server which allows you to set an ErrorDocument directive in an .htaccess file, you can use this method as a last resort. Posy has had special code added to check the environment for the different variables which are set when it is called as an ErrorDocument processor.

Put the posy.cgi script into your DOCUMENT_ROOT directory, calling it index.cgi (this is assuming that you can put CGI scripts anywhere).

Then put in your .htaccess file:

        ErrorDocument 404 /index.cgi

This will elicit similar behaviour to the above Apache Rewrite rules -- that is, it will call Posy to process all documents that are not found (since this is the processing for 404 (Not Found) errors).

It is less than satisfactory, however, and may not work fully on some web servers. For example, if used with a Zeus web server, while it does serve up all the pages, it still returns a 404 Not Found error code, while Apache actually pays attention to Posy saying "yes I did find it after all" and does return a "Found" status code.

This means that if one uses Zeus and this method, all search bots and link-checking bots will declare that your site has fallen off the net -- not a very desireable outcome.

Static Rendering

If all else fails, one could render the whole site statically, and copy the files where they need to go. You can also use a combination of this and the ErrorDocument approach to render most of your site statically, but still enable some dynamic rendering for less-used files.

Speed Tips

If you have a large site, and you find that the top page takes forever to render, then make an 'index' entry instead, and put most of the content in sub-directories (which you can link to by hand in the 'index' entry, or use a breadcrumb with Posy::Plugin::Categories and Posy::Plugin::TextTemplate). Having an 'index' entry means that Posy will not attempt to load up every file in the site into the index page.

A not-so-drastic, but also not so effective method is to set the 'num_entries' config setting to a small number. This is less efficient because Posy will still select and sort the entry-identifiers before it decides how many entries to display.

Similarly, Posy::Plugin::LocalDepth limits the entries displayed, by filtering the selected entry-identifiers by their "depth" in the tree. This is slightly more efficient than using 'num_entries' to limit the number of entries, because the filtering is done before the sorting.

Of course, if you want the ultimate in speed, pre-generate your site with posy_static rather than using the CGI script. The advantage is speed, the disadvantage is a loss of flexibility.

Setting The Base Dir Portably

If you have your own domain, and you also mirror your site on a different server (such as a test server on your own PC), then it can be irritating to have to edit $base_dir and $libdir every time you sync your sites. One way around this is to make sure that the base dir is in the same position relative to the DOCUMENT_ROOT, and then use the DOCUMENT_ROOT environment variable (which is set by the CGI mechanism) as a basis for figuring out where these directories are.

Here is an example, where the base_dir is ../data and the lib dir is ../data/perl/lib.

    our $base_dir;
    our $libdir;
    BEGIN {
        use File::Spec;
        # untaint DOCUMENT_ROOT
        $ENV{DOCUMENT_ROOT} =~ m#^([-._/\w]+)$#;
        my $doc_root = $1;
        my @dd = File::Spec->splitdir($doc_root);
        pop @dd;
        push @dd, 'data';
        $base_dir = File::Spec->catdir(@dd);
        push @dd, 'perl';
        push @dd, 'lib';
        $libdir = File::Spec->catdir(@dd);
    }

Posy From the Command Line

When you've updated your site, you might usually reindex your site by pointing your browser at your site and then using one or more of the 'reindex' related parameters. On the other hand, you may find it more convenient to do it from the command-line, if it so happens that the user the web-server would normally run your CGI as, is the same user as you are on the command-line (this can be the case when the "suexec" mechanism is used, which is very common with ISPs and web-hosts).

Since Posy accepts parameters from the command line, this is possible; even though "dynamic" will be false, this should not affect the index cache, since that shouldn't care whether or not the call is dynamic.

For example:

        perl ./cgi-bin/posy.cgi reindex_all=1

If you are using the above DOCUMENT_ROOT-related method of setting the base_dir, then something like the following will work on a Unix-like system:

        cd /your/document/root
        DOCUMENT_ROOT=`pwd` perl ./cgi-bin/posy.cgi reindex_all=1

In either case, when the reindexing is done, posy will then spit out the contents of the top page of the Posy-site.

This can also be used to check your site without having to point your browser at it, since you can put the output through a pager and thus have a convenient way of looking at the source.

        perl ./cgi-bin/posy.cgi path=/tools/ | less

Or you could even look at it with a console browser like w3m:

        perl ./cgi-bin/posy.cgi path=/tools/ | w3m -T 'text/html'

Maintaining A Hybrid Site

If you are using the Apache Rewrite rules for your whole site, where Posy only processes those directories and files which don't exist in the web directory, and you have a hybrid site where some parts of the site are not controlled by Posy, but the main part of the site is, then there are a few things that need to be worked around.

Say, for example, you have a 'graphics' sub-directory, and a sub-category of this is 'digitart', which is served up by Posy (and thus the contents of 'digitart' are in the Posy data-docs directory, and not on the web directory) and another sub-directory called 'gallery' which runs a photo-gallery CGI script, and hence is not suitable to be served up by Posy. Therefore the 'graphics/gallery' directory does exist in the web directory.

This creates two problems:

  • Since the 'graphics' directory exists ('graphics/gallery'), then Posy is not called when the user points their browser to http://www.example.com/graphics/, even though you want Posy to display the index-page for that page. This is because Posy will only serve files and directories that don't exist in the web directory. That directory does exist, so the web-server will serve up the generic directory index for that directory, or a "Forbidden" error, depending on the particular setup.

    If you use the URL http://www.example.com/graphics/index.html then Posy will serve that file, since there is no index file in the 'graphics' sub-directory.

    There are three possible solutions to this. One is to provide an index file which is not served by Posy -- which you would then have to create or update by hand, which would be somewhat annoying.

    The second is to provide an index file, yes, but to provide an index.cgi file, which is the same posy.cgi script which the whole site uses. If your website is on a Unix-like system, you can insure that both copies of the Posy script are the same by using a soft link.

            cd graphics
            ln -s ../cgi-bin/posy.cgi index.cgi

    The third is to add a new rewrite rule for that specific directory.

            RewriteCond %{REQUEST_FILENAME} -d
            RewriteRule ^(graphics/)$ index.cgi/$1 [L,QSA]
  • If you are using breadcrumbs or a site map (as generated by Posy::Plugin::Categories), then the 'graphics/gallery' directory won't be included since it isn't served up by Posy and isn't in the Posy data directory. You can fake out Posy by creating an empty directory in the data_dir, which will then be taken as a Category that doesn't have any entries in it.

            cd data/docs
            mkdir graphics/gallery

Another possibility depends on why you are maintaining mixed site in the first place. If you want to run a simple CGI program as well as Posy, you can actually stick the CGI program in the data_dir and have Posy treat it as an entry and run the CGI program for you with the Posy::Plugin::CgiFile plugin -- but the plugin is limited and will only work on a Linux/Unix system for simple CGI scripts which don't have setups that are too complicated.

Changing Entry Dates

If you have a site where entries are sorted by time rather than by basename or path, then you are going to be interested in the date-time information of your entry files. Posy gets that date-time information from the modification time of the given entry file. Which means that if you edit an entry, it's modification time changes, and it will be listed in a different order if you do a reindex_all rather than a reindex.

Barring the use of a plugin which changes the way that Posy gets the date-time information for a file, what does one do if one wishes to ensure that an entry file will have a particular modification date? If one is on a Unix-like system, one can use the 'touch' command. On Linux, 'touch' has the '--date' option, which will enable one to set a file's modification date and time to a specific time rather than the current time. See the 'touch' man page for details.

SEE ALSO

perl(1). Posy posy.cgi

BUGS

Please report any bugs or feature requests to the author.

AUTHOR

    Kathryn Andersen (RUBYKAT)
    perlkat AT katspace dot com
    http://www.katspace.com

COPYRIGHT AND LICENCE

Copyright (c) 2005 by Kathryn Andersen

This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.