2007年12月31日の投稿

2007-12-31
晴れ

WordPress のコメント投稿エラーを入力フォームと一緒に出す方法

ゆりこ による 11:49:05 の投稿
カテゴリー: WordPressハック

WordPress でコメント投稿時のエラー表示は別ウィンドウに遷移し、元の画面に戻るにはブラウザーの戻るボタンが必要です。これはユーザビリティー的に非常に不親切です (ブラウザーによっては入力した内容が復活せず白紙に戻ることがある!!)。そこで、Yuriko.Net 旅行記 では、なんとか、エラー表示をコメント投稿フォームの中に埋め込んだ形で表示するよう改善しました。コメント本文、名前など必須項目を入れ忘れても、エラーがコメントフォームの上に出てくるので、そのままやり直しできます。こちらでは、その方法の詳細を記載しておきます。

まず、テーマの comments.php を改造して、エラーメッセージや入力中の名前・コメント本文を表示させるようにします。default テーマ (kubrick) の場合、以下のようにします。XSS 対策のため、$comment_author などの表示に wp_specialchars(), attribute_escape()を使うように修正しています。

<h3 id="respond"><?php _e('Leave a Reply', 'kubrick'); ?></h3>
<?php if ( get_option('comment_registration') && !$user_ID ) : ?>
<p><?php printf(__('You must be <a href="%s">logged in</a> to post a comment.', 'kubrick'), 
get_option('siteurl') . '/wp-login.php?redirect_to=' . urlencode(get_permalink())); ?></p>
<?php else : ?>
<?php	global $yn_commentdata;
	if (isset($yn_commentdata['message']) && $yn_commentdata['message']) {
		$comment_author       = $yn_commentdata['author'];
		$comment_author_email = $yn_commentdata['email'];
		$comment_author_url   = $yn_commentdata['url'];
		$comment_content      = $yn_commentdata['content'];
?><p><font color="red"><?php echo wp_specialchars($yn_commentdata['message']); ?></font></p><?php 
	} ?>
<form action="<?php echo get_option('siteurl'); ?>/wp-comments-post.php#respond" method="post" id="commentform">
<?php if ( $user_ID ) : ?>
<p><?php printf(__('Logged in as <a href="%1$s">%2$s</a>.', 'kubrick'), get_option('siteurl') . '/wp-admin/profile.php', 
wp_specialchars($user_identity)); ?> <a href="<?php echo get_option('siteurl'); ?>/wp-login.php?action=logout" 
title="<?php _e('Log out of this account', 'kubrick'); ?>"><?php _e('Logout »', 'kubrick'); ?></a></p>
<?php else : ?>
<p><input type="text" name="author" id="author" value="<?php echo attribute_escape($comment_author); ?>" size="22" tabindex="1" />
<label for="author"><small><?php _e('Name', 'kubrick'); ?> <?php if ($req) _e("(required)", "kubrick"); ?></small></label></p>
<p><input type="text" name="email" id="email" value="<?php echo attribute_escape($comment_author_email); ?>" size="22" tabindex="2" />
<label for="email"><small><?php _e('Mail (will not be published)', 'kubrick'); ?> <?php if ($req) _e("(required)", "kubrick"); ?></small></label></p>
<p><input type="text" name="url" id="url" value="<?php echo attribute_escape($comment_author_url); ?>" size="22" tabindex="3" />
<label for="url"><small><?php _e('Website', 'kubrick'); ?></small></label></p>
<?php endif; ?>
<!--<p><small><?php printf(__('<strong>XHTML:</strong> You can use these tags: <code>%s</code>', 'kubrick'), allowed_tags()); ?></small></p>-->
<p><textarea name="comment" id="comment" cols="100%" rows="10" tabindex="4"><?php echo wp_specialchars($comment_content); ?></textarea></p>
<p><input name="submit" type="submit" id="submit" tabindex="5" value="<?php _e('Submit Comment', 'kubrick'); ?>" />

次は、wp-comments-post.php を改造します。51行目から59行目からの wp_die() を、自作の関数に振り分けます。それ以外の wp_die() は別エラー画面で問題ないためそのままです。

if ( get_option('require_name_email') && !$user->ID ) {
	if ( 6 > strlen($comment_author_email) || '' == $comment_author )
		yn_comment_form( __('Error: please fill the required fields (name, email).') );
	elseif ( !is_email($comment_author_email))
		yn_comment_form( __('Error: please enter a valid email address.') );
}
if ( '' == $comment_content )
	yn_comment_form( __('Error: please type a comment.') );

そして、末尾に以下の関数を記述します。念のため、元からある wp_redirect() のあとに exit() を書いておきます。この関数は、コメント投稿エラー時にむりやりコメント投稿フォームを呼び出すものです。require_once(ABSPATH . WPINC . '/template-loader.php'); ではうまく動かなかったため、single.php または index.php を直接読み込みようにしています。このため、テーマによってはうまく動かないかもしれません。

wp_redirect($location);
exit;

/* ==================================================
 * @param	string  $message
 * @return	none
 */
function yn_comment_form($message) {
	global $yn_commentdata, $withcomments, $comment_post_ID, $comment_author, 
	$comment_author_email, $comment_author_url, $comment_content;
	$yn_commentdata['author']  = $comment_author;
	$yn_commentdata['email']   = $comment_author_email;
	$yn_commentdata['url']     = $comment_author_url;
	$yn_commentdata['content'] = $comment_content;
	$yn_commentdata['message'] = $message;
	unset($_POST['author']);
	unset($_POST['email']);
	unset($_POST['url']);
	unset($_POST['comment']);
	define('WP_USE_THEMES', true);
	wp("p=$comment_post_ID");
	$withcomments = TRUE;
	if ($template = get_single_template()) {
		include $template;  
	} else {
		include(TEMPLATEPATH . "/index.php");
	}
	exit;
}
?>

[追記] wp-comments-post.php には不具合があったので、赤字部分を修正いたしました。

紅白のトリは実質SMAP

ゆりこ による 23:48:12 の投稿
カテゴリー: テレビ・メディア,音楽
タグ: , ,

今年の紅白歌合戦は、五木ひろしの「契り」がトリというのはどうかと思っていましたが、そのあと、全員で SMAP の「世界に一つだけの花」を合唱する、という演出が用意されていました。とはいえ、声が流れるのは SMAP と槇原敬之だけなので、実質、「トリがSMAP」という状態でした ;-) 今年の SMAP は新曲が1つだけという寂しい状態なのでトリを務めるのは無理がありましたが、来年あたりは大トリにしてもいいんじゃないかと……。