WooCommerceの商品情報をREST APIで取り出す

WordPress + WooCommerceプラグインでECショップを構築しました。このブログで紹介したオリジナル3Dプリント品を販売するサイトなので、こちらのブログ記事にもショップの当該アイテムページにリンクを貼りたい、それも画像入りカード形式でカッコ良くしたい、というのがゴール。

通常はWordPress同士ならoEmbedというOGPのようなヘッダー情報があり、WordPressのGutenbergエディタにURLをペーストするだけでカード形式になってくれます。しかしなぜか今回の2サイト間では上手くいかない。

こんな感じで「このコンテンツを埋め込めませんでした。」と出てカードに展開されません。

ChatGPTに言われたとおりにApacheの設定かえたり子テーマにPHPコード書いたり二日くらい格闘しましたが解決せず。JSONのエンドポイントをブラウザで開くとレスポンスコードが200できちんと表示されるのに、curlだと401になったり。

あきらめて前から活用しているPZLinkカードというプラグインを使うことも考えたのですが、こちらでも403になって取得できない。

次にEmbedlyというWebサービスベースのプラグインを入れて無事サムネ、タイトル、概要などは出るようになったんですが、iframeで描画されるのでCSSで詳細がカスタムできない。無料プランだとサービスロゴが表示されたりというのもやや気になります。

Geminiにプラグイン書いてもらう

ChatGPTの助言も堂々巡りで疲れ切っていた時、ふと「もう同じサーバー上にあるので、MariaDB(MySQL)のID/PWを使ってPHPで直接データ取得してカードをレンダリングするプラグインを自前で作ったれ、と閃きました。するとChatGPTもセカンドオピニオンとして聞いたGeminiも技術的に可能だと返答。加えてGeminiが「それもいいけど、WordPress(というかWooCommerce)にはREST APIで記事(商品情報)のメタデータを取得する機能がるから、そっち使うのも手だよ」と提案してきました。なるほど、そんないいものが。それなら(まずないけど)将来的にサーバーを分離しても取得できます。やりたいことを読み取って最適な別解も提示してくれるGeminiさん強い

ということで、そこからは主にGeminiを使ってショートコードプラグインを作ってみたので、ざっくり手順を記録しておきます。

利用イメージは、Gutenbergエディターのショートコードブロックに「[shop id="123"]」のように入れることでカード展開されるというスタイルです。「[shop id="123,124"]」と複数のIDを入れるとカードが連続で並ぶところまで改良してもらいました。

APIにアクセスする認証キーを発行する

まずは読み出される側(ソース)のWordPressの管理画面を開き、WooCommerceプラグインの設定画面から「高度な設定」→「REST API」を開いて、「キーを追加」で発行します。今回は商品情報を参照するのみなので、権限を「Read」にしておけば万一キーが漏洩しても情報を書き換えられないのでお勧めです。

最終的に、Consumer KeyとConsumer Secretという2つの文字列が生成されるので、どこかにコピペしてメモっておきます(再表示できません)。

curlコマンドで動作チェック

商品IDを調べる

特定の商品を参照するID番号を調べます。WooCommerceの商品一覧で赤丸の箇所に表示されるのが商品IDです。

WindowsやMacの黒画面から以下を叩きます。

123が商品ID、cunsumer_keyとconsumer_secretはさきほど作成したものに置き換えてください。

StatusCode:200とかJSONデータが返ってくれば成功です。黒画面だと途中までしか見られませんが、ちゃんと価格や在庫情報なども含まれています。これを読み込んでカードHTMLをレンダリングするプラグインを作っていきます。

認証キーを安全な場所(wp-config.php)に記述

プラグインのソースコードにREST API認証キーを直書きするのはセキュリティ的に危険なので、通常Web経由でアクセスできない場所にあるwp-config.php内に定義して、それをプラグインから読み出すようにします。具体的には以下の形式で記述。

wp-config.phpはたぶんWordPress上からは読み書きできないので、シェルでサーバーにログインするか、FTP/SFPTで一旦ダウンロードして編集します。書き込み権限も削ってあると思うので、一時的にchmod +wする必要もあるでしょう。編集が終わったら-wも忘れずに。

WC_EXTERNAL_API_HOSTNAMEは便宜上ホスト名としていますが、もしWordPressがサブディレクトリにインストールされていたら、そのパスも書く必要があると思います。

プラグインのフォルダとファイルを作成

/wp-content/plugin/フォルダ下にshop-item-linkというフォルダを作ります。これがプラグイン名になります。さらに同じ名前でphpファイルshop-item-link.phpという名前で以下のコードをコピペして保存します。

HTMLレンダリングブロックは適宜書き換えてください。

編集ポイント

6行目のAuthorは適当に自分の名前に書き換えます。

17行目の第一引数の「shop」が実際に使用するショートコードになります。

46~48行目がwp-config.phpに定義した認証キーとホストネーム情報を読み込むところです。大文字部分を1字たりとも相違なくあちらと揃える必要があります。

66行目でカードよりも前に1回だけ出力したいHTML(この場合は見出し)を定義しています。

151~170行目あたりがカードのHTMLです。面倒くさいのでスタイルシートも直書きしてますが、カードを繰り返したくさん出力するならきちんとCSSファイルで定義するべきでしょう。

