NAME

Posy::Core - the core methods for the Posy generator

VERSION

This describes version 0.93 of Posy::Core.

SYNOPSIS

# implicitly
use Posy qw(Posy::Core Posy::Plugin::TextTemplate ...);

# or explicitly
require Posy;

@plugins = qw(Posy::Core Posy::Plugin::TextTemplate ...);
Posy->import(@plugins);
Posy->run(%args);

DESCRIPTION

This 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 a 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.

Posy::Core provides the core functionality of the system. Other functions can be added and overridden by plugin modules.

CLASS METHODS

run

Posy->run(%args);

run is the only method you should need to use from outside this module; other methods are called internally by this one.

This method orchestrates all the work; it creates a new object, and applies all the actions.

Arguments include:

actions

The actions that should be performed by the Posy engine. If none are given, then the default sequence will be used.

entry_actions

The actions which should be performed on each entry. If none are given, then the default sequence will be used.

base_dir

The directory to use as a prefix when setting the default locations of the data_dir, the flavour_dir, the config_dir and the state_dir. This is just for convenience; if those directories are given in the arguments, we use those. (default: the current directory)

data_dir

The directory where the entry data is.

state_dir

The directory where the state-related data is (what used to be "plugins/state" in blosxom).

flavour_dir

The directory where the flavour template files are.

config_dir

The directory where the configuration files are. Defaults to being the same as data_dir.

debug_level

Setting the debug_level to something other then 0 will turn on varying levels of debugging output. The higher the number, the more voluminous the output (though generally most debugging messages are either level 1 or level 2).

OBJECT METHODS

Documentation for developers and those wishing to write plugins.

new

Make a new object. See "run" for the arguments.

init

Do some initialization of the object after it's created. Set up defaults for things which haven't been defined.

Plugin writers should override this method rather than "new" if they want to do some initialization for their plugin.

do_actions

$self->do_actions();

Do all the actions in the $self->{actions} list. (Called from "run").

Flow Action Methods

Methods implementing actions. All such methods expect a reference to a flow-state hash, and generally will update either that hash or the object itself, or both in the course of their running.

init_params

Parse the global parameters. Creates a CGI object in $self->{cgi} and checks whether we are in a CGI environment (dynamic) or not (static) and sets $self->{dynamic} and $self->{static} accordingly.

Note that "static" does not mean the same thing as with blosxom2; what actions are performed depend entirely on the $self->{actions} array; it won't be trying to generate all the files just because we aren't in CGI mode.

Sets $self->{url} if it isn't already set.

When this is not in dynamic mode, the parameters can be set (a) by passing them through the $self->{params} hash (by setting params=>{...} when calling "new" or "run"), and (b) by giving them on the command line (as "param=value" pairs). This can be useful for writing scripts that aren't CGI scripts. Note that the command-line values override the $self->{param} values.

parse_path

Parse the PATH_INFO (or 'path' parameter) to get the parts of the path and figure out various bits of information about the path. If the path is undefined, uses DOCUMENT_URI or REDIRECT_URL.

This checks whether or not the requested file/directory exists under the data directory.

Sets $self->{path} hash as follows:

info

The original PATH_INFO or equivalent.

type

The type of the path: entry, top_entry, category, top_category chrono, file.

file_key

The path in unix style without the extension; used as a key in $self->{files}.

ext

The extension of the actual entry file or "file" file.

data_file

The full path of the found file.

basename

The base name of the file without directory or extension.

cat_id

The directory (category) part of the path in unix style.

depth

The depth of the file from the top directory.

flavour

The flavour of the request.

name

The path directory with underscores instead of slashes.

year

For "chrono" paths, the year part of the request.

month

For "chrono" paths, the month part of the request. Optional.

day

For "chrono" paths, the day part of the request. Optional.

Expects parameters to have been initialized (so that it can check $self->param('path') as well as PATH_INFO).

If it fails to parse the path, sets $self->{path}->{error} to true, and $self->{path}->{info} will be the only other part set. This can be used by later actions, such as "process_path_error".

process_path_error

If there was an error parsing the path ($self->{path}->{error} is true) then flag the actions to stop.

Also sends a 404 error if we are in dynamic mode; this assumes that if it can't parse the path, it can't find the file.

This is done as a separate action method so that it makes it easier to change this behaviour.

set_config

$self->set_config($flow_state);

Set $self->{config} from the config files. Takes into account the path, but does not use chunk information; useful for setting global parameters.

