前回の記事で書いたように、このサイトに導入しているプラグインの大改修を行い、運用を始めつつ、改修・機能追加するフェーズに入ったので、その報告を書きます。
WordPressプラグイン実装でComposerを使う場合の落とし穴
さて、WordPressはPHPというプログラミング言語で書かれており、プラグインも同様にPHPで記述します。
NodeJSでいう「NPM」、Rubyでいう「Rubygems」のように、PHPにもパッケージ管理ツールである「Composer」というものがあります。
このパッケージ管理ツールからライブラリをインストールしてプラグインの一部として使うことで、自分で実装するコードを飛躍的に減らし、素早い開発を実現することができます。
しかし、WordPressプラグインを開発するのに、そのまま使ってしまうと(むしろそれが通常の使用方法なのですが…)WordPressが読み込んだ別のプラグインの中で、同じライブラリを使用していた場合、意図しない側のライブラリを使用してしまい、おかしな挙動をする場合があります。
私は「BackWPup」をインストールしていたのですが、これに含まれる「Guzzle」というライブラリが、自作のプラグインに導入したものとメジャーバージョンが異なることで発生したエラーにより問題が発覚しました。
Uncaught Error: Call to undefined method GuzzleHttp\Utils::chooseHandler()
前作のプラグインではこれをケアできていなく(たまたま問題が発生せず、この問題に気がついていなかった)、併用するプラグインによっては正しく動作しない可能性があります。
実のところ、これがケアされていないプラグインが公式プラグインにも結構あるようです。
プラグインごとの名前空間を追加する
さて、ではどのように解決できるかというと、「プラグインに導入したライブラリに上位の名前空間を付与して、隔離する」という方法で解決することができるようです。
この問題にぶち当たってから調べていくにつれて、あの有名な「WooCommerce」なんかも困っていたようです。(使ったことがないので詳しくはわかりませんが)
先人の知恵を借りようと検索して情報収集していると「PHP-Scoper」というので解決しているそうです。
しかし、先人のものまねをしてみても、どうにも自分の手元では解決ができませんでした(おそらく自分のせい)
「BrianHenryIE/strauss」で解決
他のツールも試してみた結果、「BrianHenryIE/strauss」というツールで対応方法もシンプルでかつ解決に至ることが出来ました。
PHPパッケージの名前空間回避ツールとして「coenjacobs/mozart」というものがあったようですが、そこからWordPressプラグインのためのツールとして「BrianHenryIE/strauss」へフォークしたようです。
使い方はリポジトリの説明を見て、コマンドを追記すれば動く程度には簡単だったので、READMEを参考にしてください。
ただ、一部のライブラリについては、そのライブラリ内部の実装の仕方の問題で動作させることができなくなってしまいました。
こういったこともあるので、実際に動作確認してみて、名前空間の切り分けを見送るか、手動で対応するとか、違うライブラリに変えてしまうなどの対応が要求され、一発というわけにはいきませんでしたが、十分な効果は得られました。
ブロックエディタへの対応
前作のプラグインでもブロックエディタには対応していました。
と言うよりも、実装としては「ショートコード」によるもので、それを素人ながらこねくり回してどうにかブロックエディタで扱えるものにしたものでした。
今作ではキチンとブロックエディタ用にブロックの実装をしています。ブロックプラグインの開発はこの公式ページが参考になりました。
このチュートリアルにならって「create-block」コマンドで雛形を作り、一通りこなしたら理解できました。たったこれだけで十分に実用的な雛形が作れるのでとても便利ですね。
具体的なプラグインの実装には前作からソースを転用したり、プラグインハンドブックを参考に進めていきました。
あとは実現したいことをモリモリガリガリ作っていくだけ、って感じですね。
WordPressは歴史が長くて、後方互換性を保ちつつ進化を続けているのは本当にすごいと思いますが、故にレガシーな辛みを引きずっているところがあり、実はあんまり関わりたくないなぁ…と思ってるところがあります。
ま、CMSとして、オープンソースで無料で使えて、プラグイン資産も多いので乗っかって楽になるメリットのほうが上回るので利用させていただきますが。
プラグインを使ったワークフロー
このプラグインを使ったワークフローはこんな感じ。
URLを入力して、取得ボタンを押下すればデータを取得して各項目にセットします。
データの取得はAPIは使用せず、スクレイピングだけで実現しています。(APIキーの準備とかめんどくさいし、結局取れるデータが限られている)
FANZAやDLsiteのサイトごとのプラグインとして実装しています。サイトに最低限必要な実装だけ作ればいいようにしているので、他のサイトへの対応もできる仕組みとなっています。
このデータをベースにした商品に関するページをボタン一発で作成できます。
テンプレもカスタム可能にしたいのですが、現状はソースコード固定となっています。
制約はあるものの、各ブロックの配置や共通パーツを配置できるように、ページのテンプレート機能も実装しました。
後はこの生成したページを元に自分の記事を書いていく、というワークフローを想定しています。
まとめページを作る場合なんかは、カードのコードブロック単体を使うこともできます。
ひとつづつ商品を登録するのも大変なので、CSV形式でリストを流し込んで登録することもできるようになってます。
データの取得や記事作成をバッチ処理するための仕組みもあるので、URLさえ登録すれば、一括で商品データを埋めるということもできます。
価格情報も取得しているので、セール情報も表示できます。もちろん定期的に取得して自動的に更新されます。
セール中一覧のブロックも作りました。
商品管理されている商品のセール情報をリストで表示するブロックです。
FANZAブックス
今年4月にFANZAブックスの試し読みページのアフィリエイト素材使用が解禁されて久しいですね。
11月現在のところ、未だ素材の提供はありませんので、利用規約違反にならないように、自力でキャプチャを撮るしか無いようです。
プラグインとは別のサブシステムを構築して、キャプチャさせる手法としました。
まだ若干不安定ですが、URLを指定すればキャプチャを保存して、それをダウンロードできるシステムができました。
見ての通り、AWS Lambdaに関数としてシステムをデプロイしており、エンドポイントへリクエストすると、試し読みページをキャプチャしてS3へ保存、レスポンスとして保存したキャプチャの画像ファイルURLを返却させています。
このシステムの維持費が高額では元が取れなくなってしまうので、お金を掛けずにかつ利便性のバランスを取った構成には出来たと思います。
そしてこのAPIにプラグインから問い合わせられるようにすることで、前述のワークフローと同じ手順でFANZAブックスに対応できました。
試し読みの初回キャプチャにはページ数に比例して少し時間がかかりますが、FANZAブックスの商品も5分以内でこの記事のような内容で構築できます。
このAPIをサービス化しようかとも検討しましたが、形として取得したキャプチャの再配布となる気がするので、規約的にちょっとはっきりしないので、一旦保留としました。
システムスタックを立ち上げるプログラムコードなら、あくまでそのコードの利用者がキャプチャしたものとなるので、そういった方法でなら、提供ができるかもしれませんね。
今後の改修・機能追加
AIによるサポートはまだあまり成熟しておらず、プロンプトの作り込みが甘いのでまだ実用的ではないので、もっと作り込んでいきたいですね。
他には、実際に運用していくなかで気がついた欲しい機能を盛り込んでいこうと思っています。
具体的な計画は特に立ててませんが、運用にこじつけられる程度には機能の実装ができたので、あとは細かい作業って感じですかね。
すこし大きな目標としては、サークルやメーカーの情報もページとして管理できるようにして、それらとの内部リンク施策ができるようにもしていきたいですね。
まとめ
まずはドッグフーディングで運用しながら手を入れていきますが、もし他人様に使ってもらえるようなレベルになったら、数名〜十数名程度の方に頒布して、使ってみてもらいたいなとも考えてはいます。(計画は未定ですが)