また元々Geminiが生成したコードでは取得内容を1時間キャッシュする仕様だったんですが、ウチの場合は必要ないし、むしろ価格や在庫はリアルタイムに反映してほしいので無効化してあります。ところどころにその残骸があるかも。

ともあれ、これで、[shop id="998,999"]などと書くだけで、

こちらで注文できます

TOYOTA新型クラウン向けスペアホール→タイプDスイッチアダプター

TOYOTA新型クラウン向けスペアホール→タイプDスイッチアダプター

参考価格: ¥1,800(別途消費税、送料がかかります)

在庫: あり

セキュリティカメラAnker Eufy SoloCam S340用雨樋/ポールマウント

セキュリティカメラAnker Eufy SoloCam S340用雨樋/ポールマウント

参考価格: ¥2,273(別途消費税、送料がかかります)

在庫: あり

が出るようになりました。

KUSANAGI + WooCommerceのドハマリポイント覚え書き

WordPress + WooCommerceで自家ECサイトを立ち上げた際、どうしても一部の文言が英語表記のまま日本語化できない問題でハマりました。

WordPressのプラグインは多言語化の仕組みをもっており、多くのプラグインはそれを通して表示する文言を言語ごとに切り替えています。しかしそれがどうも上手く機能しない。WooCommerceの決済や配送設定を日本にあわせてカスタマイズするJapanized for WooCommerceも入れており、どの文言はどちらのリソースで設定されてるかともわからず、ChatGPTにも聞きつつ、色々なところをいじりまくした。

先に結論

うちのWordPressは高速化プラットフォームのKUSANAGI9が導入されています。結論をいうと、その一部である「翻訳アクセラレーター」という機能が原因でした。これをオフにしたら英語だったところがあっさり日本語になりましたとさ。

途中したこと→結果色々カスタマイズできてよかった

以下は結果として原因の根本解決にはなりませんでしたが、結果的に自分で文言を修正したいところがあり(お買い物カゴ→カートなど)、そのための仕組みの理解が深まったので結果オーライかなと思っています。

文言修正方法その1 Loco Translate

まず前述のローカライズファイルで定義されている文言をいじる方法があります。多くのソフトでは.po/.moという拡張子の言語ファイルを使っています。.poファイルに原語(厳密にはどこで使われるか定義するID)と翻訳後のテキストの対応データが入っており、それをコンパイルしたのが.moです。例えばWooCommerceの場合、/wp-content/lanmguage/pluginsにwoocommerce-ja.po/.moがあります。これを直接編集してもいいですが、プラグインの更新などで上書きされてしまうので、Loco Translateというプラグインをインストールして、WordPress上から編集した方がよいです。GUIでプラグインやテーマがもつ言語リソースをリストしてくれて、検索して書き換えることができます。POEditというPC向け編集ツールがありますが、それに近い感覚のUIがWordPress上で使えます。

で、これでみると翻訳率は100%とかになってるのに、公開される画面では日本語にならない。試しに編集してみても反映されない。最新の翻訳定義ファイルを同期すると未翻訳の文言も出てきて、一部はそれで反映もされますが、とにかく英語箇所がめちゃくちゃ残る!

ChatGPTにはKUSANAGIやPHP-fpmのキャッシュの可能性を散々指摘されるのでフラッシュしてみるけどダメ。また最近のWordPressは上記フォルダにある.jsonファイル(たくさんありすぎてどこになにがあるかは追跡不能)を使ってるから.poファイルいじってもダメ、みたいなことも言われたい。

結果として先に書いたKUSANAGIの翻訳アクセラレーターを無効にしたらOKだったわけですが、結果としてこのLOCO Translateはめちゃ重宝してます。翻訳後で気に入らない箇所の修正が手軽に行え、プラグインの更新でリセットされないよう管理もできます。先の「お買い物かご」を「カート」に言い換えたり、文章もなんとなくしっくりこない箇所を直したりといったことに使えます。翻訳のためのプラグインではあるんですが、表記カスタマイズツールとして必須プラグインでしょう。

文言修正方法その1 gettext

それでもそもそも.poファイル(の元の.potファイル)に定義されておらず、PHPコードにハードコーディングされた文字列などがあったりします。そいう時は自分のテーマ(子テーマ)の中のfunctions.phpにgettextというフィルターを使ったコードを書くことで強制的に表示文言を置換することができます。詳しい書き方はこちらなどが参考になると思います。

https://tech.kurojica.com/archives/19876

翻訳アクセラレーターが原因と判明するまで、あらゆるところをせっせとこれで書き換えていましたw。でも最終的にはきちんと標準の日本語翻訳が当たって、一部の不満箇所をLoco Translateで修正、で済んだのでgettextを使った置き換えはすべて削除しました。盛大に遠回りしましたが、パフォーマンス的には無駄も多いと思うので排除できて良かったです。まぁ非常手段としてメモしておきます。

まとめ

ということで、もしKUSANAGI環境でWooCommerce(や他のプラグイン)の英語表記が残る問題に直面したら翻訳アクセラレーターを切ってみることをお勧めします。

またLoco Translateは日本語化された箇所のカスタマイズにも超絶便利なので是非活用してみてください。