MT の検索結果ページの URL を別の URL にする方法

blue-abstract

MT の検索結果ページの URL を別の URL にする方法

Movable Type (MT) を、例えば www.example.com/x/ というフォルダにインストールしていた場合、公開パスを www.example.com にして、静的 HTML は ドメイン直下、MT 管理画面は x フォルダ以下、というような形で運用しているケースがあるかと思います。

しかし、MT の検索機能をコンテンツ側で利用しようとした場合、MT の管理画面フォルダにある mt-search.cgi (または mt-cdsearch.cgi)を参照する必要があり、かつ、出力される結果の URL は www.example.com/x/mt-cdsearch.cgi?search=…. といったような形になるため、 x フォルダの存在がユーザーに露呈してしまいます。

検索結果を x フォルダではない階層で表示できないかと思い模索していましたが、ひとまずウェブサーバー側の機能を使うことで www.example.com/x/mt-cdsearch.cgi を www.example.com/search/ のように、別の URL でアクセスできるようにすることで疑似的にフォルダの秘匿化を実現することができましたので、その方法を記していきたいと思います。

通常の検索機能の実装

MT では、記事/ページ用の検索モジュールとコンテンツデータ用の検索モジュールが異なっていますので、今回はまずコンテンツデータの検索をベースに話をすすめてみます。

まず通常の形で検索が正しく機能するようにしていきます。手始めに検索元のページを作ります。実験用に「インデックステンプレート」などで作るのが良いかと思います。

新規で「インデックステンプレート」を作成し、検索窓のついたごくごく簡単なページをひとつ作成します。

<!DOCTYPE html>
<html lang="ja" itemscope itemtype="http://schema.org/WebPage">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width,initial-scale=1">
  <title>検索テストページ</title>
</head>

<body>

  <h2>検索テストページ</h2>
  
  <form method="get" id="search" action="<$mt:CGIPath$><$mt:ContentDataSearchScript$>">
    <div>
    <input type="text" name="search" value="<MTIfStatic><mt:IfStraightSearch><$mt:SearchString$></mt:IfStraightSearch></MTIfStatic>" placeholder="検索...">
    <mt:If name="search_results">
      <input type="hidden" name="IncludeBlogs" value="<$mt:SearchIncludeBlogs$>">
      <input type="hidden" name="blog_id" value="<$mt:SiteID$>">
      <input type="hidden" name="SearchContentTypes" value="料理レシピ">
    <mt:Else>
      <input type="hidden" name="IncludeBlogs" value="<$mt:SiteID$>">
      <input type="hidden" name="blog_id" value="<$mt:SiteID$>">
      <input type="hidden" name="SearchContentTypes" value="料理レシピ">
    </mt:If>
      <input type="hidden" name="limit" value="<$mt:SearchMaxResults$>">
      <button type="submit" name="button">検索</button>
    </div>
  </form>
  
</body>
</html>

上記を仮に search-sample.html などという名前で保存します。上記の例では、「料理レシピ」というコンテンツデータに対して検索を行うような内容になっていますので、「料理レシピ」の箇所は適宜自身の環境に合わせて変更して下さい。

action=”<$mt:CGIPath$><$mt:ContentDataSearchScript$>” という箇所がシステムとの接続部分であり、前者の mt:CGIPath の値は mt-config.cgi 内で定義されています。デフォルトでは MT がインストールされているフォルダの値になります。

mt:ContentDataSearchScript は、デフォルトでは MT フォルダにインストールされている mt-cdsearch.cgi を指します。

いずれも環境変数を参照しますので、プログラム上は <$mt:CGIPath$><$mt:ContentDataSearchScript$> とそのまま記述すれば OK です。

次に検索で呼び出される側の準備をしていきます。「テンプレート > コンテンツの検索結果」を確認します。デフォルトで HTML が記述されていると思いますので、今回はそれをそのまま利用していきます。

もし検索結果ページが存在しなかった場合、こちらのページを参照して検索結果ページを用意してください。

記事とウェブページの検索結果ページを用意する | CMSプラットフォーム Movable Type ドキュメントサイト
コンテンツタイプの検索結果ページを用意する | CMSプラットフォーム Movable Type ドキュメントサイト

さてそれでは最初に作った検索元ページから何か検索をしてみましょう。

システムが正しく接続されているようであれば、下図のような検索結果ページが表示されるかと思います。

MT 検索結果ページ イメージ

これで検索の機能自体は実現できているわけですが、一方で上記ページが表示される URL は以下のようになっているかと思います。

www.example.com/x/mt-cdsearch.cgi?search=豚肉&IncludeBlogs=1&blog_id=1&SearchContentTypes=料理レシピ&limit=20&button=

これだと、冒頭で説明したように MT を利用している事が対外的にバレてしまいますし、かつ、システムが x フォルダにインストールされていることが明らかになってしまい、セキュリティ的にも良くありません。

MT インストールフォルダの秘匿化

上記の問題を解決するには2つの方法があります。

  1. x フォルダの上位、つまり公開パスに、検索で利用するモジュールをすべてコピーする
  2. ウェブサーバー側で URL をリライトする

前者は MT6 の際に成功している記事を他で見かけたのですが、MT7 になってから、結局どのファイルをコピーすれば良いかが特定できなかったため、挫折しました。が、技術的には、 mt-cdsearch.cgi を公開パスのルートに置いて、関連するファイルもすべて公開パスにコピーし、最後 mt-cdsearch.cgi のパスを mt-config.cgi 内で ContentDataSearchScript パス+ファイル名 で宣言してあげればうまくいくと思っています。

今回は後者の方法を使って目的を実現していこうと思います。

とはいっても、ウェブサーバーにもいろいろな種類があり、ウェブサーバーによっては今回のようなリライト機能が使えない場合もありますので、その点はお使いのウェブサーバーの技術仕様をご確認ください。今回は Apache での実装例をご案内していきます。

Apache で URL リライト機能を実現するには .htaccess というファイルを編集します。.htaccess 内に以下の2行を記述します。

RewriteCond 条件
RewriteRule URL書換&転送

これをうまく実装することで、 www.example.com/hoge/ という URL にアクセスしたと見せかけて、実はウェブサーバー側ではリライトを実行して www.example.com/x/neko/ の情報を返す、といったようなことができるようになるのです。

という訳で結論的には以下のような構文を .htaccess の RewriteEngine on の下に追加します。

RewriteCond %{QUERY_STRING} ^search=(.*)$
RewriteRule .* /x/mt-cdsearch.cgi?IncludeBlogs=3&blog_id=3&SearchContentTypes=料理レシピ&limit=50&search=%1 [L]

上記は、www.example.com/?search=AAA という URL リクエストがあった際に、サーバー側でリライトを実行し、www.example.com/x/mt-cdsearch.cgi?IncludeBlogs=3&blog_id=3&SearchContentTypes=料理レシピ&limit=50&search=AAA の結果を www.example.com/?search=AAA という URL のまま返す、という意味の設定になります。

MT への検索リクエストは /x/mt-cdsearch.cgi? のまま MT に渡され、MT がその結果を返したあと、ウェブサーバーが別の URL に置き換えてユーザーに返すので、これで /x 階層を秘匿化したいという目的が果たされることになります。