Daizu
view release on metacpan or search on metacpan
lib/Daizu/File.pm view on Meta::CPAN
=cut
sub urls_in_db
{
my ($self, $method, $argument) = @_;
my %criteria = (
wc_id => $self->{wc_id},
guid_id => $self->{guid_id},
status => 'A',
);
$criteria{method} = $method
if defined $method;
$criteria{argument} = $argument
if defined $argument;
return db_select_col($self->{db}, url => \%criteria, 'url');
}
=item $file-E<gt>article_urls
Return information about the URLs which the file should have, if it
is an article. Fails if it isn't.
The URLs are returned in the same format as the
L<Daizu::Gen method custom_urls_info|Daizu::Gen/$gen-E<gt>custom_urls_info($file)>, and
should be used within implementations of that method to ensure that
articles get the proper URLs even if an article loader plugin or
DOM filtering plugin has changed the usual forms.
There are two sets of URLs returned, as a single list:
=over
=item *
URLs for the pages of the actual article, as normal web pages published
through the templating system. There will always be at least one of
these, which will be the first URL returned. It will have a method of
'article', an empty argument string, and a content type of 'text/html'.
The generator class is likely to be L<Daizu::Gen>, although it doesn't
have to be. The URL for this first article page will be the one supplied
by the article loader plugin as C<pages_url>, and stored in the database
in the C<article_pages_url> column. If none is supplied it defaults to the
empty string. If the article has multiple pages, this URL
info will be followed by others, one for each subsequent page, which
will be identical except for the actual URL and the argument, which
will contain the page number (starting from '2' for the second page).
The first 'article' page URL is the one which should be used when linking
to an article, unless you have some special reason to link to a particular
page or an alternative URL for the same file. For example, this is
the URL which will be included in blog feeds and navigation menus.
To get at it conveniently, see the L<permalink()|/$file-E<gt>permalink> method.
=item *
There may be additional URLs for supplementary resources generated by
plugins, although by default a simple article written in XHTML won't
have any 'extra' URLs. These URLs are the ones supplied by the article
loader plugin as C<extra_urls>, and stored in the database in the
C<wc_article_extra_url> table. One example of an 'extra'
URL is a POD file (Perl documentation, like this document itself)
published with the L<Daizu::Plugin::PodArticle> plugin. If the filename
of the POD file ends in '.pm', then this plugin will add an extra
URL for the original source code, since that might be of interest
to programmers reading API documentation.
=back
=cut
# Used by article_urls() below. Uses some crufty heuristics to decide
# how pages (other than the first page) of articles should be referenced.
# $url should be the URL of the article's first page, which is likely to
# be the empty string or 'filename.html', although it could be an absolute
# URL. It's up to the generator class.
sub _pagify_url
{
my ($url, $page) = @_;
assert($page > 0) if DEBUG;
assert($url ne '') if DEBUG;
return $url if $page == 1;
return "$url/page$page.html" if $url =~ m!/$!;
$url =~ s!\.([^/.]+)$!-page$page.$1! or $url .= "-page$page.html";
return $url;
}
sub article_urls
{
my ($self) = @_;
croak "file is not an article"
unless $self->{article};
$self->_find_content_marks; # need to know how many pages
my @page_urls = map {
{
url => _pagify_url($self->{article_pages_url}, $_),
generator => (ref $self->generator),
method => 'article',
argument => ($_ == 1 ? '' : $_),
type => 'text/html',
}
} (1 .. scalar @{$self->{page_start}});
return @page_urls, $self->article_extra_urls;
}
=item $file-E<gt>parent
Return a new Daizu::File object representing this file's parent directory.
Returns nothing if this file is at the 'top level' of its branch and so has
no parent.
=cut
sub parent
{
lib/Daizu/File.pm view on Meta::CPAN
by looking at the C<daizu:generator> property for the file, and if
necessary its ancestors. The class is loaded automatically.
It also knows to use L<Daizu::Gen> if no generator specification is found.
Returns the new object, which should support the API of class L<Daizu::Gen>.
=cut
sub generator
{
my ($self) = @_;
return $self->{generator_obj} if exists $self->{generator_obj};
my $cms = $self->{cms};
my $root_file = $self;
$root_file = Daizu::File->new($cms, $self->{root_file_id})
if defined $self->{root_file_id};
my $generator = instantiate_generator($cms, $self->{generator},
$root_file);
$self->{generator_obj} = $generator;
return $generator;
}
=item $file-E<gt>update_loaded_article_in_db
Updates the cached article content for C<$file> in the database.
This includes the finished XML version of the content,
the article pages URL, the extra URLs, and the extra templates.
Does nothing if the file isn't an article.
Fails if it is but there are no plugins able to load it.
This normally happens automatically when a file's content is updated,
and can also be triggered manually from the C<daizu> program with
the
This is where article loader plugins set with the L<Daizu> method
L<add_article_loader()|Daizu/$cms-E<gt>add_article_loader($mime_type, $path, $object, $method)>
are invoked.
Doesn't return anything.
=cut
sub update_loaded_article_in_db
{
my ($self) = @_;
return unless $self->{article};
return transactionally($self->{db}, \&_update_loaded_article_in_db_txn,
$self);
}
sub _update_loaded_article_in_db_txn
{
my ($self) = @_;
my $cms = $self->{cms};
my $mime_type = $self->{content_type};
if (!defined $mime_type) {
# Articles must have a mime type, but allow a default based on file
# extension for the built-in XHTML format.
croak "article in file '$self->{path}' has no mime type specified"
unless $self->{name} =~ /\.html?$/i;
$mime_type = 'text/html';
}
$mime_type =~ m!^(.+?)/!
or croak "bad article mime type '$mime_type' in file '$self->{path}'";
my $mime_type_family = "$1/*";
# Search through applicable MIME type patterns.
my $file_path = $self->{path};
for my $match ($mime_type, $mime_type_family, '*') {
next unless exists $cms->{article_loaders}{$match};
my $plugins = $cms->{article_loaders}{$match};
# Search through applicable paths, sorting in reverse order of length
# so that the most specific configuration gets tested first.
for my $match_path (sort { length $b <=> length $a } keys %$plugins) {
next unless
$match_path eq '' || $match_path eq $file_path ||
substr($file_path, 0, length $match_path + 1) eq "$match_path/";
# Search through the plugins we've found to find one which
# accepts the file.
for my $handler (@{$plugins->{$match_path}}) {
my ($object, $method) = @$handler;
my $article = $object->$method($cms, $self);
next unless $article;
croak "bad return value '$article' from article loader" .
" '$object->$method"
unless ref($article) eq 'HASH';
$self->_expand_article_xinclude($article);
$self->_filter_loaded_article($article);
$self->_save_article_content($article);
return;
}
}
}
die "can't load article $self->{id}," .
" don't know how to handle content type '$mime_type'";
}
sub _expand_article_xinclude
{
my ($self, $article) = @_;
my @included_files = expand_xinclude($self->{db}, $article->{content},
$self->{wc_id}, $self->{path});
$article->{included_files} = \@included_files
if @included_files;
}
sub _filter_loaded_article
{
my ($self, $article) = @_;
my $cms = $self->{cms};
# Filter through plugins.
( run in 1.515 second using v1.01-cache-2.11-cpan-39bf76dae61 )