Daizu
view release on metacpan or search on metacpan
lib/Daizu.pm view on Meta::CPAN
trim trim_with_empty_null
validate_number validate_uri validate_mime_type
validate_date db_datetime
db_row_exists db_row_id db_select db_insert db_update db_delete
wc_file_data
guid_first_last_times
load_class
xml_attr xml_croak
daizu_data_dir
);
=head1 NAME
Daizu - class for accessing Daizu CMS from Perl
=head1 INTRODUCTION
Daizu CMS is an experimental content management system. It uses content
stored in a Subversion repository, and keeps track of it in a PostgreSQL
database. It is an attempt to solve some of the underlying problems of
content management once and for all. As such the development so far has
focused on the 'back end' parts of the system, and it doesn't really have
a user interface to speak of. It's certainly not ready for less technical
users yet. More information is available on the Daizu website:
L<http://www.daizucms.org/>
=head1 DESCRIPTION
Most access to Daizu functionality requires a Daizu object. It provides
a database handle for access to the 'live' content data, and a L<SVN::Ra>
object for access to the Subversion repository.
Some other classes are documented as requiring a C<$cms> value as the
first argument to their constructors or methods. This should always be
a Daizu object.
=head2 CONSTANTS
=over
=item $Daizu::VERSION
The version number of Daizu CMS (as a whole, not just this module).
=item $Daizu::DEFAULT_CONFIG_FILENAME
The full path and filename of the config file which will be read by
default, if none is specified in the constructor call or the environment.
Value: I</etc/daizu/config.xml>
=item $Daizu::CONFIG_NS
The URI used as an XML namespace for the elements in the config file.
Value: L<http://www.daizucms.org/ns/config/>
=item $Daizu::HTML_EXTENSION_NS
The URI used as an XML namespace for special elements in XHTML content.
Value: L<http://www.daizucms.org/ns/html-extension/>
=item $Daizu::HIDING_FILENAMES
A list of file and directory names which prevent any publication of
files with one of the names, or anything inside a directory so named.
Separated by '|' so that the whole string can be included in Perl
and PostgreSQL regular expressions.
Value: C<_template|_hide>
=cut
our $VERSION = '0.3';
our $DEFAULT_CONFIG_FILENAME = '/etc/daizu/config.xml';
our $CONFIG_NS = 'http://www.daizucms.org/ns/config/';
our $HTML_EXTENSION_NS = 'http://www.daizucms.org/ns/html-extension/';
our $HIDING_FILENAMES = '_template|_hide|_lib';
=item %OVERRIDABLE_PROPERTY
A hash describing which pieces of metadata can be overridden by article
loader plugins. The keys are the names of Subversion properties, and
the values are the names of columns in the C<wc_file> table.
=cut
our %OVERRIDABLE_PROPERTY = (
'dc:title' => 'title',
'dc:description' => 'description',
'daizu:short-title' => 'short_title',
);
=back
=head2 METHODS
=over
=item Daizu-E<gt>new($config_filename)
Return a Daizu object based on the information in the given configuration
file. If C<$config_filename> is not supplied, it will fall back on any
file specified by the C<DAIZU_CONFIG> environment variable, and then
by the default config file (see C<$DEFAULT_CONFIG_FILENAME> above).
The value returned will be called C<$cms> in the documentation.
For information about the format of the configuration file, see
the documentation on the website:
L<http://www.daizucms.org/doc/config-file/>
=cut
# This ensures that @INC is only fiddled with once for each Daizu installation.
# The keys are the URIs of content repositories. If an entry exists for a
# particular repository, then its _lib directory has already been added.
my %added_lib_path;
lib/Daizu.pm view on Meta::CPAN
=item $id
The ID number of the file in the C<wc_file> database table for which the
new property values apply.
=item $props
A reference to a hash of the new property values.
Only properties which have been
changed during a working copy update will have entries, so the file
may have other properties which haven't been changed.
Properties which have been deleted during the update will have an
entry in this hash with a value of C<undef>.
=back
An example of a property loader method is C<_std_property_loader> in
this module. It is always registered automatically.
=cut
sub add_property_loader
{
my ($self, $pattern, $object, $method) = @_;
push @{$self->{property_loaders}{$pattern}}, [ $object => $method ];
}
=item $cms-E<gt>add_article_loader($mime_type, $path, $object, $method)
Plugins can use this to register a method which will be called whenever
an article of type C<$mime_type> needs to be loaded. The MIME type can be
fully specified, or be something like C<image/*> (to match any image format),
or just be C<*> to match any type. These aren't generic glob or regex
patterns, so only those three levels of specificity are allowed. The
most specific plugin available will be tried first. Plugins of the same
specificity will be tried in the order they are registered. The plugin
methods can return false if they can't handle a particular file for
some reason, in which case Daizu will continue to look for another suitable
plugin.
The plugin registered will only be called on for files with paths which
are the same as, or are under the directory specified by, C<$path>.
Plugins should usually just pass the C<$path> value from their C<register>
method through to this method as-is.
C<$method> (a method name) will be called on C<$object>, and will be
passed C<$cms> and a
L<Daizu::File> object representing the input file. The method should
return a hash of values describing the article. Alternatively it can
return false to indicate that it can't handle the file.
The hash returned can contain the following values:
=over
=item content
Required. All the other values are optional.
This should be an XHTML DOM of the article's content, as it will be published.
It should be an L<XML::LibXML::Document> object, with a root element called
C<body> in the XHTML namespace. It can contain extension elements to be
processed by article filter plugins. It can contain XInclude elements,
which will be processed by the
L<expand_xinclude() function|Daizu::Util/expand_xinclude($db, $doc, $wc_id, $path)>.
Entity references should not be present.
=item title
The title to use for the article. If this is present and not undef then
it will override the value of the C<dc:title> property.
=item short_title
The 'short title' to use for the article. If this is present and not
undef then it will override the value of the C<daizu:short-title> property.
=item description
The description to use for the article. If this is present and not undef then
it will override the value of the C<dc:description> property.
=item pages_url
The URL to use for the first page of the article, and which will also be
used to generate URLs for subsequent pages (if any). This can be absolute,
or relative to the file's base URL.
=item extra_urls
A reference to an array of URL info hashes describing extra URLs generated
by the file in addition to the actual pages of the article. These are
stored in the C<wc_article_extra_url> table.
=item extra_templates
A reference to an array of filenames of extra templates to be included in
the article's 'extras' column. These are stored in the
C<wc_article_extra_template> table.
=back
See L<Daizu::Plugin::PodArticle> or L<Daizu::Plugin::PictureArticle> for
examples of registering and writing article loader plugins.
=cut
sub add_article_loader
{
my ($self, $mime_type, $path, $object, $method) = @_;
push @{$self->{article_loaders}{$mime_type}{$path}}, [ $object => $method ];
}
=item $cms-E<gt>add_html_dom_filter($path, $object, $method)
Plugins can use this to register a method which will be called whenever
an XHTML file is being published. C<$method> (a method name) will be
called on C<$object>, and will be passed C<$cms>, a L<Daizu::File> object
for the file being filtered, and an XML DOM object
of the source, as a L<XML::LibXML::Document> object. The plugin method
should return a reference to a hash containing a C<content> value which
is the filtered content, either a completely new copy of the DOM
or the same value it was passed (which it might have modified in place).
The returned hash can also contain an C<extra_urls> array, in the same
way as an article loader, if the filter adds additional URLs for the file.
The plugin registered will only be called on for files with paths which
are the same as, or are under the directory specified by, C<$path>.
Plugins should usually just pass the C<$path> value from their C<register>
method through to this method as-is.
See L<Daizu::Plugin::SyntaxHighlight> for an example of registering and
implementing a DOM filter method.
=cut
sub add_html_dom_filter
{
my ($self, $path, $object, $method) = @_;
my $filter_name = ref($object) . "->$method"; # just for a hash key
croak "HTML DOM filter already defined for '$filter_name' at '$path'"
if exists $self->{html_dom_filters}{$filter_name}{$path};
$self->{html_dom_filters}{$filter_name}{$path} = [ $object => $method ];
}
sub _std_property_loader
{
my ($self, undef, $id, $props) = @_;
my $db = $self->{db};
my %update;
$update{content_type} = validate_mime_type($props->{'svn:mime-type'})
if exists $props->{'svn:mime-type'};
if (exists $props->{'dcterms:issued'}) {
my $time = validate_date($props->{'dcterms:issued'});
warn "file $id has invalid 'dcterms:issued' datetime, ignoring\n"
if !defined $time && defined $props->{'dcterms:issued'};
# If the custom publication datetime is removed, or isn't valid, then
# reset it back to the default, which is the time of the file's
# first commit.
if (!defined $time) {
my $guid_id = db_select($db, wc_file => $id, 'guid_id');
($time, undef) = guid_first_last_times($db, $guid_id);
assert(defined $time) if DEBUG;
}
$update{issued_at} = db_datetime($time);
}
if (exists $props->{'dcterms:modified'}) {
my $time = validate_date($props->{'dcterms:modified'});
warn "file $id has invalid 'dcterms:modified' datetime, ignoring\n"
if !defined $time && defined $props->{'dcterms:modified'};
# If the custom update datetime is removed, or isn't valid, then
# reset it back to the default, which is the time of the file's
# most recent commit.
( run in 0.966 second using v1.01-cache-2.11-cpan-39bf76dae61 )