# BigPAPI.pl # BigPAPI plugin for Movable Type # by Kevin Shay # http://www.staggernation.com/mtplugins/BigPAPI/ # last modified 9/9/05 use strict; package MT::Plugin::BigPAPI; use vars qw( $VERSION ); $VERSION = '1.04'; require MT::Plugin; require MT; my $plugin = MT::Plugin->new({ name => "BigPAPI", description => 'Enable other plugins to enhance and modify the MT interface.', doc_link => 'http://www.staggernation.com/mtplugins/BigPAPI/', author_name => 'Kevin Shay', author_link => 'http://www.staggernation.com/', version => $VERSION }); MT->add_plugin($plugin); require MT::App; # store pointer to the original subroutine my $mt_build_page = \&MT::App::build_page; # install our new subroutines { local $SIG{__WARN__} = sub { }; *MT::App::build_page = \&_build_page; *MT::App::load_tmpl = \&_load_tmpl; } sub _build_page { my ($app, $file, $param) = @_; my $tmpl = $file; $tmpl =~ s/\.tmpl$//; run_callbacks("bigpapi::param::$tmpl", $app, $param); run_callbacks("bigpapi::param", $app, $param); return &{$mt_build_page}($app, $file, $param); } sub _load_tmpl { # mostly copied from MT::App::load_tmpl() my $app = shift; my($file, @p) = @_; my $cfg = $app->can('config') ? $app->config : $app->{cfg}; my $path = $cfg->TemplatePath; require HTML::Template; my $tmpl; my $err; my @paths; if ($app->{plugin_template_path}) { if (File::Spec->file_name_is_absolute($app->{plugin_template_path})) { push @paths, $app->{plugin_template_path} if -d $app->{plugin_template_path}; } else { my $dir = File::Spec->catdir($app->app_dir, $app->{plugin_template_path}); if (-d $dir) { push @paths, $dir; } else { $dir = File::Spec->catdir($app->mt_dir, $app->{plugin_template_path}); push @paths, $dir if -d $dir; } } } if (my $alt_path = $cfg->AltTemplatePath) { my $dir = File::Spec->catdir($path, $alt_path); if (-d $dir) { # AltTemplatePath is relative push @paths, File::Spec->catdir($dir, $app->{template_dir}) if $app->{template_dir}; push @paths, $dir; } elsif (-d $alt_path) { # AltTemplatePath is absolute push @paths, File::Spec->catdir($alt_path, $app->{template_dir}) if $app->{template_dir}; push @paths, $alt_path; } } push @paths, File::Spec->catdir($path, $app->{template_dir}) if $app->{template_dir}; push @paths, $path; my $cache_dir; if ($app->can('config')) { if (!$app->config('NoLocking')) { $cache_dir = File::Spec->catdir($path, 'cache'); undef $cache_dir if (!-d $cache_dir) || (!-w $cache_dir); } } my $type = {'SCALAR' => 'scalarref', 'ARRAY' => 'arrayref'}->{ref $file} || 'filename'; my $orig_type = $type; my $template_text; if ($type eq 'filename') { my $filename = find_file(\@paths, $file); eval { local($/, *FH) ; open(FH, $filename) || die $!; $template_text = \; }; $err = $@; return $app->error( $app->translate("Loading template '[_1]' failed: [_2]", $filename, $err)) if $@; $file =~ s/\.tmpl$//; run_callbacks("bigpapi::template::${file}::top", $app, $template_text); $type = 'scalarref'; } else { $template_text = $file; } $tmpl = HTML::Template->new( type => $type, source => $template_text, path => \@paths, search_path_on_include => 1, die_on_bad_params => 0, global_vars => 1, loop_context_vars => 1, $cache_dir ? (file_cache_dir => $cache_dir, file_cache => 1, file_cache_dir_mode => 0777) : (), filepath => '', # to avoid an uninitialized value warning filter => sub { if ($orig_type eq 'filename') { run_callbacks("bigpapi::template::$file", $app, $_[0]); } run_callbacks("bigpapi::template", $app, $_[0]); $_[0]; }, @p); ## We do this in load_tmpl because show_error and login don't call ## build_page; so we need to set these variables here. if (my $author = $app->{author}) { $tmpl->param(author_id => $author->id); $tmpl->param(author_name => $author->name); } my $spath; if ($app->can('static_path')) { $spath = $app->static_path; } else { $spath = $app->{cfg}->StaticWebPath || $app->mt_path; $spath .= '/' unless $spath =~ m!/$!; } $tmpl->param(static_uri => $spath); my $app_uri = $app->can('uri') ? $app->uri : $app->app_uri; $tmpl->param(script_url => $app_uri); $tmpl->param(mt_url => $app->mt_uri); if ($app->can('path')) { $tmpl->param(script_path => $app->path); } else { $tmpl->param(script_path => $app->app_path); } $tmpl->param(script_full_url => $app->base . $app_uri); $tmpl->param(mt_version => MT->can('version_id') ? MT->version_id : MT->VERSION); $tmpl->param(language_tag => $app->current_language); if ($app->can('charset')) { $tmpl->param(language_encoding => $app->charset); } else { my $enc = $app->{cfg}->PublishCharset || $app->language_handle->encoding; $tmpl->param(language_encoding => $enc); $app->{charset} = $enc; } $tmpl; } sub find_file { my ($paths, $file) = @_; return File::Spec->canonpath($file) if -e $file; foreach my $p (@$paths) { my $filepath = File::Spec->canonpath(File::Spec->catfile($p, $file)); return File::Spec->canonpath($filepath) if -e $filepath; } # we didn't find it, so just return the filename return $file; } sub run_callbacks { # run a callback and all its version-specific variations my ($name, $app, $param) = @_; my $ver = MT->version_number(); my @run = ($name, "${name}::$ver"); my ($maj, $min) = split(/\./, $ver); while ($min =~ m/\d$/) { push (@run, "${name}::$maj.${min}x"); $min =~ s/\d$//; } push (@run, "${name}::$maj.x"); my $str = ''; for my $run (@run) { MT->run_callbacks($run, $app, $param); } } 1;