index_entries

Find the entries files, the "other" files, and the categories. This uses caching by default.

Expects $self->{path} and $self->{config} to be set.

Sets $self->{reindex} if full reindexing has been done.

This will do a full reindex if (a) there are no caches existing (b) the 'reindex' parameter is true

This will do a partial reindex (one category) if the 'reindex_cat' parameter is set to a category id.

This will delete missing files from the indexes if the 'delindex' parameter is true.

This will add a single new file to the index is it is not there, and it does exist, and it is the current path request.

select_entries

$self->select_entries($flow_state);

Select entries by looking at the path information. Assumes that no entries have been selected before. Sets $flow_state->{entries}. Assumes it hasn't already been set.

filter_by_date

$self->filter_by_date($flow_state);

Filter entries by looking at the date-time information in $self->{path}. Assumes that $flow_state->{entries} has already been populated; updates it.

sort_entries

$self->sort_entries($flow_state);

Sort the selected entries (that is, $flow_state->{entries}) Checks $self->{config}->{sort_type} to determine the sort order. The possible types are: time, time_reversed, name, name_reversed, path, path_reversed (default: time_reversed)

content_type

$self->content_type($flow_state);

Set the content_type content in $flow_state->{content_type}

head_template

$self->head_template($flow_state, $current_entry, $entry_state);

Set the head template in $flow_state->{head_template} This also sets the $self->{config} for head.

foot_template

$self->foot_template($flow_state);

Set the foot template in $flow_state->{foot_template} This also sets the $self->{config} for foot.

head_render

$self->head_render($flow_state);

$self->head_render($flow_state, $current_entry, $entry_state);

Interpolate the head template into the head content; Set the head content in $flow_state->{head}

If called as an entry action, will do nothing unless the current path type ($self->{path}->{type}) is an entry; if it is an entry, this will set the entry variables and override the previous call to head_render -- this can be used to enable entry-specific head stuff.

foot_render

$self->foot_render($flow_state);

Interpolate the foot template into the foot content; Set the foot content in $flow_state->{foot}

If called as an entry action, will do nothing unless the current path type ($self->{path}->{type}) is an entry; if it is an entry, this will set the entry variables and set $flow_state->{foot}. If not called as an entry action, will not set $flow_state->{foot} if the path type is an entry and the foot has already been set.

do_entry_actions

$self->do_entry_actions($flow_state);

Process the $self->{entry_action} list.

render_page

$self->render_page($flow_state);

Put the page together by pasting together its parts in the $flow_state hash and print it (either to a file, or to STDOUT). If printing to a file, don't print content_type

Entry Action Methods

Methods implementing per-entry actions.

count_or_stop

$self->count_or_stop($flow_state, $current_entry, $entry_state)

Increment the $flow_state->{entry_count} and stop the processing of this entry if it goes beyond the required number in $self->{config}->{num_entries}.

read_entry

$self->read_entry($flow_state, $current_entry, $entry_state)

Reads in the current entry file. Sets $current_entry->{raw} with the contents.

parse_entry

$self->parse_entry($flow_state, $current_entry, $entry_state)

Parses $current_entry->{raw} into $current_entry->{title} and $current_entry->{body}. For HTML entries, it also sets $current_entry->{body_attrib} and $current_entry->{html_head}.

The template variables set are therefore:

entry_raw

The unaltered entry text.

entry_title

The entry title.

entry_body

The "body" content of the entry.

entry_html_head

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

entry_body_attrib

The attributes of the body tag.

$self->header($flow_state, $current_entry, $entry_state)

Sets the entry date vars for this entry, in $curent_entry. See "nice_date_time" for details.

Set the header content in $flow_state->{header} and add the header to @{$flow_state->{page_body}} if it is different to the previous header.

entry_template

$self->entry_template($flow_state, $current_entry, $entry_state)

Set the entry template in $entry_state->{entry_template} This also sets the $self->{config} for entry.

render_entry

$self->render_entry($flow_state, $current_entry, $entry_state)

Interpolate the current entry, replacing $current_entry->{body}.

append_entry

$self->append_entry($flow_state, $current_entry, $entry_state)

