「Programming」カテゴリーアーカイブ

AmazonのPA-API制限への対策

今年になってからのProduct Advertising API(PA-API)の利用ポリシーの変更により、1ヶ月以上アフィリエイトの売り上げが無い場合にはPA-APIの利用ができなくなりました。そのため、4月の段階でこのブログではAmazonJSプラグインを使った投稿画面での商品検索とアフィリエイトリンク挿入、並びにAmazonJSによるブログ記事での商品紹介が表示されなくなっていました。その後、4月以降いくつか他のアフィリエイトリンク経由での売り上げがあったためPA-APIの利用が復活し、今日(2019/7/14)時点でもまだ使えています。でもまたいつ利用停止になってしまうか分かりませんので、何らかの対策を始めることにしました。ちなみに、ウェブ上でリンクを生成してくれるサービスなども軒並みこのAPI制限(売り上げがないAPIアクセスの切り捨て及びアクセス過多のサイトの制限)により使えなくなっているようです。

検索してみると、使えそうなツールとして"カッテネ"というのが見つかりました。WordPress用のプラグインとして利用可能ですが、HTML及びCSSも公開されています。いずれにしろリンク先URLや画像は自分で別途探して記入することになります。使用方法はリンク先の作者さんのサイトを見てもらうこととして、詳細はここでは述べません。

WordPressのプラグインを導入した場合ですが、このプラグインを有効化すると独自のショートコードが利用可能になるだけで、自分でショートコード内にJSON形式で画像とリンク先、タイトルなどを記入しなくてはなりません。投稿画面でボタンを押すと雛形が挿入されたりするわけではなく、記述方法を覚えるかどこかからコピペすることになり、正直なところこのままでは使いにくいです。将来的にこの辺が使いやすく改良されると良いのですけど。

そこで、作者さんのページでも紹介されている"Shortcoder"というプラグインを併用することにします。このプラグインは定型文をショートコードとして投稿画面に挿入してくれるものです。ただしショートコードでショートコードを挿入することはできませんので、カッテネで公開されているHTMLの方を定型文として登録します。パラメーター指定もできますので、画像URL・商品URL・タイトルなどは変数としておきます。投稿画面でShortcoderのボタンを押して作成した定型文を選ぶとパラメーターの入力画面になり、記入して挿入ボタンを押せば、投稿画面にパラメーターを含んだショートコードが挿入されます。記事が表示される際にこのショートコードはカッテネのHTMLに展開されて商品リンクが表示されます。

Shortcoderを利用してAmazonリンクを挿入する
Shortcoderを利用してAmazonリンクを挿入する

ちなみにこの方法でリンクを挿入する場合は、自分のサイトのスタイルシートにカッテネのCSSも記述しておかないと、Katteneプラグインを有効化していたとしてもスタイルが適用されません。KatteneプラグインはどうやらKatteneのショートコードが存在しないとスタイルシートも読み込まれないようです。なので私の使い方をするならKatteneプラグインは入れなくても問題ないということになります(WordPress以外の使い方と全く同じになります)。

私の運用方法としては、Amazonで紹介する商品を検索し、商品ページからアソシエイトツールバーを使って画像リンクを取得。そこに含まれているURLを商品URL及び画像URLとして使用します。カッテネのページで説明されているやり方でアソシエイトセントラルからURLを取得してもよいのですが、商品説明として記述する内容を取得するのにどうせ商品個別ページも開かなくてはなりませんから、最初から通常のAmazonで検索してアソシエイトツールバーを使った方が簡単です。

AmazonJSを使って作ったリンクになるべく似せるためCSSを編集してタイトルの見た目を変え、さらにAmazonボタンも小さめにしました。こうして出来上がったリンクの例は以下のようになります。

これから少しずつ過去記事にあるAmazonJSのショートコードを置き換えていこうと思いますが、10年ブログをやっていると(中断期間もあるとはいえ)さすがに数も多いんですよね。時間はかかると思いますがコツコツと少しずつやっていきましょうか。

Amazonのアフィリエイトリンクが死亡

