用MT-XSearch替换MT默认的Tag搜索

毋庸置疑,Movable Type确实是Blog系统中的佼佼者,它强大的功能,简洁清爽的界面,以及随心所欲的可定制性深深的吸引着我。但即使如此,Movable Type还是有不尽如人意的地方,搜索功能消耗大量资源绝对是其中一条。在最新版的Movable Type 3.32中,这一点愈加突出。3.32版的Movable Type,最显著的就是内置了Tag和各种类型的RSS feed,如搜索关键字feed,特定Tag的feed……。与生成静态页或动态PHP出版的日志归档不同,Tag、搜索,以及为它们提供的RSS feed全都是动态内容,全靠一个mt-search.cgi实现。在Blog访问量增加,或订阅某个关键字以及Tag的人数增加的时候,大量的mt-search.cgi进程很有可能把服务器拖垮,前几天Postshow遇到故障无法访问,即由此引起。最终,我使用MT-XSearch插件替换了Movable Type默认的Tag搜索,并为其加上缓存功能,问题才告解决。现将整个解决过程记录如下,与诸君分享。

必备插件(Required Plugins) 安装步骤(How to setup)
  1. 安装TagSupplementals
    其官方网站下载此插件,解压缩后,将TagSupplementals.p文件拷贝/上传到Movable Type的plugins目录。 安装MT-XSearch
    这里下载mt-plus插件,解压缩后,将下述文件拷贝/上传到你的Movable Type程序安装目录。
    • mt-xsearch.cgi
    • plugins/mt-xsearch.pl
    • extlib/MT/XSearch.pm
    若主机空间为*nix系统,请设置mt-xsearch.cgi的属性为755。

  2. 按照下述方法修改mt-xsearch.cgi和plugins/mt-xsearch.pl文件,以让MT-XSearch支持多国语言,并修复其Bug。
    [--- mt-xsearch.cgi.bak	Fri Aug 27 12:06:24 2004
    +++ mt-xsearch.cgi Sat Jun 11 02:58:33 2005
    @@ -41,7 +41,8 @@
    $ctx->stash('CGI',$q);
    my $out = $tmpl->build($ctx)
    or die "Building search template failed: ".$tmpl->errstr;
    - print $q->header.$out;
    + my $charset = $mt->{cfg}->PublishCharset;
    + print $q->header(-charset=>$charset).$out;
    };
    if ($@) {
    print "Content-Type: text/html\n\n";


    --- plugins/mt-xsearch.pl.bak	Sat May 14 06:01:19 2005
    +++ plugins/mt-xsearch.pl Sat Jun 11 00:31:39 2005
    @@ -63,7 +63,7 @@
    my $pages = $limit ? ($count-($count % $limit)) / $limit : 1;
    $pages += ($limit && $count % $limit) ? 1 : 0;
    my $offset = $xsearch->args->{offset} || 0;
    - my $current = $offset / $limit + 1;
    + my $current = $limit ? ($offset / $limit + 1) : 1;
    $ctx->stash('MT::XSearch::current_page',$current);
    $ctx->stash('MT::XSearch::pages',$pages);
    my $builder =
    $ctx->stash('builder');]


  3. 如果主机空间安装有CGI::Cache模块,则可以按照下面的方法修改mt-xsearch.cgi,用缓存来让MT-XSearch提供更好的负载。
    --- mt-xsearch.cgi.bak	Fri Aug 27 12:06:24 2004
    +++ mt-xsearch.cgi Sat Jun 11 03:44:32 2005
    @@ -17,6 +17,7 @@
    }

    use CGI;
    +use CGI::Cache;
    use MT;
    use MT::ConfigMgr;
    use MT::Template;
    @@ -27,10 +28,13 @@
    my $mt = MT->new( Config => $MT_DIR . 'mt.cfg', Directory => $MT_DIR )
    or die MT->errstr;
    my $q = new CGI;
    + CGI::Cache::setup({ cache_options => { cache_root => './cache', default_expires_in => 3600 } });
    my $blog_id = $q->param('blog_id') or
    die "Missing parameter blog_id";
    my $key = $q->param('search_key') or
    die "Missing parameter key";
    + CGI::Cache::set_key($q->Vars);
    + CGI::Cache::start() or exit;
    my $search = MT::XSearch->execute($q);
    my $tmpl = MT::Template->load( {
    name=>'XSearch '.$key,
    @@ -41,7 +45,14 @@
    $ctx->stash('CGI',$q);
    my $out = $tmpl->build($ctx)
    or die "Building search template failed: ".$tmpl->errstr;
    - print $q->header.$out;
    + my $charset = $mt->{cfg}->PublishCharset;
    + my @m = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec);
    + my @w = qw(Sun Mon Tue Wed Thu Fri Sat);
    + my ($sec, $min, $hour, $mday, $mon, $year, $wday) = gmtime(time);
    + my $now = sprintf("%3s, %02d %3s %04d %02d:%02d:%02d GMT",
    + $w[$wday], $mday, $m[$mon], $year+1900, $hour, $min, $sec);
    + print $q->header(-charset=>$charset,-Last_Modified=>$now).$out;
    + CGI::Cache::stop();
    };
    if ($@) {
    print "Content-Type: text/html\n\n";

    你会看到,在上面这段程序中,我们定义了缓存使用的目录--“./cache”,以及缓存的持续时间--3600″(1个小时)。你也可以修改成其它需要的值,但一定要根据程序中的情况建立一个放置缓存的目录,并为其赋予写入权限(一般设置权限为777即可)。这里,我们要在Movable Type的安装目录下建立一个名为cache的文件夹,设置其权限为777。

  4. 增加一个用于Tag搜索的模块XSearch TagSupplementals
    在你的Blog管理界面中点击“模板”,选择“模块”标签,按下“新增模板模块”链接,在出现的窗口中填入模块名字和模块的模板信息。其中模块名字为“XSearch TagSupplementals”,模块的模板则根据你自身的情况来制作,下面给出一个样历:
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=<$MTPublishCharset$>" />
    <title>Tag: <$MTSearchString decode_url="1"$> on <$MTBlogName$></title>
    </head>
    <body>

    <h2><a href="<$MTBlogURL$>tags/">Tag</a>: <em><$MTSearchString decode_url="1"$></em></h2>

    <MTSearchResults>
    <MTSearchHeader>
    Results found: <$MTSearchResultCount$>
    <ol>
    </MTSearchHeader>
    <li><a href="<$MTEntryLink$>"><$MTEntryTitle$></a></li>
    <MTSearchFooter>
    </ol>
    </MTSearchFooter>
    </MTSearchResults>
    <MTNoSearch><p>No search performed.</p></MTNoSearch>
    <MTNoSearchResults><p>Nothing found.</p></MTNoSearchResults>

    <h3>Related Tag</h3>
    <MTXSearchTags>
    <ul>
    <MTRelatedTags>
    <li>
    <a title="Tag: <$MTTagName$>" href="<$MTBlogURL$>tag/<$MTTagName encode_url="1"$>"><$MTTagName$>(<$MTTagCount$>)</a>
    </li>
    </MTRelatedTags>
    </ul>
    </MTXSearchTags>

    </body>
    </html>

    上面只是一些最基本的元素,你可以根据自己的具体情况把样式表和DIV层套用上来。
使用(Usage)
  1. 最简单的,将所有的<$MTTagSearchLink$>换成<$MTTagXSearchLink$>。
  2. 如果此前为Movable Type的内置Tag做过URL_rewrite,则请编辑.htaccess 文件,将其中有关Tag的部分修改为:
    RewriteEngine on RewriteRule tag/(.+) /mt/mt-xsearch.cgi?blog_id=1&search_key=TagSupplementals&search=$1
    其中/mt/为Movable Type的程序路径,blog_id为你的Blog在整套Movable Type中的ID号。
相关下载(Related Download)