Add $current_entry->{body} to @{$flow_state->{page_body}} (This is done as a separate step so that plugins can alter the entry before it's added to the page).

Helper Methods

Methods which can be called from within other methods.

param

my $value = $self->param($name);

Return or set global parameters.

This passes the arguments on to $self->{cgi}->param(); See CGI::Minimal for more information.

set_vars

my %vars = $self->set_vars($flow_state);

my %vars = $self->set_vars($flow_state, $current_entry, $entry_state);

$content = $self->interpolate($chunk, $template, \%vars);

Sets variable hashes to be used in interpolation of templates.

This can be called from a flow action or from an entry action, and will use the given state hashes accordingly.

This sets the variable hash as follows:

  • $self->{name} where it is a simple value (eg 'url') -> $name

  • $self->{path}->{name} -> $path_name

  • $self->param('name') -> $param_<name>

  • $self->{config}->{name} -> $config_<name>

  • $flow_state->{name} -> $flow_<name>

  • $current_entry->{name} -> $entry_<name>

  • $entry_state->{name} -> $es_<name>

get_template

my $template = $self->get_template($chunk);

Get the template file for this state, taking into account $self->{path}->{cat_id}, $self->{path}->{type}, $self->{path}->{flavour}, $self->{path}->{basename} and of course $chunk

Returns (a copy of) the found template. This is so that the following actions can alter the template as they see fit.

Possible chunks are "content_type", "head", "header", "entry", "foot". The "header" and "entry" chunks are used during entry processing.

Also looks for alternative path-types (minus the 'top_')

The template files are called

  • chunk.path_type.basename.flavour

  • chunk.basename.flavour

  • chunk.path_type.flavour

  • chunk.flavour

get_config

my %config = $self->get_config($chunk);

Get the config settings for this state, taking into account $self->{path}->{cat_id}, $self->{path}->{type} $self->{path}->{basename} and $chunk

Possible chunks are nothing, "content_type", "head", "header", "entry", "foot".

The config files are called

  • path_type.chunk.basename.config

  • path_type.basename.config

  • chunk.basename.config

  • path_type.chunk.config

  • path_type.config

  • chunk.config

  • config

Returns a hash of cumulative config settings.

read_config_file

$self->read_config_file($filename);

Read the given config file, and return a hash of config settings from it. The $filename is the full name of the file to read.

The config file is made up of name:value pairs of data.

interpolate

$content = $self->interpolate($chunk, $template, \%vars);

Interpolate the contents of the vars hash with the template and return the result.

(This is passed the chunk name just in case a future plugin which overrides this method wishes to do something different depending on what chunk type it is.)

nice_date_time

my %nice_vals = $self->nice_date_time($mtime);

Given a unixtime (in seconds since whenever it was) will return a hash containing the portions of the date-time:

sec

The second.

min

The minute.

hour

The hour (24-hour time).

year

The 4-digit year.

mnum

The number of the month (1-12).

da

The day of the month.

wday

The day of the week (number).

dw

The day of the week (name).

month

The month name.

    $self->print_header(content_type=>$content_type,
	status=>$status,
	extra=>$extra);

Print a web-page header, with content-type and any extra things required for the header. The default status is $self->{path}->{status}, but this can be changed by using the 'status' argument if need be.

This is done as a separate method to enable it to be overridden by plugins such as Posy::Plugin::CgiCarp.

debug

$self->debug($level, $message);

Print a debug message (for debugging). Checks $self->{'debug_level'} to see if the message should be printed or not.

Private Methods

Methods which may or may not be here in future.

_whowasi

For debugging: say who called this

_find_file_and_ext

($fullname, $ext) = $self->_find_file_and_ext($full_path_and_filebase);

Returns the full path file and the extentsion of the given path-plus-basename-of-file; if no matching entry file exists under the data directory, the returned values are empty strings.

_look_for_template

Look for the given template with combination of features.

_look_for_config

Look for the given config with combination of features.

_wanted

$self->_wanted();

This is a method called from a wrapper 'wanted' function inside the call to File::Find::find inside the index_entries method. This does all the work in indexing the entries.

_init_caching

Initialize the caching stuff used by index_entries

_read_caches

Reads the cached information used by index_entries

_save_caches

Saved the information gathered by index_entries to caches.

extract_date

Given a unixtime (in seconds since whenever it was) will return an array containing the 4-digit year, the month (1-12) and the day of the month.

_url

Figure out the full url.

_protocol

Figure out the protocol. (taken from CGI::Simple)

_server_port

And the server port.

_server_protocol

And the server protocol.

REQUIRES

File::Spec
File::stat

File::Find
Storable
CGI::Minimal

Test::More

SEE ALSO

perl(1). Posy

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) 2004-2005 by Kathryn Andersen

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