この投稿日は4/1ですが、エイプリルフールネタではありません。いたって真面目な話です。

このブログで商品などを紹介する際にはAmazonへのリンクと画像を使用しています。アフィリエイトでガッツリ儲けようという意図はなく、デザイン的にもいいし投稿も楽なので、AmazonJSというWordPressのプラグインを使用してリンクと画像を挿入しています。先月はちょっと用事があってブログ記事は1回しか投稿できませんでしたが、その時には何の問題も無くAmazonへのリンクが表示されていました。ところが昨日久しぶりに投稿でもしようかと自分のブログを見てみると、投稿中のAmazonアフィリエイトリンクが全く表示されないではありませんか。以前同様な現象が起きた時はProduct Advertising API(PA-API)の認証キーを再生成することで解決したので、今回も同じ方法を試してみましたがダメでした。

調べてみると、WordPressやAmazonJS側の問題ではなく、私のPA-APIが無効になっている可能性が高いようです。今年に入ってPA-APIの利用ポリシーに改定があり、1ヶ月以上アフィリエイトの売り上げが無い場合にPA-APIの利用ができなくなるとのことです。売り上げレポートを見てみると、2月には売り上げがありましたが、3月に入ってからは確かに売り上げがありません。うーん。

PA-APIを使わずにAmazonの商品ページから生成するリンクに置き換えてもいいのですが、数が多いのでちょっとやる気がおきません。アフィリエイトの売上実績があればPA-APIを再び利用できるようになるみたいですので、見た目は悪いですが、しばらくこのままで放置して様子を見たいと思います。左のカメラ・レンズのAmazonへのリンクは生きているので、そちらが利用されることを祈るのみです。いつまでも復活しないようなら、コツコツとリンクを書き換えましょうかね・・・。

私のような弱小ブログのオーナーにはこの30日ルールは厳しすぎます。今までも1ヶ月売り上げが無いことなんてしょっちゅうあります。せめて90日ぐらいにしてもらえないですかね。

WindowsでMac風の日本語入力

MacのJISキーボードは、英数キーをおせばIMEオフ、かなキーを押せばIMEオンとなり、現在どちらの入力モードにあるか意識せずとも切り替えができ非常に便利です。間違って日本語入力モードのまま英数字をタイプしてしまっても、英数キーの2度押しで半角英数に変換してモードも変更してくれます。USキーボードには英数・かなキーはありませんが、Karabinerというアプリを使うと左右のCommandキーをそれぞれ英数・かなキーと同じ機能を持つように設定することができます。私のMacにはWindows用のゲーミングキーボードを使っていますが、KarabinerでOption(Alt)キーとCommand(Win)キーを入れ替えて、さらにCommand(Alt)キーでIME切り替えできるようにしています(ゲーミングキーボードも導入)。

困るのは仕事で使っているWindows PC。JISキーボードなら半角/全角キーでトグル変換なので、今どちらの入力モードにあるか意識して切り替える必要はあるものの、まだ1ストロークです。しかしUSキーボードだとAlt+~での変換となりちょっと面倒です。WindowsでもKarabinerが使えればいいのに。

というわけで、Keyhacというアプリケーションを導入してみました。Keyhacである程度はMacに近い操作にカスタマイズすることができます。JISキーボードなら無変換・変換キーをMacの英数・かなキーと同じ動作をするように変更できます。USキーボードだと変換・無変換のキーがありませんので、左のコントロールキーの1度押しで英数、右のコントロールキーの1度押しでかな入力モードになるように設定してみました。

def ime_on():
	keymap.wnd.setImeStatus( 1 )

def ime_off():
	keymap.wnd.setImeStatus( 0 )

keymap_global[ "O-RCtrl" ] = ime_on
keymap_global[ "O-LCtrl" ] = ime_off

keymap_global[ "LWin-J" ] = "F6"
keymap_global[ "LWin-K" ] = "F7"
keymap_global[ "LWin-I" ] = "F10"

