に投稿 コメントを残す

Woocommerceのプラグインを作ってみた

今回作るのは商品一覧の初期ソートを設定するプラグインです。通販サイトで商品一覧を見る時、大抵最初はおすすめ順とかになっていますが、あれって何を基準に並べてあるのか良く分かりません。店が売りたい順なのかなと疑いながら安い順などに並べ替えることになります。

Woocommerceでも初期ソートはデフォルト表示になっています。これは、商品登録をする際に高度な設定で表示順番を登録することができ、それを反映した並び順なのですが、お客さんにはなんのことやらさっぱりです。安い順や人気順、あるいは平均評価順など、お客さんにとって意味が分かりやすい順で並べたほうが使い勝手の良いサイトになるでしょう。

実のところ、この初期ソート自体は、追加のプラグインを入れなくても変更できます。外観のカスタマイズからWoocommerce > 商品カタログで、デフォルトの商品順を設定できます。そこで今回作るプラグインでは、商品詳細ページ、カートページ、マイアカウントページ、支払いページ、そしてその他のページそれぞれから飛んできた時の表示順を設定できるようにします。

まずは開発環境を整えます。XAMPPを使います。そこへWordPressを入れてWoocommerceを入れる訳ですが、先にWoocommerceがどのWordPressのバージョンまで対応しているか確認します。うかつに最新版のWordPressに飛びつくとやり直すはめになります(経験済み)。それから、php.iniを開いてmax_execution_timeに-1を設定しておきます。最初は30になっているので時間が足りずWoocommerceがインストールできない可能性があります(経験済み)。

環境が整ったらいよいよ作成です。プラグインと言っても基本はただのPHPです。先頭に規定のコメントを書くとプラグインとして認識されます。

バックエンドの作成にはadmin_menuのアクションフックを使いadd_menu_page()で呼び出す関数でページを表示させます。今回のプラグインでは、商品一覧へ辿り着くリファラ毎に、表示順のセレクトボックスが並ぶ画面にします。表示順のセレクトボックスはどこで設定されているのでしょうか?

見つけました。woocommerce/includes/wc-template-functions.phpのwoocommerce_catalog_ordering()で設定されています。それをそのまま持ってきます。submitボタンを付け、update_option()で設定の更新、get_option()で設定を取得できるようにして、描写の際に反映させればバックエンドの基本の動きは完成です。

リファラの情報も取得する必要があります。商品詳細以外はwp_postsテーブルにあります。そこへデフォルトと商品詳細の情報を合わせ、その数だけセレクトボックスを出します。デザインも整えたいところですが、後回しです。

次は設定をフロントエンドへ反映させる処理です。商品一覧を表示させるタイミングで、セレクトボックスのselectedを変更できれば良いはずなのですが……。

商品一覧で表示順のセレクトボックスを出すテンプレートがwoocommerce/templates/loop/orderby.phpであることは分かりました。そしてそこへ値を渡しているのは前述のwoocommerce_catalog_ordering()です。

woocommerce_catalog_ordering()が値を渡した後、セレクトボックスが描写される前に割り込めれば良いのですが、値を渡す時点で描写も完了してしまうようです。試しに値を渡すために使われてるwc_get_template()を使うとセレクトボックスが二つ出来ます。この動きは求めていない。

ではwoocommerce_catalog_ordering()が受け取る値を変えるしかありません。引数はないので、内部で取得している値、すなわちwoocommerce_default_catalog_orderbyです。

これは、前述の外観のカスタマイズからの設定を収めている場所です。これをwoocommerce_catalog_ordering()が呼び出される毎に、先んじて変えてやれば、こちらの設定を優先させることができます。

woocommerce_catalog_ordering()はwoocommerce_before_shop_loopのフックで呼び出されていますが、優先順位は低いです。そこで同じフックにこちらのフロントエンド用関数を登録します。そして設定した値を取得し、その中からリファラに合わせた値を選び、それをwoocommerce_default_catalog_orderbyへ上書きします。

さてどうだ……上手く行きました。裏では呼び出す度にDBへ書き込みが行われている訳ですが、表向きは意図どおりの動きです。この仕様はDBのパフォーマンスにはよろしくないかもしれません。しかし、まずはそのパフォーマンスが気になるほどお客さんを集めるほうが先決でしょうね。

コメントを残す