use strict;
package MT::Plugin::PageBute;
use vars qw( $MYNAME $VERSION );
$MYNAME = 'PageBute';
$VERSION = '3.2.2';
use MT::Plugin;
use POSIX qw( ceil );
my $plugin = MT::Plugin->new({
name => $MYNAME,
description => <It is possible to use it only once a page.
HTMLHEREDOC
version => $VERSION,
});
MT->add_plugin( $plugin );
my %garbage = (
NextLink => '',
BeforeLink => '',
Separator => '',
PageLists => '',
Contents => '',
IfPageNext => '',
IfPageNext_end => '',
IfPageBefore => '',
IfPageBefore_end => '',
);
MT::Template::Context->add_container_tag(PageContents => \&_page_contents);
MT::Template::Context->add_container_tag(IfPageNext => \&_if_page_next);
MT::Template::Context->add_container_tag(IfPageBefore => \&_if_page_before);
MT::Template::Context->add_tag(PageNext => \&_page_next);
MT::Template::Context->add_tag(PageBefore => \&_page_before);
MT::Template::Context->add_tag(PageSeparator => \&_separator);
MT::Template::Context->add_tag(PageLists => \&_page_lists);
MT->add_callback('BuildPage', 9, $plugin, \&_page_bute);
MT->add_callback('BuildFile', 9, $plugin, \&_repage_bute);
sub _if_page_next {
my ($ctx, $args, $cond) = @_;
my $tokens = $ctx->stash('tokens');
my $builder = $ctx->stash('builder');
my $result = $builder->build( $ctx, $tokens, $cond )
or return $ctx->error( $builder->errstr );
$garbage{IfPageNext}. $result. $garbage{IfPageNext_end};
}
sub _if_page_before {
my ($ctx, $args, $cond) = @_;
my $tokens = $ctx->stash('tokens');
my $builder = $ctx->stash('builder');
my $result = $builder->build( $ctx, $tokens, $cond )
or return $ctx->error( $builder->errstr );
$garbage{IfPageBefore}. $result. $garbage{IfPageBefore_end};
}
sub _page_next {
my ($ctx,$args,$cond) = @_;
my $delim = $args->{delim} || '>>';
my $pb = $ctx->stash('PageBute');
if(!$pb) {
my %pagebute = ();
$pb = \%pagebute;
$ctx->stash('PageBute',$pb);
}
$pb->{next_delim} = $delim;
$garbage{NextLink};
}
sub _page_before {
my ($ctx,$args,$cond) = @_;
my $delim = $args->{delim} || '<<';
my $pb = $ctx->stash('PageBute');
if(!$pb) {
my %pagebute = ();
$pb = \%pagebute;
$ctx->stash('PageBute',$pb);
}
$pb->{before_delim} = $delim;
$garbage{BeforeLink};
}
sub _separator {
$garbage{Separator};
}
sub _page_lists {
my ($ctx,$args,$cond) = @_;
my $pb = $ctx->stash('PageBute');
if(!$pb) {
my %pagebute = ();
$pb = \%pagebute;
$ctx->stash('PageBute',$pb);
}
$pb->{page_delim} = defined $args->{delim} ? $args->{delim} : " \n";
$pb->{link_start} = $args->{link_start} || q{};
$pb->{link_close} = $args->{link_close} || q{};
$pb->{show_always} = defined $args->{show_always} ? $args->{show_always} : 1;
$garbage{PageLists};
}
sub _page_contents {
my ($ctx,$args,$cond) = @_;
my $tokens = $ctx->stash('tokens');
my $builder = $ctx->stash('builder');
my $pb = $ctx->stash('PageBute');
if(!$pb) {
my %pagebute = ();
$pb = \%pagebute;
$ctx->stash('PageBute',$pb);
}
return $ctx->error( 'This plugin can be applied only once in a page.') if ($pb->{loaded});
$pb->{loaded} = 1;
$pb->{contents} = $builder->build($ctx,$tokens,$cond);
$pb->{count} = $args->{count} || 10;
$pb->{navi_count} = $args->{navi_count} || '11';
$pb->{nav_separator} = $args->{nav_separator} || '_';
$garbage{Contents};
}
sub _page_bute {
my ($cb, %opt) = @_;
my $ctx = $opt{Context};
my $pb = $ctx->stash('PageBute');
return 1 unless($pb);
#Get file information
my ($filename, $file_ext);
my $file = $opt{File};
my $blog = $ctx->stash('blog');
my $site_url = $blog->{column_values}->{site_url};
$site_url = $site_url . '/' unless ($site_url =~ /[\/\\]$/);
my $site_path = $blog->{column_values}->{site_path};
$site_path = $site_path . '/' unless ($site_path =~ /[\/\\]$/);
my $file_path = substr($file, length($site_path));
if ( $file_path =~ /^[\/\\]?(.*)\.(.*?)$/ ) {
$filename = $1;
$file_ext = $2;
} else {
$filename = $file_path;
$file_ext = '';
}
my $contents = $opt{Content};
my $split_count = $pb->{count};
my $delim = $pb->{page_delim};
my @entries = split(/$garbage{Separator}/, $pb->{contents});
my $page_limit = ceil( $#entries / $split_count );
my $page_count = 1;
my $output_page_contents = '';
my $fmgr = $blog->file_mgr;
for (my $i=0; $i < $#entries; $i++) {
$output_page_contents .= $entries[$i];
if( ($i + 1) % $split_count == 0 || $i == $#entries - 1) {
$file = $page_count == 1 ? $file : "${site_path}${filename}_${page_count}.${file_ext}";
my $output = $$contents;
$output =~ s/$garbage{Contents}/$output_page_contents/g;
my $lists = &_create_lists($page_count, $page_limit , $pb->{navi_count} );
my $before = $lists->{before}
? &_create_link($page_count - 1, $site_url . $filename, $file_ext, $pb->{before_delim}, 'link_before')
: '';
my $next = $lists->{next}
? &_create_link($page_count + 1, $site_url . $filename, $file_ext, $pb->{next_delim}, 'link_next')
: '';
my $page_lists = '';
for (my $i = $lists->{min_page}; $i <= $lists->{max_page}; $i++) {
$page_lists .= $i == $lists->{min_page} ? '' : $delim;
$page_lists .= $pb->{link_start};
$page_lists .= $i == $page_count
? "$page_count"
: &_create_link($i, $site_url . $filename, $file_ext, $i, 'link_page');
$page_lists .= $pb->{link_close};
}
#replace before link
if ($before) {
$before = $pb->{link_start}. $before. $pb->{link_close};
$output =~ s/\Q$garbage{IfPageBefore}\E//g;
$output =~ s/\Q$garbage{IfPageBefore_end}\E//g;
$output =~ s/\Q$garbage{BeforeLink}\E/$before/g;
} else {
$output =~ s/\Q$garbage{IfPageBefore}\E[\s\S]*?\Q$garbage{IfPageBefore_end}\E//g;
}
#replace next link
if ($next) {
$next = $pb->{link_start}. $next. $pb->{link_close};
$output =~ s/\Q$garbage{IfPageNext}\E//g;
$output =~ s/\Q$garbage{IfPageNext_end}\E//g;
$output =~ s/\Q$garbage{NextLink}\E/$next/g;
} else {
$output =~ s/\Q$garbage{IfPageNext}\E[\s\S]*?\Q$garbage{IfPageNext_end}\E//g;
}
#replace page lists
if (!$next && !$before && $pb->{show_always} == 0) {
$output =~ s/\Q$garbage{PageLists}\E//g;
}
else {
$output =~ s/\Q$garbage{PageLists}\E/$page_lists/g;
}
$fmgr->put_data($output,"${file}.new");
$fmgr->rename("${file}.new",$file);
if($page_count == 1) {
$ctx->stash('FirstContents', $output);
$ctx->stash('FirstFileName', $file);
}
$output_page_contents = '';
$page_count++;
}
}
$ctx->stash('PageBute', 0);
1;
}
sub _repage_bute {
my ($cb, %opt) = @_;
my $ctx = $opt{Context};
my $file = $ctx->stash('FirstFileName');
my $contents = $ctx->stash('FirstContents');
return 1 unless($file);
my $blog = $ctx->stash('blog');
my $fmgr = $blog->file_mgr;
$fmgr->put_data($contents,"${file}.new");
$fmgr->rename("${file}.new",$file);
$ctx->stash('FirstFileName',0);
}
sub _create_lists {
my ($page, $max , $navi_count ) = @_;
my ($min_page , $max_page , $navi_side_count) = (0,0,0);
$navi_count = $navi_count || '11';
if ( $navi_count =~ /^\d+$/ ){
if($navi_count == 1 || $max == 1){
$min_page = $page;
$max_page = $page;
}else{
$navi_count = $max if $navi_count > $max;
$navi_side_count = $navi_count > 1 ? int ($navi_count/2) : 0;
$min_page = $page - ($navi_side_count);
$min_page = 1 if $min_page < 1;
$max_page = $min_page + ($navi_count - 1);
$max_page = $max if $max_page > $max;
$min_page = $max_page - ($navi_count - 1) if ($max_page - $min_page) < ($navi_count - 1);
}
}else{
$max_page = $max;
$min_page = 1;
}
my %pages = (
before => $page - 1 > 0 ? $page - 1 : 0,
next => $page + 1 <= $max ? $page + 1 : 0,
max_page => $max_page,
min_page => $min_page
);
return \%pages;
}
sub _create_link {
my ($page, $file, $extension, $name, $class_name) = @_;
my $url = $file . ( $page == 1 ? '' : "_${page}" ) . ".${extension}";
$url =~ s|\\|\/|g; # for windows
return "$name";
}
1;