本当はスペースキーの横にあるAltキーでIMEのオン・オフを行いたいのですが、Altキーを押した時点でメニューバーがアクティブになる(Altキー本来の動作)のが優先されるため、IME切り替えのためにはAltキーを2度押しする必要があります。レジストリをいじってAltキーをCtrlもしくはWinキーと入れ替えればMacと同じキー配置にできますが、そうすると他のショートカットに影響が出てきますので諦めました。またMacと同じように左Ctrlキーの2度押しで半角変換->確定->英数入力モードとなるようにしたかったのですが、これもうまく実現できませんでした。

加えて、左WinキーとI、J、Kキーの組み合わせでひらがな、カタカナ、半角英数に変換できるようにしました。MacだとCtrlキーとの組み合わせで出来ることを再現しようとしたわけです。WindowsでCtrlキーと組み合わせると他のショートカットとかぶってしまうので修飾キーはWinキーに変更、さらにMacだとCtrl+Lで半角英数なのですがWin+LはスクリーンロックになってしまうのでWin+Iに変更しています。

Keyhacの設定はGUIではなく、Pythonで書かれたファイルを編集する必要があります。人によってはちょっと敷居が高いかもしれません。またデフォルトで書かれている設定から不要なものは削除したほうが良さそうです。私はPythonはまったく触ったことがなかったのですが、見よう見まねでなんとか設定してみました。Pythonではインデントの位置で関数やステートメントの有効範囲が決まるようなので注意する必要があります。ちなみに私の環境ではKeyhacを動作させるためにVisual Studio 2015ランタイムパッケージをインストールする必要がありました。この辺のことも公式ページに書かれていますので、使ってみようと思われる肩はしっかりと読んでおきましょう。

完璧とは言いがたいですが、少しはMacとWindowsの使い勝手を近づけることができたかなと思います。KeyhacはMac版もあり、Sierraで動かないKarabinerの代替アプリとしても挙げられているんですが、El Capitan+Karabinerが優秀すぎるので、もうしばらくOSアップデートを控えてKarabinerを使い続けようと思っています。

データベースをいじったら・・・

WordPress上のブログ記事はデータベース(MySQL)に保存され、すべての記事にはIDが振られて管理されています。そのIDが結構歯抜けになっているのに気づいて、なんとかキレイにしたいと思っていました。サーバーを変更したのを機に、ついに着手しました。

投稿IDの変更は実は簡単ではなく、他のテーブルやレコードで参照されているものもすべて書き換える必要があります。そしてすべての投稿IDを整合性を保ってきちんと書き換えました。パーマリンクにはIDを使ってませんので、URLの変更はありませんし、カテゴリーやタグ、コメントなどちゃんと今まで通りになっているのも確認しました。一部メニュー部分で書き換え忘れた部分もありましたが気づいて直しました。これで完璧に書き換えれたと思っていました。しかし、どうやらそうではなかったようです。

現在自分で気づいている不具合は2点。1つはJetpackのサイト統計情報。個別記事のアクセス情報はIDで管理されていたらしく、統計がどうもおかしなことになっています。自分では直しようがないですし、ビジターの方々には全く影響はないので、もう諦めるしかないです。

もう一つは関連記事。こちらは各投稿のメタ情報内にキャッシュとして関連記事のIDが保存されているのでそこを書き換えればいいのですが、かなりの手間です。おそらくですが、そのうちキャッシュは期限が切れますから、そのうち情報がアップデートされて正しく関連記事を表示してくれるんじゃないかと思っているんですが、どうでしょうか。1ヶ月経っても直らないようなら手作業でやるしかないですかねぇ。

一応データベースのバックアップは取ってあったんですが、もう大丈夫と思って新規投稿をしちゃったんで、ロールバックも出来なくなってしまったのは大失敗でした。

そんなわけで、データベースを直接いじる場合は本当に慎重にやらないといけないという教訓でした。特に投稿IDはいじっちゃいけませんね。ちゃんと連番にしたいというのは単なる自己満足なのは分かっています。歯抜けを直す・起こしたくないなら投稿の直後に確認するなりして大きな影響を及ぼす前にしないとダメでした。起こってしまったことは仕方ないので、今後気をつけていきたいと思います。

