WordPress 2.7タグの投稿


コメントの入れ子に対応
当サイトはすでに WordPress 2.7 になっているわけですが、テーマファイルを調整して、コメントの入れ子に対応しました。これによって、各コメントに「返信する」リンクが付くようになりました。「返信する」リンクの直下にコメントフォームが出るという Ajax 化は面倒だったので、コメントフォームは画面最下部のを使うようにしています。
WordPress 2.7 で導入された、コメントの入れ子やページ分割に対応するのは実は簡単で、comments.php のコメントループを wp_list_comments()
関数に入れ替えるだけです。しかし、各コメントのフォーマットは、wp-includes/comment-template.php で定義された Walker_Comment
クラスによる画面出力になってしまいます。wp_list_comments()
の引数を調整することで、リスト方式を、ol, ul, div から選ぶことはできますが、名前→投稿日時→コメント内容という表示順序は決め打ちになります。これが気に入らなかったので、Walker_Comment
を使用中テーマの functions.php にコピーしてクラス名を変更し、中身を改造することにしました。こうすれば出力順序は思いのままです。そして、comments.php では wp_list_comments(array('walker' => new My_Walker_Comment))
のようにすれば、自作クラスを使うことができます。従来の comments.php よりは改造がしにくくなったと言えますが、入れ子を実装するためには Walker クラスが必要なので仕方ないですね。
[追記] よく調べると、Walker_Comment クラスをコピーする必要はありませんでした。Walker_Comment クラスの start_el()
メソッドの中身は、コールバック関数を指定して置き換えることが可能になっているからです。つまり、start_el()
メソッドの $GLOBALS['comment'] = $comment;
の行以降をテーマの functions.php で定義し、それへのコールバックを
wp_list_comments()
の callback 引数として与えればよいです。例えば、以下のような感じです。
functions my_list_comments($comment, $args, $depth) { $GLOBALS['comment'] = $comment; extract($args, EXTR_SKIP); if ( 'div' == $args['style'] ) { $tag = 'div'; $add_below = 'comment'; } else { $tag = 'li'; $add_below = 'div-comment'; } ?> <<?php echo $tag ?> <?php comment_class(empty( $args['has_children'] ) ? '' : 'parent') ?> id="comment-<?php comment_ID() ?>"> <?php if ( 'ul' == $args['style'] ) : ?> <div id="div-comment-<?php comment_ID() ?>"> <?php endif; ?> <div class="comment-author vcard"> <?php if ($args['avatar_size'] != 0) echo get_avatar( $comment, $args['avatar_size'] ); ?> <?php printf(__('<cite class="fn">%s</cite> <span class="says">says:</span>'), get_comment_author_link()) ?> </div> <?php if ($comment->comment_approved == '0') : ?> <em><?php _e('Your comment is awaiting moderation.') ?></em> <br /> <?php endif; ?> <div class="comment-meta commentmetadata"><a href="<?php echo htmlspecialchars( get_comment_link( $comment->comment_ID ) ) ?>"><?php printf(__('%1$s at %2$s'), get_comment_date(), get_comment_time()) ?></a><?php edit_comment_link(__('(Edit)'),' ','') ?></div> <?php comment_text() ?> <div class="reply"> <?php comment_reply_link(array_merge( $args, array('add_below' => $add_below, 'depth' => $depth, 'max_depth' => $args['max_depth']))) ?> </div> <?php if ( 'ul' == $args['style'] ) : ?> </div> <?php endif; ?> <?php }
テーマの comments.php では、以下のようにします。
if (function_exists('wp_list_comments')) { wp_list_comments(array('callback' => 'my_list_comments')); } else { /* 従来のコメント表示処理 */ }

