本記事のソースコードの利用によって生じた損害について、当方は一切の責任を負いません。ご自身の判断と責任のもとで参照・ご利用ください。
結論として、これまで利用していたGoogleカスタム検索を廃止し、Movable Type標準のサイト内検索機能へ完全に移行しました。これにより、サイト内の全コンテンツが検索対象となり、ユーザビリティの課題を一つ解決できました。
Googleサイト内検索で過去記事がヒットしない根本原因
このサイトでは長らく、サイト内検索にGoogleカスタム検索を利用していました。導入した当時は何らかのメリットがあったはずですが、今となってはその理由を明確に思い出すことができません。それ以上に、看過できない問題が発生していました。
事の発端は、私自身が過去の記事を検索しても見つけられない、という矛盾した状況でした。未来の自分に向けて記録しているはずの備忘録に、当の本人がアクセスできないのです。 Google Search Consoleで確認したところ、このサイトの半分近い記事がGoogleにインデックスされていないという事実が判明しました。この問題を根本的に解決するには、Googleの仕様に依存する現状から脱却するほかないと判断するに至りました。
Movable Type標準検索へ!移行を決断した3つのメリット
Movable Typeが標準で提供する検索機能へ回帰することは、単なる問題解決だけでなく、3つの明確なメリットをもたらすと判断しました。
- メリット1:全記事が検索対象になる 最大のメリットは、インデックス状況に関わらず、サイト内で公開されている全ての記事を検索対象にできることです。これで、何年も前に書いた短い記事や、ニッチなテーマの記事も、確実に振り返ることができます。
- メリット2:デザインの完全な自由 Googleカスタム検索は、検索結果の表示スタイルがある程度Googleの仕様に制約されます。標準機能であれば、検索結果ページのHTMLやCSSを完全にコントロールできるため、サイト全体のデザインと統一感のある、理想的な見た目を実現できます。
- メリット3:安定性 外部サービスの仕様変更・障害に影響されない安定した機能提供が期待できます。
【実践】Movable Typeサイト内検索の実装手順(全3ステップ)
ここからは、実際の移行手順を記録します。私のサイトは構造が少々複雑だったため試行錯誤しましたが、基本的な構造であれば、公式ページの情報で十分対応可能だと思います。
ステップ1:検索フォームを設置する
サイトのヘッダーなど任意の場所に検索フォームを設置します。
CMSプラットフォーム Movable Type ドキュメントサイト
<form method="get" id="search" action="<$mt:CGIPath$><$mt:SearchScript$>">
<div class="mm-searchfield__input">
<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="2">
<input type="hidden" name="blog_id" value="2">
<mt:Else>
<input type="hidden" name="IncludeBlogs" value="2">
<input type="hidden" name="blog_id" value="2">
</mt:If>
<input type="hidden" name="limit" value="<$mt:SearchMaxResults$>">
</div>
</form>
IncludeBlogsというパラメータで、検索対象にしたいブログのIDを指定します。カンマ区切りで複数のブログを横断検索の対象にすることも可能です。
このサイトはmmenuというプラグインを利用してサイドメニューを実装しており、サイドメニュー内に検索ボックスを表示させる必要があります。
そのため下記のようなコードを書いています。
<script>
//mmenu
document.addEventListener(
"DOMContentLoaded", () => {
new Mmenu( "#menu", {
"offCanvas": {
"position": "right"
},
"theme": "dark",
navbars:{content:['<form method="get" id="search" action="<$mt:CGIPath$><$mt:SearchScript$>"><div class="mm-searchfield__input"><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="2"><input type="hidden" name="blog_id" value="2"><mt:Else><input type="hidden" name="IncludeBlogs" value="2"><input type="hidden" name="blog_id" value="2"></mt:If><input type="hidden" name="limit" value="18"></div></form>']}
});
}
);
</script>
ステップ2:検索結果テンプレートを作成・設定する
検索結果を表示するページを用意します。システム標準の「検索結果」テンプレートをカスタマイズしました。
CMSプラットフォーム Movable Type ドキュメントサイト
<main>
<mt:SetVarTemplate id="search_results" name="search_results">
<mt:SearchResults>
<mt:SearchResultsHeader>
<mt:IfStraightSearch><$mt:SearchString$></mt:IfStraightSearch>
<div class="post-list-wrapper">
<ul>
</mt:SearchResultsHeader>
<li><a href="<$MTEntryPermalink$>"><$MTEntryTitle$></a></li>
<mt:SearchResultsFooter>
</ul>
</div> </mt:SearchResultsFooter>
</mt:SearchResults>
</mt:SetVarTemplate>
<$mt:Var name="search_results"$>
<mt:NoSearchResults>
<mt:IfStraightSearch><$mt:SearchString$></mt:IfStraightSearch>
「<$mt:SearchString$>」と一致する結果は見つかりませんでした。
</mt:NoSearchResults>
<mt:NoSearch>
<mt:IfStraightSearch>検索キーワードなし</mt:IfStraightSearch>
検索キーワードを入力してください
</mt:NoSearch>
<div class="search-pagination">
<mt:IfPreviousResults>
<a href="<$mt:PreviousLink encode_html='1'$>" rel="prev" class="prev"><div class="inner">前のページ</div></a>
</mt:IfPreviousResults>
<mt:IfMoreResults>
<a href="<$mt:NextLink encode_html='1'$>" rel="next" class="next"><div class="inner">次のページ</div></a>
</mt:IfMoreResults>
</div>
<mt:IfMoreResults>
<script type="text/javascript">
var div = document.getElementById('search-results');
var results = {
'<$mt:CurrentPage$>': {
'content': div.innerHTML,
'next_url': '<$mt:NextLink$>'
}
};
var timer = window.setTimeout("getResults(" + <$mt:CurrentPage$> + ")", 1*1000);
</script>
</mt:IfMoreResults>
</main>
下記はページネーションの設定になります。デフォルトの20件より検索結果が多いときに表示します。
<div class="search-pagination">
<mt:IfPreviousResults>
<a href="<$mt:PreviousLink encode_html='1'$>" rel="prev" class="prev"><div class="inner">前のページ</div></a>
</mt:IfPreviousResults>
<mt:IfMoreResults>
<a href="<$mt:NextLink encode_html='1'$>" rel="next" class="next"><div class="inner">次のページ</div></a>
</mt:IfMoreResults>
</div>
<mt:IfMoreResults>
<script type="text/javascript">
var div = document.getElementById('search-results');
var results = {
'<$mt:CurrentPage$>': {
'content': div.innerHTML,
'next_url': '<$mt:NextLink$>'
}
};
var timer = window.setTimeout("getResults(" + <$mt:CurrentPage$> + ")", 1*1000);
</script>
</mt:IfMoreResults>
ステップ3:再構築と動作確認
テンプレートの設置や変更が完了したら、必ずサイトの「再構築」を行います。これを忘れると、変更が反映されません。再構築後、実際にいくつかのキーワードで検索し、意図した通りの結果が表示されるかを確認します。
再構築時間との戦い
今回の改修で最も時間を要したのは、トラブルシューティングそのものよりも、テンプレートの「再構築」でした。私のサイトは複数のブログで構成され、テンプレート構造も複雑化していたため、サイト全体を再構築するとかなりの時間がかかりました。 Movable Typeのテンプレートを触るのは久しぶりだったため、仕様を思い出しながらの作業は骨が折れます。だからこそ、こうして備忘録として残しておくことが、未来の自分にとって重要になると考えています。
未来の自分へ、確実に届く記録を残すために
Movable Type標準のサイト内検索機能への移行は、単なる機能改修ではありませんでした。これは、私自身が未来の自分のために積み重ねてきた思考や知識という資産を、確実に引き出せるようにするための不可欠なメンテナンスです。 「備忘録が検索できない」という本末転倒な状態を解消し、サイトが再び私の信頼できる外部記憶装置として機能し始めた今、ようやく次のステップへ進むことができます。
今回の改修は、将来的に組織に依存しない働き方を本格化させる前の地ならしでもあります。サイトの基本的な問題を一つ解決したことで、その基盤がまた少しだけ強固になりました。次の課題は表示速度の改善ですが、これも時間をとって対応するつもりです。