AmazonJSが動かなくなった原因&対処法

このブログでは商品の紹介をするのにAmazonJSというWordPressのプラグインを使っています。アフィリエイトのためではなく、簡単できれいに商品情報を記事中に挿入できるからです。

ところが、先週ぐらいから(もしかするともっと前からかもしれません)このプラグインがうまく動作しなくなってしまっていました。記事中ではAmazonJSが出力する商品情報ではなくAmazonのデフォルトの商品リンク(サイドバーに貼り付けているのと同じやつです)になってしまい、また投稿画面からの検索もRequest Expiredとなって行うことができませんでした。

Amazon側のアクセスキーを取得しなおしても変化なし。しばらく前にWordPress本体のセキュリティーアップデートがあったのでそのせいかもと思いましたが、検索してもそのような報告はひとつもなく、それどころか他の方のブログではすべてちゃんとAmazonJSが機能しているようです。

どの端末で見ても同じ現象なので、問題は私のブログもしくはサーバーの設定にあるのは間違いありません。検索がRequest Expiredになっていることから時刻関係の問題ではないかと考えました。普段はシンガポールから更新しているのでWordPressのタイムゾーンはシンガポールに設定してあるのですが、これを東京に変更してみました。サーバーは日本にありますし端末も日本の時刻に変更してあります。それでも問題は解決しません。

もうお手上げかと思ったその時、WordPressのタイムゾーン設定画面に表示されている世界標準時(UTC)が明らかにずれている(遅れている)のに気がつきました。WordPressや端末のタイムゾーン設定にかかわらず常に間違ったUTCが表示されていますので、これはサーバー自体の時刻設定が狂ってしまっています。私のサーバーとAmazonのサーバーの時刻が一致しないためAmazonへのリクエストが期限切れ扱いになっていたのですね。というわけで借りているVPSのコントロールパネルからサーバーを再起動させてみました。果たして、UTCの表示は修正され、AmazonJSもこれまで通りにちゃんと動作するようになりました。

なぜサーバーの時刻がずれてしまったのか、根本的な原因は分かりません。でも今後同様な問題が起きた際の対処法としてメモしておきます。

WordPress 4.4とタグクラウド

WordPress 4.4に早速アップデートしました。すると、このブログのサイドバーにあるタグクラウドが下の画像のように乱れてしまいました。左側が正しい出力、右側が乱れた出力です。

タグクラウドの表示が乱れた
タグクラウドの表示が乱れた

タグクラウドはウィジェットを使っていますが、後述のようにテーマのfunctions.phpでフィルターをフックしてパラメーターを渡し、出力内容を変更しています。試しに変更を加えずそのままデフォルトのウィジェットを出力するように変更すると正しく出力されます。検索してみると同様な現象の報告はあるものの解決策は見つかりませんでしたので、自力でなんとか解決してみました。

まずは正しい出力と乱れた出力のHTMLソースを見比べてみます。正しい出力では、タグクラウド部分全体が<aside>タグで囲まれ、その下に<h1>タグでウィジェットのタイトルがあり、次に<div>で囲まれたタグクラウド本体が出力されています。ところが、乱れた出力ではこれらのタグが一切なく、前のウィジェットの直後にいきなりタグクラウド本体が出力されてしまっています。<aside><div>に指定されているクラスが存在しないためCSSも正しく適用されていないわけです。タグクラウドの内容自体(除外するタグや並び順など)はデフォルトのものではなく指定したものになっているので、パラメーター自体は正しく渡っています。

WordPressコアのソースを見て直接の原因は分かりました。タグクラウドウィジェットで実際にタグクラウドを取得している部分はwp-includes/widgets/class-wp-widget-tag-cloud.php内の以下のコードで、ウィジェットのタイトルやラッパーを出力する前に記述があります。

$tag_cloud = wp_tag_cloud( apply_filters( 'widget_tag_cloud_args', array(
	'taxonomy' => $current_taxonomy,
	'echo' => false
) ) );