WordPress 2.7 のカテゴリー/タグごと CSS 割り当て機能を修正する
新機能の問題点を指摘していた WordPress 2.7 ですが、さきほどリリースされてしまいました。trac のチケットを切ったり、WordPress 日本語フォーラムでトピックを作ったんですが、結局直されませんでした……。やっぱり「WordPress 開発者の I18N 対応は優先度が低い」と言えます。これらの改善のためには、英語以外のユーザーが増えてもっと口出ししなければなりません。
さて、嘆いていても進まないので、とりあえず改善用プラグインを作ってみました。詳細は日本語フォーラムを見てもらうとして、ここでは改善コードを出しておきましょう (スラッグを URL デコードする、という仕組みです)。以下のコードを新規テキストファイルにコピー & ペーストして適当な名前 (fix-post_class.php など) で保存し、WordPress のプラグインディレクトリーにアップロードすれば OK です。WordPress 2.7 では、zip ファイルにしておけばインストールが簡単なんですが、「あえて敷居を高くする」ということで、このままにしておきます
<?php /* Plugin Name: Fix Post Class Plugin URI: http://www.yuriko.net/arc/2008/12/11/fix-post_class/ Description: Use url-decoded CSS class names for assigned categories/tags of each post with WordPress 2.7 Version: 1.0.0 Author: IKEDA yuriko Author URI: http://www.yuriko.net/cat/wordpress/ */ /* Copyright (c) 2008 yuriko This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ function fix_post_class($classes, $class, $post_id) { $num_classes = count($classes); if ($num_classes < 1) { return $classes; } for ($i = 0 ; $i < $num_classes ; $i++) { if (strpos($classes[$i], '%') !== 0) { $classes[$i] = preg_replace('/[^-_0-9a-zA-Z\x80-\xff]/', '', urldecode($classes[$i])); } } return $classes; } add_filter('post_class', 'fix_post_class', 99, 3); ?>
[追記] 日本語フォーラムでの議論では、XHTML 1.0 の場合は「WordPress 2.7 の実装は問題ないが、style.css の方では % 記号をバックスラッシュでエスケープする必要がある」「上記プラグインによる Unicode 化も正しい方法である」(可読性ではこちらが上) となります。しかし、XHTML 1.1 では、% 記号に加え、Unicode 文字列が不可となるため、WordPress の実装自体 NG となります (上記プラグインの解決方法もだめ)。XHTML 1.1 は class 属性の部分が NMTOKENS になったのですが、NMTOKES は英数字だけじゃなくて Unicode の文字列も含まれるため、日本語でも OK です。つまり、上記プラグインは XHTML 1.1 でも使えます。post_class()
関数は、XHTML 1.1 の出力かどうかで動作を変える必要があるわけです。上記プラグインは、XHTML 1.0 でのみ使ってください。

WordPress 本家開発者の I18N 軽視はどうにかならんか
現在開発中の WordPress 2.7 ですが、新機能として「投稿表示部分を囲む div 要素に、属するカテゴリーごとの class 指定ができる」というものがあります。例えば、mobile カテゴリーの投稿ならば、div class="category-mobile"
という div 要素で囲まれます。これ自体はデザインの多様化が図れて歓迎されることなんですが、その実装があまりに国際化や HTML/CSS 仕様を無視したもので、泣けてきます。
この機能は、Changeset 8641 にて post_class()
関数を増強する形で追加されました。コード (下に引用) を見ると分かりますが、”category-XXXX” の XXXX の部分は、カテゴリースラッグそのままです。ところが、カテゴリースラッグに使える文字と、class 指定に使える文字の範囲が異なるため、このままでは XHTML および CSS 違反になってしまいます。カテゴリー名が英数字だけならば、スラッグは a-z, 0-9, – (ハイフン), _ (アンダースコア) だけになるため問題ありません。しかし、カテゴリー名に Unicode 文字 (日本語等) を使うと、スラッグは %nn という URL エンコードした形式になります。しかし、class 名には % 記号は使えないのです!! 現在のコードでは、class 名に % 記号を含んだものになってしまいます (「携帯」カテゴリーならば “category-%e6%90%ba%e5%b8%af” となってしまう)。
186 // Categories 187 foreach ( (array) get_the_category($post->ID) as $cat ) { 188 if ( empty($cat->slug ) ) 189 continue; 190 $classes[] = 'category-' . $cat->slug; 191 } 192 193 // Tags 194 foreach ( (array) get_the_tags($post->ID) as $tag ) { 195 if ( empty($tag->slug ) ) 196 continue; 197 $classes[] = 'tag-' . $tag->slug; 198 }
今までも、WordPress 開発者は、I18N (国際化対応) がいい加減だと思っていましたが、今回もまた配慮が足りません……。早々にチケットを切らないといけませんが、対応策としては「カテゴリー ID を使う」ぐらいしか思い浮びません。スラッグから % 記号を抜いたもの、とか、% を _ に変化させたもの、を使うのはいまいちだと思いますし。実は class 名には「ASCII 以外の Unicode 文字」が使えるため「category-携帯」という出力でよかったりするんですが、既存のウェブブラウザーがそういう記述を認識するのかは疑問なので、「スラッグではなくカテゴリー名そのものを使う」という変更が有効なのかは疑問です……。
[追記] いい加減な英語でチケット#8446を切りました。結局、解決策としては、バックスラッシュで % 記号をエスケープするか、カテゴリー ID を使うかどちらか、ということにしました。カテゴリー名そのものを使うのは、ASCII 記号が含まれている場合によくないので没としました。
さきほど発表された WordPress 2.7 RC1 でも直っていませんでした……。チケットは切ってあるので、RC2 あたりで直してもらえることを期待しましょう。

WordPress 2.7 ベータ版を試す
遅ればせながら WordPress 2.7 ベータ版を試しました。管理パネルのデザインがまたも一新されています。今度は左側にサイドバーにできてメニューが縦に並ぶようになりました。AJAX を活用して、サブメニューの項目にアクセスしやすくなっています。
残念な点として、Mac 版 Safari では、メニュー最上部の「ダッシュボード」という文字が1行ではなく2行に渡ってしまっています。横幅を少し広げればいいはずなので、管理パネル用のスタイルシートの調整が必要ですね。
あと、ローカライズに不具合があって、「コメント編集」画面に英語が残ってしまっています。これはソースコードと日本語リソースの両方の問題なので、なかなかやっかいです。
とりあえず、Ktai Style の動作を確認してみたところ、携帯閲覧部分は問題ないものの、管理機能はところどころ英語が残っていました。つまり、ローカライズ対象の文字列が変更になったということです。これについては、WordPress のバージョンを判別して、それによって使う文字列を切り替えばいいでしょう。記事の作成や編集はとりあえず動いてるっぽいですが、さらなる確認が必要だと思われます。つまり、Ktai Style の WordPress 2.7 対応は微調整で済みそうです。
Ktai Entry など他のプラグインはこれから確認しますが、おそらく問題なく動作するものがほとんどでしょう。
[追記] Ktai Style の CVS に WP 2.7 beta2 暫定対応版をコミットしました。上記「Approved」関連の不具合があるので、携帯版のコメント編集画面でも、英語が残ってしまっています。また、WordPress 2.6 以前でのチェックが非常に甘いので、逆に (表示上の) 不具合が出ているかもしれません……。
過去のコメントを入れ子にする
カテゴリー: WordPressハック
タグ: WordPress 2.7, コメント
WordPress 2.7 からコメントの入れ子 (スレッド) 表示が可能となりました。以前、テーマを改造して表示に対応したのですが、今回、データベースをいじって、過去のコメントについても入れ子表示させるようにしました。
やり方は、wp_comments テーブルに対して「返信コメントならば comment_parent カラムに親コメントの comment_ID を入れる」という修正を行います。phpMyAdmin ならば、複数のフィールドを修正できるので比較的ラクですが、1つの投稿に対して数10ものコメントが付いてて、親子関係が入り組んでいると、ちょっとやっかいです。ときどき、複数のコメントに対してまとめて回答しているときがあって、そのときは親子関係を定義できませんし……。
当サイトはコメントが 733 件もあるので、なかなか作業が進んでいません。今のところ、2008年8月以降のみ対応しました。少しずつ古いコメントにさかのぼって対応していきたいと思います。
[追記] 2008年4月1日以降の記事に対するコメントを修正しました。以前は独自ウェブログシステムでのコメントのため、入れ子にしなくてもいいかな、という気がします
自作プラグインに対するコメントだと、質問→回答の入れ子がすごく、ディスカッション設定で8階層まで OK にしないと、きちんとネストされませんでした。