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

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

WordPress 3.1とJetpack

WordPressを3.1にアップグレードしました。

今回もいつも通りに自動更新。これまで自動更新で何のトラブルもなかったのですが、今回初めて一発ではうまくいきませんでした。「データベースをアップグレードしています」で表示が止まったまま全然先に進まなかったのです。本来なら「WordPressの更新を完了しました」の表示が出て終了のはずなのですが。

しばらくはサイトも管理者ページもメンテナンス中の表示が出て全くどうしようもなかったのですが、ある程度放置した後に管理者ページに再アクセスしてみると、「データベースの更新をしてください」という表示が出ました。指示通りボタンを押してデータベースの更新を行うといつもの管理者ページに移動しました。使用中のバージョンの表示はきちんと3.1になっているものの、画面上部に正しく更新されていないとかなんとかいうエラーメッセージがでています(スクリーンショットを取っておけば良かったと後悔)。

試しにもう一度自動更新を行ってみると、今度はすんなりと更新が進み、エラーメッセージも消えて無事更新完了。

さて、3.1の新機能ですが、やはり目立つのは管理バーでしょうか。最初は必要ないかなと思っていたのですが、使ってみると意外と便利。このブログではテーマ内にログインとか管理者ページへのリンクとか表示していないので、サイトと管理画面を行き来するのに使ってます。

更新と同時にJetpackプラグインも導入しました。レンタルブログであるWordPress.comのいくつかの機能を、自分でホスティングサービスにインストールしたWordPressでも利用できるようにするプラグインで、以下の解説が詳しいです。

WordPress.com の便利機能をインストール版に! Jetpack を導入してみた | Odysseygate.com

私が実際に使っている機能は少しだけですが、結構気に入ってます。

WordPress.com Statsは以前から単独のプラグインで使用していました。WordPress.comのサイト統計情報の表示はずいぶん前に脱Flash化・棒グラフ化され、早くプラグイン版にもにも適用されないかと待っていたのですが、現在まで反映されず(iPhone/iPadからだとFlashは見れませんから)。Jetpackの登場でやっと解決です。

Gravater Hovercardもなかなか面白いですね。

Sharedaddyは使ってみようかと思いましたがやっぱりやめました。以前使っていて現在は外しているツイートボタンの、カウント数の非整合性がやはり気になるので。

Jetpackで気になるのは、個別の機能のオン・オフがちょっと分かりにくいのと、管理画面左のメニューでサイト統計情報へのリンクがダッシュボードの下からJetpackの下へ移動したため1クリック多く必要になったことでしょうか。今後どのような機能が追加されるか楽しみです(評価機能、アンケートあたりでしょうか)。

ツイートボタン

Twitter公式のツイートボタンができたということで、早速このブログにも設置してみました。各投稿の最後にある青いボタンがそれです。該投稿について簡単にTwitterでつぶやくことができます。

同様な機能を提供するプラグインはたくさんあります。Twitterへの通知に使っているプラグインSimple Tweetでも可能です。正直そちらのほうが今は使い勝手も良いのですが、「公式」というのと今後への期待料込みで、公式のボタンを設置してみました。

設置方法は、Twitterのツイートボタンページにアクセスして、デザイン等を選択した後、表示されているコードをブログに貼付けるだけ。WordPressの場合、使用しているテーマの該当箇所に貼付けることになりますが、そのうちプラグインで簡単に設置できるようになるでしょう。

デフォルトではボタンが表示されているページのURLとタイトルがツイート内に含まれることになります。WordPressのシングルページに設置する場合にはそれで全く問題ありませんが、インデックスページやアーカイブページに設置したい場合には、上記ページで表示されるコードを各テンプレートファイルのループ内に記述しただけでは困ったことになります。表示される複数の投稿のツイートボタンは、どれを押しても表示されているページのURLとタイトルをツイート内に含むことになってしまいます。思い通りの動作(各投稿のURLとタイトルをツイートに含める)にするには、ループ内に記述するコードを例えば以下のようにしてやれば良いです。

<a href="http://twitter.com/share"
    data-url="<?php the_permalink(); ?>"
    data-text="<?php the_title(); ?>"
    data-count="horizontal"
    data-lang="ja">Tweet</a>
<script type="text/javascript" src="http://platform.twitter.com/widgets.js"></script>

トップページやアーカイブページでは投稿の全文ではなく抜粋を表示している場合、ツイートボタンを表示するのは個別ページだけで良いでしょう。しかし、このブログのように全文を表示している場合、読者は個別ページに行かずにトップページだけを読むことの方が多いと思われますから、こうした細工をしてみました。

もう一つ注意点があります。ボタンの横または上にツイート数のカウントを表示することができ、この吹き出しをクリックするとTwitterのリアルタイム検索の結果に飛ぶようになっています。カウントが0以外になっているのに、クリックすると表示されるページでは0件になっている場合があります(投稿日現在、このブログではすべてこうなります)。ツイート数を取得する際は短縮URLでツイートされたものもカウントしているにも関わらず、リアルタイム検索では短縮URLでの投稿はヒットしないためだと考えられます。この辺は今後改善されることを期待します。