wp_tag_cloud関数は元々テーマ中でタグクラウドを出力する関数ですが、echoパラメーターをfalseにすることで出力せずに文字列として他の関数・変数に渡すことができます。一旦変数$tag_cloudに格納されたタグクラウドの文字列は、この後タイトルやラッパーの出力後にechoされるのですが、今回の乱れた出力では、ここの部分でタグクラウドの出力がされてしまって、その後の処理が行われていません。つまり、wp_tag_cloud関数の引数echoがデフォルトのtrueになってしまっているのです。私がfunction.php内で指定しているパラメーターもここで引数として渡されており、その場合に上のコードにあるechoの指定(false)が有効にならず、wp_tag_cloud関数のechoのデフォルト値であるtrueが有効になってしまい、出力されていたというわけです。

これは私のコードの書き方に問題があって、引数を全部自分のものに上書きしていたんですね。その際にechoは指定をしていなかったのでデフォルトの値が使われてしまっていました。正しくは、引数をマージしないといけなかったのです。

そんなわけで、function.php内の記述を以下のように書き換えることにより問題は解決しました。(以前は$my_argsではなく直接$argsとしていて、wp_parse_args関数も使わずそのまま返していました。)

function my_tag_cloud_args( $args ) {
	$my_args = array(
	// ここに自分が指定したいパラメーターを記述する。
	// (例)
	'format' => 'list',
	'orderby' => 'count'
	);
	$args = wp_parse_args( $args, $my_args );
	return $args;
}
add_filter( 'widget_tag_cloud_args', 'my_tag_cloud_args' );

アップグレードするまでは正しく動作していた(ように見えた)のは、以前のバージョンではwp_tag_cloud関数が直接出力に使われていたためです。私がpost_tagしかタグクラウドに使っていないためtaxonomyの引数してを無視してしまっていることも問題になりませんでした。

メジャーアップグレードの際にはこういった細かい変更がテーマや動作に影響を与えることが少なくありません。本当はいきなりアップグレードするのではなくローカル環境でチェックしてからの方がいいのは分かってるんですけどね。最初は原因が分からず戸惑いましたが、思ったより早く解決することができましたし、正しいカスタマイズ方法に修正できたので良しとしましょう。

アップグレードは慎重に

WordPress 3.4がリリースされたのでアップグレードしました。

いつものように自動更新をしたのですが、アップグレード時のトラブルに関する話を何件か目にしていたので、ローカルで問題ないことを確かめた上で、しっかりとファイルとデータベースのバックアップをとってからアップグレードに臨みました。慎重にやって正解でした。

3.1へのアップグレードの時と同様に、「データベースをアップグレードしています」のところで止まってしまいました。ずっと待っていてもどうにもならない感じだったので諦めて、バックアップから復元することにしました。まずはデータベースをダンプファイルから復元。しばらくしてからアクセスし、データベースを更新して管理画面に入ると上部にエラーメッセージがある、という流れは3.1でトラブルに遭った時と一緒です。前の時はもう一度自動更新(再インストール)を行うとうまく行ってエラーも消えたのですが、今回は再びデータベースアップグレードで止まってしまいました。何回か繰り返してみましたが、すべて止まってしまいます。

そんなわけで、再インストールを行う前に使用中のプラグインをすべて停止して、それから再インストールを行ってみました。すると今度は問題なく進んで、無事アップグレードできました。停止させたプラグインを再び有効化し、JetpackをWordPress.comと連携させて終了です。アップグレード時の不具合が報告されているキャッシュ系のプラグインは使ってないですし、一括で停止して進めたのでどのプラグインが問題だったかは分からずじまいですが、まあ結果オーライということで。

教訓としては、WordPressのアップグレードの前にはちゃんとバックアップをとっておきましょう、ということです。もし今回バックアップがなかったら危なかったです。あと、プラグインも停止してからアップグレードしたほうが無難です。

データベースの最適化

昨日の朝、突然このサイトへのアクセスが出来なくなりました。ブログも管理画面もだめです。サーバーの管理画面やphpMyAdminにはアクセスできたのですが。サーバーの不具合だろうと思い半日ほど放っておいたのですが、まったく復旧せず、サーバー自体の障害報告もありません。

