MT-XSearch的FastCGI化

去年九月份,在Movable Type 3.32推出之时,曾经用MT-XSearch替换了MT默认的Tag搜索,除了有效降低服务器负载外,还能够和TagSupplementals配合,增强Movable Type的Tag功能。

不过随着Movable Type 3.34开始全面支持FastCGI,MT-XSearch却仅能运行在标准CGI下面,让人觉得非常不爽。为此,Hirotaka Ogawa写过一篇MT-XSearchをFastCGI化する的网志,我也根据这篇网志实现了Movable Type 3.34下MT-XSearch的FastCGI化。

MT-XSearch FastCGI化的方法如下:

  1. 按照这里的方法安装MT-Xsearch插件,记得把CGI::Cache模块安装上。如果主机空间没有CGI::Cache,但用的是DreamHost等支持SSH和自主编译的Host,则可以《自己动手,在DreamHost上安装所需的Perl模块》中所述的方法自己安装CGI::Cache模块支持。
  2. 将下述内容保存成/MTDIR/extlib/MT/App/XSearch.pm文件,放在相应目录下。
    package MT::App::XSearch;
    
    use strict;
    use MT::App;
    @MT::App::XSearch::ISA = qw( MT::App );
    use MT::ConfigMgr;
    use MT::XSearch;
    
    sub init {
        my $app = shift;
        $app->SUPER::init(@_) or return;
        $app->add_methods(main => \&view);
        $app->{charset} = $app->{cfg}->PublishCharset;
        $app->{default_mode} = 'main';
        $app;
    }
    
    sub view {
        my $app = shift;
        my $q = $app->{query};
        require MT::Template;
        require MT::Template::Context;
        my $blog_id = $q->param('blog_id') or
            return $app->error("Missing parameter blog_id");
        my $key = $q->param('search_key') or
            return $app->error("Missing parameter key");
        my $search = MT::XSearch->execute($q);
        my $tmpl = MT::Template->load({ blog_id => $blog_id, 
                                        name => 'XSearch ' . $key,
                                        type => 'custom' });
        my $ctx = MT::Template::Context->new;
        $ctx->stash('MT::XSearch', $search);
        $ctx->stash('CGI', $q);
        my $html = $tmpl->build($ctx)
            or return $app->error("Building search template failed: " . $tmpl->errstr);
        $html;
    }
    
    1;
  3. 将以下内容保存为mt-xsearch.fcgi文件,放在/MTDIR目录。
    #!/usr/bin/perl -w
    use strict;
    use lib 'lib';
    use MT::Bootstrap;
    use CGI::Fast;
    use CGI::Cache;
    use MT::App::XSearch;
    
    eval {
        CGI::Cache::setup({
            cache_options => { cache_root => './cache', default_expires_in => 600 }
        });
        while (my $q = new CGI::Fast) {
            my $cgi_cache = $q->param('cgi_cache') || 0;
            if ($cgi_cache) {
                CGI::Cache::set_key($q->Vars);
                CGI::Cache::start() or next;
            }
            my $app = MT::App::XSearch->new(CGIObject => $q)
                or die MT::App::XSearch->errstr;
            local $SIG{__WARN__} = sub { $app->trace($_[0]) };
            MT->set_instance($app);
            $app->init_request(CGIObject => $q) unless $app->{init_request};
            $app->run;
            CGI::Cache::stop($app->errstr ? 0 : 1) if $cgi_cache;
        }
    };
    if ($@) {
        print "Content-Type: text/html\n\n";
        print "Got an error: $@";
    }
  4. 好了,将原来RewriteRule中的mt-xsearch.cgi换成mt-xsearch.fcgi,并且最后后面加上&cgi_cache=1,启用缓存即可
    RewriteRule ^tag/(.*)$ /mt/mt-xsearch.cgi?blog_id=1&search_key=TagSupplementals&search=$1&cgi_cache=1 [L]

其中,mt-xsearch.fcgi文件的后缀,可以根据你自己的情况进行修改。