北村由衣のブログ

記事一覧に検索機能を追加

ブログ記事一覧に、検索欄とタグ機能を組み込みました


記事一覧のキャプチャ
並び替えもできるようにしたので、今後記事の本数が増えていくにつれて、多少便利に使えるんじゃなかろうかと、思っています

Googleの検索エンジンには、一覧ページも個別記事も、なんだかんだインデックスしてもらえているようなので、 クリティカルな検索ワードを指定すれば検索結果に出てきてくれるようです。


Google検索のキャプチャ
ただ、まだこのサイト自体の価値がそこまで評価されておらず、ふつうに検索すると、同音異字の女優さんが出てきますね

一覧の並び替え機能

記事一覧に実装した機能について、実装の経過を記録しておこうと思います

並び替え、ソート機能ですが、2種類各2方向の計4パターン用意しました。日付順・タイトル順の、それぞれ昇順・降順です。
そもそも一覧自体、ハードコーディングはしておらず、一覧のlist.htmlに仕込んだJavaScriptが、 Ajax通信でページ読み込みとは非同期でcontent_list.jsonを読み、そのデータを元にリンクを生成したりしています。
なので、表示させるスクリプト処理にひと手間加えるだけで並び替えは実装可能でした。

一覧ページの作成当初から、並び替え機能は組み込むつもりでしたので、当初の実装自体「日付順・古い順」という並び替えを 内部処理として独立した関数で実行していました。 なので、UIとしてのラジオボタンの作成と、選択内容に応じて並び替える処理を呼び出すだけで大まかには実装が完了しました

日本語文字列の昇順/降順

悩んだのがタイトルの並び替えです。

例えば「今日の記事」と「今風な話題」で検討してみましょう。
読み仮名を振ると「きょうのきじ」「いまふうなわだい」ですね。なので「いまふう」が先に来て欲しいわけです。 ところが、漢字のまま並び替えをすると、「今日の記事」の後に「今風の話題」がやってきます。これは、文字コードで並び替えられているためで、 今日=\u4ECA\u65E5と、今風=\u4ECA\u98A8のUnicode比較をすることになり、 実際の文字の読み方に関係なく「1文字目が同じ、2文字目は『風』の方が後」と判定されるわけです

//JavaScript
const kyou = '今日';
const imafu = '今風';
let ary = [imafu, kyou];
console.log(ary);
ary.sort();
console.log(ary);
//console log
(2) ['今風', '今日']  //元データ
(2) ['今日', '今風']  //並び替え結果

これでは、五十音順には並べられません。解決策として、非表示要素として読み仮名のデータを持たせることにしました。

list: [
{
  title: "今日の記事",
  ruby: "キョウノキジ"
},
{
  title: "今風の話題",
  ruby: "イマフウノワダイ"
}
]

これで、表示用のタイトルと、並び替え用の読み仮名(ルビ=ruby)が用意できましたので、内部処理で並び替える時には読み仮名を照会させ、 五十音順に並ぶようにできました

//JavaScript
const kyou_ = 'キョウ';
const imafu_ = 'イマフウ';
let ary_ = [kyou_, imafu_];
console.log(ary_);
ary_.sort();
console.log(ary_);
//console log
(2) ['キョウ', 'イマフウ']  //元データ
(2) ['イマフウ', 'キョウ']  //並び替え結果

小文字が入ると発音と多少相違がでるのはご愛敬。例えば、今日='キョウ'と器用='キヨウ'では、 小文字が文字コードで先に定義されているため、「キョウ(今日)」「キヨウ(器用)」と並びます

絞り込み検索機能

タイトル検索

タイトルに含まれる文字を検索できる機能として実装しました。 読み仮名での検索には対応していません。読みでの検索に需要はあるのかしら。

記事一覧に表示する元ネタとして持っているデータを、JavaScriptでぐるぐる照合しているだけです。
記事件数が何千と増えたらミリ秒単位で負荷にもなるでしょうが、まぁ、そんなことになる頃には、 もういっそこの仕組みを全面的に見直している気がします。 検索処理によるサーバへの通信は発生しません。画面表示時に初期取得した一覧データを元に、制御しています

タグ検索

記事に対してタグを設定しています。同じタグが設定されている記事だけを表示させる機能として実装しました。

絞り込み機能を作るにあたり、3点ほど壁がありました。

1つ目が、選択肢の生成です。を組み込みました。 このセレクタに表示させる選択肢は、実際の記事に設定されているタグたちをかき集めて表示させるようにしました。 実装としては、記事の一覧データを読み、タグを抜き出して集め、重複を除いて、並び替えて、選択肢に追加する、という処理です。 壁と感じたのは、漏れなく重複なく、という要件を充たそうとしたためかと思っています。 データに群に対する2重ループの中で「もし既存なら追加しない」といった分岐を噛ましたことで、ネストが深くなってしまいました。

2つ目が、検索機能間の影響です。タイトル検索と、タグ検索の2種類を用意したのですが、 これはお互いに無視するのではなく、両方入力されていれば両方の条件に合致する記事だけを表示したいのです。 実装するとき、まずはタイトルの絞り込み機能、次にタグ検索の機能、と順に実装したため、 お互いの影響という点で手直しが発生してしまいました。

3つ目は、タグをクリックした時の絞り込みです。一覧表示で記事の横に設定されているタグを表示していますが、 その表示されているタグがクリックされたら、当該タグの記事に絞り込まれるようにしました。 どうするか迷ったのですが、これは、ページの再読み込み(再アクセス)を含む実装としました。 イメージとしては、タグ毎のページに遷移する、といったところでしょうか。 queryStringでパラメタとして受け取って表示するようにし、 .../list?tag=Javaのようなリクエストで当該タグのみ初期表示するように実装しました。

一覧ページは…

前回と今回で、当ブログの機能拡充をしたわけですが、 いずれも記事自体の本数が増えていかないとなかなか光を浴びないのかな、と。
特に一覧ページの機能を拡充した今日の機能追加は、本数が増えてこそ活きると思うので。

下書きにすらなっていない、書きたいことメモだけは数本あるので、 遅筆ながらも、時間を使ってでも、書いていきたいと思います


このエントリーをはてなブックマークに追加


コメントはこちらからお寄せください