サーバーの管理会社にサポートをお願いすると、すぐに対応していただき、サイトにアクセスできるようになりました。データベースの最適化をすることで修復できたようです。データベースのオーバーヘッドによりこのような状態が発生した可能性があるとのことで、参照URLとして提示されたのが、WordPress フォーラムのトピック

そういえば最近そんな話を読んだような気がするなぁ・・・と思ったら、先週末にみやびさんがブログ記事を書いてらっしゃいました

時々phpMyAdminにアクセスして最適化も行っていたのですが、いつの間に(というか一晩の間に)それほど大きなオーバーヘッドが発生していたのか不思議です。こんなことが頻繁に起こらないよう、みやびさんの記事に従って、自動で定期的に最適化を行うように設定することにしました。最適化だけでなくバックアップも行える、プラグイン(WP-DBmanager)を使った方法を採用しました。

書かれている手順に従ってインストール・設定(セーフモード対策も)しました。wp-adminとwp-cronをCGIモードで動かすことでパフォーマンスが落ちたりしないかちょっと気になりますが、しばらくこのまま様子を見ることにします。

テーマ更新とレスポンシブデザイン

1年強ぶりにテーマを更新しました。WordPress 3.2からのデフォルトテーマ、Twenty Elevenを参考に改変を加えてみました。

分かりやすい変更はヘッダー画像だと思います。これまでもランダムに(といっても2〜3種類だけですが)変わるようにしていましたが、サイドバーにも投稿画像のサムネイルをランダムにピックアップしていましたので、これらを統合しました。タイル状に並べた画像があまり多いとごちゃごちゃして嫌だったので、12枚までに抑えて、固定ページへのナビゲーションメニューを画像の右側に移しました。

フォントの大きさだとかコメントフォームだとか(Twenty Elevenのものそのまんま)ちょこちょこと変わってますが、もう一つの大きな変更は、Twenty Elevenのレスポンシブデザインを採用したことです。iPhoneなど表示領域の小さなデバイスで表示した際には見やすいようにレイアウトやサイズが変わります。上記ヘッダー画像の数もそれに応じて減るようになってます。

このレスポンシブデザインは手持ちのiPhone (4S, 3GS)、iPad (初代)で確認しながら作業していたのですが、どうしても思い通りにCSSが適用されずに苦労しました。その原因はWebkitのバグにあり、max-widthの値を実際の値より20pxほど大きく指定しなくてはなりませんでした。これからレスポンシブデザインを採用される方はご注意ください。

参考:レスポンシブ・ウェブデザインのMedia Queriesの設定と15px

自動下書きの怪・再び

WordPressで強制的に作成される自動下書きに投稿IDを無駄に消費されてしまうのが嫌で、その原因がクイック投稿にあることを突き止め、ダッシュボードでクイック投稿を非表示にする事で対処したということを、1年ほど前に書きました。(自動下書きの怪

ところが、WordPressを3.2.1にアップグレードしてから、再びこの自動下書きが作成されるようになってしまいました。以前はクイック投稿を非表示にしていればクイック投稿関連のスクリプトは実行されなかったのですが、WP3.2からはダッシュボードをロードするだけで表示・非表示に関わらず実行されるようになったみたいです。

こうなったらクイック投稿ウィジェット自体をダッシュボードから削除してしまうしかありません。「WordPressのダッシュボードカスタマイズ | Simple Colors」を参考にテーマのfunction.phpにコードを記述して対応しました。私が削除したいのはクイック投稿だけですから、ループ部分は簡略化しました。何回か試してうまくいっているので、おそらく大丈夫でしょう。

最近のWordPressは初心者でも気軽に投稿・簡単にカスタマイズできるようにウィジェットとか充実してきました。それはそれで良いのですが、必要としない機能はユーザーが簡単にオフにできて、コードやデータベースもなるべくシンプルに汚さないで欲しいなと思います。(このテーマも実は全くウィジェットは使わずコード直書きだったりします。)