今から遡ること、およそ3ヶ月。高野直子さんのJetpack 対応の公式 Send to Kindle プラグインを追加してみたという記事を読んだところまではよかったのですが、何故か自分の環境でのみ正常に動作しないということが判明。
どうやらJetpack側に問題がないことまでは特定。Amazonに不満を書き連ねたメールを送り続けようかとも考えましたが、面倒だし、そこまで必要性もなかったので放置していました。
一部のマルチサイトでは使えない…だと?
WordPress.orgのフォーラムで偶然にもこんな投稿を見つけました。
WordPress › Support » Add To Jetpack Sharing
不具合の原因が切り分けられないでいたのですが、Send to Kindleの実装の問題だったようです。Jetpackとの連携のためのソースコードの記述に不備があるようです。
編集する箇所はjetpack.phpの19行目だけです。
$share_plugin = preg_grep( '/\/jetpack\.php$/i', wp_get_active_and_valid_plugins() ); if ( 1 === count( $share_plugin ) ) { // There is absolutely no reason why more than one result should appear, but // let's assume a correct search will only have one match. if ( ! class_exists( 'Sharing_Source' ) ) { include_once( preg_replace( '/jetpack\.php$/i', 'modules/sharedaddy/sharing-sources.php', reset( $share_plugin ) ) ); } add_filter( 'sharing_services', array( 'Share_Kindle', 'inject_service' ) ); add_action( 'admin_notices', array( 'Share_Kindle', 'jetpack_message') ); } else { // Nothing to see here, move along. return; } {以下省略}
19行目で使用しているwp_get_active_and_valid_plugins関数はWordPressの定義したユーザ定義関数ですがマルチサイトには使えません。
$share_plugin = wp_get_active_and_valid_plugins(); if ( is_multisite() ) { $share_plugin = array_unique( array_merge($share_plugin, wp_get_active_network_plugins() ) ); } $share_plugin = preg_grep( '/\/jetpack\.php$/i', $share_plugin );
- 20行目でマルチサイトであるかどうかの条件判定をしています。
- 21行目ではwp_get_active_network_plugins関数でネットワークで有効な(≒マルチサイトで有効な)プラグインの配列を取得し、array_mergeで配列を単一のブログでのみ有効なプラグインの配列と統合しています。
PHPを多少ご存知の方ならif~else構文を用いていないのを不思議に思うかもしれませんが、Jetpackがどちら(単一のブログorマルチサイト)の上で有効になっているかが分かりませんから、両方のデータを参照し、確認する必要があります。
この場合、どちらで有効になっているかを特定する必要がありませんから、2つの配列を統合してpreg_grepによる検索処理をより少ないステップ数で行う様な実装が最適といえます。
※Jetpackを無効にすることがないと言い切れるのであれば19行目を”$share_plugin[] = NULL;”に置き換えれば済む話です。さらに言うのであれば、19,20,29~32行目を削除すれば終わりです。推奨はしませんが。
とりあえず、マルチサイト環境下で不具合が起きることがある現象の応急処置は完了で、作者が早々に修正してくれることを祈るばかりですが、もう一つバグがありましたので修正していきましょう。
日本語化ができない!
問題はマルチサイト周りだけかと思いきや、多言語化の実装にも不具合が。とっても意味不明な実装をしてくれています。
ソースコードは長いので公式Subversionで確認してください。
load_text_domainという関数の実行をplugins_loadedのタイミングに指定しているようですが、この時点ですでに__construct関数の実行は完了しています。それでは遅いんです。多言語化関連の設定はそれより早いタイミングで行う必要があります。つ・ま・り、翻訳ファイルをいくら作っても適用されることはありません。
実装したはいいけど、自分が使わないからテストしないというよくあるパターンでしょう。こちらについても修正していきます。
private function __construct() { // Set up sensible defaults. add_option( 'stk_button_look', array( // placement 'home' => true, 'archive' => true, 'post' => true, 'page' => false, 'before' => false, 'after' => false, // button style 'color' => 'white', 'size' => 'small', 'border' => true, 'theme' => 'light', // button text 'text' => 'send-to-kindle', 'font' => 'sans-serif', ) ); add_option( 'stk_button_advanced', array( 'selectors' => array( 'title' => '.entry-title', 'published' => '.entry-date', 'content' => '.post', 'exclude' => '.sharedaddy', ), 'enabled' => false, 'markup' => '<div class="kindleWidget">Kindle</div>', ) ); // Register actions and filters. add_action( 'plugins_loaded', array( $this, 'load_l18n' ) ); add_shortcode( 'sendtokindle', array( $this, 'get_button_html' ) ); add_filter( 'the_content', array( $this, 'attach_to_content' ) ); add_filter( 'get_the_excerpt', array( $this, 'clean_the_excerpt' ) ); add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_script' ) ); if ( is_admin() ) { // Only load settings screens for admins. add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), array( $this, 'settings_link' ) ); if ( ! class_exists( 'STK_Settings' ) ) { include_once( dirname( __FILE__ ) . '/admin/settings.php' ); } if ( ! class_exists( 'STK_Settings_Advanced' ) ) { include_once( dirname( __FILE__ ) . '/admin/settings-advanced.php' ); } $settings = STK_Settings::get_instance(); $advanced_settings = STK_Settings_Advanced::get_instance(); } }
42~91行目までを以下で置き換えてください。
private function __construct() { load_plugin_textdomain( "kindle", false, dirname( plugin_basename( __FILE__ ) ) . '/languages/'); // Set up sensible defaults. add_option( 'stk_button_look', array( // placement 'home' => true, 'archive' => true, 'post' => true, 'page' => false, 'before' => false, 'after' => false, // button style 'color' => 'white', 'size' => 'small', 'border' => true, 'theme' => 'light', // button text 'text' => 'send-to-kindle', 'font' => 'sans-serif', ) ); add_option( 'stk_button_advanced', array( 'selectors' => array( 'title' => '.entry-title', 'published' => '.entry-date', 'content' => '.post', 'exclude' => '.sharedaddy', ), 'enabled' => false, 'markup' => '<div class="kindleWidget">Kindle</div>', ) ); // Register actions and filters. add_shortcode( 'sendtokindle', array( $this, 'get_button_html' ) ); add_filter( 'the_content', array( $this, 'attach_to_content' ) ); add_filter( 'get_the_excerpt', array( $this, 'clean_the_excerpt' ) ); add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_script' ) ); if ( is_admin() ) { // Only load settings screens for admins. add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), array( $this, 'settings_link' ) ); if ( ! class_exists( 'STK_Settings' ) ) { include_once( dirname( __FILE__ ) . '/admin/settings.php' ); } if ( ! class_exists( 'STK_Settings_Advanced' ) ) { include_once( dirname( __FILE__ ) . '/admin/settings-advanced.php' ); } $settings = STK_Settings::get_instance(); $advanced_settings = STK_Settings_Advanced::get_instance(); } }
243~252行目までは不要ですから削除しましょう。
/** * Loads the localized MO for translating strings. * * @uses load_plugin_textdomain */ public function load_l18n() { $textdomain = function_exists( 'wpcom_is_vip' ) ? 'default' : 'kindle'; load_plugin_textdomain( $textdomain, false, basename( dirname( __FILE__ ) ) ) . '/languages/'; }
これで/path/to/your/wordpress/wp-content/plugins/send-to-kindle/languages/にkindle-ja.moファイルを置けば日本語で表示されます。
これ全部やるのメンドー…
そんなこともあろうかと、こちらでパッケージ化したものを用意しました。すでにあるプラグインを削除してから、WordPress管理画面の「プラグイン」から「新規追加」、「アップロード」と進んでインストールして下さい。
Send to Kindle 1.0.3-customized(43.3KB)
Subversionにおいてあったリリース前のファイルを見る限り、多言語化については次期バージョンで修正が入るようです。Jetpackとの連携については
何かあったら「Contact」からお願いします!
たぶん1週間ぐらい忙しいので、色々とSNSにも出てくる頻度が多少減るかとは思いますが、次回は「WordPress 10周年記念」について書こうと思います。
では!