# PreviousNextInCategory # http://weblog.philringnalda.com/2004/02/05/previous-and-next-in-category # Author: phil ringnalda # # Ported to Movable Type 4.x by Yujiro ARAKI. # Release 0.01 (Mar 21, 2008) for Movable Type 4.1. # Release 0.02 (Mar 22, 2008) correct comment. # Release 0.10 (Nov 17, 2008) for Movable Type 4.2. package MT::Plugin::PreviousNextInCategory; use strict; use warnings; use base qw( MT::Plugin ); use MT; use MT::Template::Context; our $VERSION = '0.10'; my $plugin = __PACKAGE__->new({ id => 'PreviousNextInCategory', name => 'PreviousNextInCategory', description => '', version => $VERSION, doc_link => 'http://www.koikikukan.com/archives/2008/11/18-005555.php', author_name => 'Yujiro Araki', author_link => 'http://www.koikikukan.com/', l10n_class => 'PreviousNextInCategory::L10N', }); MT->add_plugin($plugin); sub init_registry { my $plugin = shift; $plugin->registry({ tags => { block => { EntryPreviousInCategory => \&_hdlr_entry_previous_in_category, EntryNextInCategory => \&_hdlr_entry_next_in_category, } }, callbacks => { 'MT::App::CMS::CMSPostSave.entry' => sub { $plugin->runner('_rebuild', @_) }, }, }); } sub _rebuild { my $plugin = shift; my ($eh, $app, $entry) = @_; my $cats = $entry->categories; for my $cat (@$cats) { my $prev = $entry->previous(1); while ($prev && !$prev->is_in_category($cat)) { $prev = $prev->previous(1); } $app->rebuild_entry(Entry => $prev->id) if $prev; my $next = $entry->next(1); while ($next && !$next->is_in_category($cat)) { $next = $next->next(1); } $app->rebuild_entry(Entry => $next->id) if $next; } return 1; } sub runner { my $plugin = shift; my $method = shift; return $_->($plugin, @_) if $_ = \&{"$method"}; } sub _hdlr_entry_previous_in_category { my($ctx, $args, $cond) = @_; my $e = $ctx->stash('entry') or return $ctx->_no_entry_error('MTEntryPrevious'); my $cat = $e->category or return ''; if($ctx->stash('category') ne '') { $cat = $ctx->stash('category'); } my $terms; $terms->{category_id} = $cat->id; my $prev = $e->previous(1, $terms); my $res = ''; while ($prev && !$prev->is_in_category($cat)){ $terms->{category_id} = $cat->id; $prev = $prev->previous(1, $terms); } if ($prev) { my $builder = $ctx->stash('builder'); local $ctx->{__stash}->{entry} = $prev; local $ctx->{current_timestamp} = $prev->created_on; my %cond = %$cond; $cond{EntryIfAllowComments} = $prev->allow_comments; $cond{EntryIfCommentsOpen} = $prev->allow_comments eq '1'; $cond{EntryIfAllowPings} = $prev->allow_pings; $cond{EntryIfExtended} = $prev->text_more ? 1 : 0; my $out = $builder->build($ctx, $ctx->stash('tokens'), \%cond); return $ctx->error( $builder->errstr ) unless defined $out; $res .= $out; } $res; } sub _hdlr_entry_next_in_category { my($ctx, $args, $cond) = @_; my $e = $ctx->stash('entry') or return $ctx->_no_entry_error('MTEntryNext'); my $cat = $e->category or return ''; if($ctx->stash('category') ne '') { $cat = $ctx->stash('category'); } my $terms; $terms->{category_id} = $cat->id; my $next = $e->next(1, $terms); my $res = ''; while ($next && !$next->is_in_category($cat)){ $terms->{category_id} = $cat->id; $next = $next->next(1, $terms); } if ($next) { my $builder = $ctx->stash('builder'); local $ctx->{__stash}->{entry} = $next; local $ctx->{current_timestamp} = $next->created_on; my %cond = %$cond; $cond{EntryIfAllowComments} = $next->allow_comments; $cond{EntryIfCommentsOpen} = $next->allow_comments eq '1'; $cond{EntryIfAllowPings} = $next->allow_pings; $cond{EntryIfExtended} = $next->text_more ? 1 : 0; my $out = $builder->build($ctx, $ctx->stash('tokens'), \%cond); return $ctx->error( $builder->errstr ) unless defined $out; $res .= $out; } $res; } 1;