个性化 WordPress 评论框

对大多数人而言,WordPress 的评论框(留言表单)也许没有多少需要自定义的地方。我恰好想在提交评论按钮前面加一段话,顺便参考别的资料总结一下。

文中介绍的方法和代码基于 WordPress 3.3.1,至于以后会不会根据更新情况修改,这个很难说。如果有修改,会在文后说明。阅读此文需要对 PHP 有一点点了解,另外还需要知道 WordPress 主题的构建方法。嗯,实际上一般用法只需要依葫芦画瓢即可。

0. 此文涵盖的内容

文中介绍的方法仅仅是修改 WordPress 默认的评论框内容,也就是默认已有定义的那些元素,不会增加新的域或按钮。仅仅是“修改”,而不是“重建”。所用方法基于 WordPress Codex 中 comment_form  一节的参数和 filter。

1. 背景

文中的方法分为两种:a. 修改参数; b. 使用 filter。涉及到的文件都在 theme 文件夹中(位于 /wp-content/theme/ 目录)。每种方法只涉及到一个特定的文件。这样就不需要修改 WordPress 核心文件了,那样会很麻烦:每次升级 WordPress 都需要重新修改,而且容易引起错误。

前一种方法只涉及到 comments.php 文件。大多数主题都会有这个文件。虽然并不是一定要有 comments.php 文件,只不过这是 WordPress 推荐的方式。

第二种方法只需要修改 functions.php 文件。同样的,大多数主题都会有这个文件。主题自定义的功能都在这个文件中。与上面不同的是,如果你的主题中没有这个文件,你可以自己创建一个。

2. 评论框简史

在版本 3 之前,整个 WordPress 评论框的全部代码都是在主题的 comments.php 文件中的。这使得修改它非常的方便。不过带来的问题就是让主题看起来有些乱。

开发人员也注意到了这个问题,然后从 WordPrss 3 开始,评论框就被精简为一个函数了,直接在主题的相应位置调用此函数:

<?php comment_form(); ?>

从此,基本上所有的主题都会直接使用此函数生成默认的评论框,顶多就是在 CSS 样式定义上各有各的风格。一切变得极其简洁。

然而问题也随之而来:如果有人想要改变评论框,那就需要多动动脑子了。

3. 两种方法

有两种方法可以对评论框进行自定义,能完成的任务也一样。要采用哪一种方法一方面看你要干什么,另一方面就看个人的喜好了。

注意:方法 2 是我个人非常推荐的方法,会覆盖掉方法 1。

方法 1: 在 comments.php 中更改 COMMENT_FORM() 调用

这个方法用于以下场景是比较合适的:

  • 修改评论框的所有细节
  • 修改评论框中各字段(field)的标记,包括标签(label)
  • 其实,要完成想我开头提到的那种修改目的,这个方法也是很好的

这个方法是通过给通常的评论框函数调用

<?php comment_form(); ?>

增加一些细节来实现修改的。这些细节通过参数来传递给该函数。要改变什么细节,就指定相应的参数。例如:

<?php comment_form( $args, $post_id ); >

其中,

  • $args:可选,是一个数组(array()),包含用于评论框的字符串和字段等的配置内容,如果不写该参数,就使用默认的(见下面);
  • $post_id:可选,指定要在 ID 为 $post_id 的文章下产生该评论框,如果不写该参数,就会使用当前文章的 ID(即在每篇文章下产生该文章的评论框)

以类似下面的形式定义上面的参数 $args 数组 array() :

$args = array(
        'parameter_name' => 'value',
        'another_parameter' => 'value'
    ));

默认的参数数组内容如下(via):

$args = array(
	'id_form' => 'commentform',
	'id_submit' => 'submit',
	'title_reply' => __( 'Leave a Reply' ),
	'title_reply_to' => __( 'Leave a Reply to %s' ),
	'cancel_reply_link' => __( 'Cancel Reply' ),
	'label_submit' => __( 'Post Comment' ),
	'comment_field' => '<p><label for="comment">' . _x( 'Comment', 'noun' ) . '</label><textarea id="comment" name="comment" cols="45" rows="8" aria-required="true"></textarea></p>',
	'must_log_in' => '<p>' .  sprintf( __( 'You must be <a href="%s">logged in</a> to post a comment.' ), wp_login_url( apply_filters( 'the_permalink', get_permalink( ) ) ) ) . '</p>',
	'logged_in_as' => '<p>' . sprintf( __( 'Logged in as <a href="%1$s">%2$s</a>. <a href="%3$s" title="Log out of this account">Log out?</a>' ), admin_url( 'profile.php' ), $user_identity, wp_logout_url( apply_filters( 'the_permalink', get_permalink( ) ) ) ) . '</p>',
	'comment_notes_before' => '<p>' . __( 'Your email address will not be published.' ) . ( $req ? $required_text : '' ) . '</p>',
	'comment_notes_after' => '<p>' . sprintf( __( 'You may use these <abbr title="HyperText Markup Language">HTML</abbr> tags and attributes: %s' ), ' <code>' . allowed_tags() . '</code>' ) . '</p>',
	'fields' => apply_filters( 'comment_form_default_fields', array(
		'author' => '<p>' . '<label for="author">' . __( 'Name', 'domainreference' ) . '</label> ' . ( $req ? '<span>*</span>' : '' ) . '<input id="author" name="author" type="text" value="' . esc_attr( $commenter['comment_author'] ) . '" size="30"' . $aria_req . ' /></p>',
		'email' => '<p><label for="email">' . __( 'Email', 'domainreference' ) . '</label> ' . ( $req ? '<span>*</span>' : '' ) . '<input id="email" name="email" type="text" value="' . esc_attr(  $commenter['comment_author_email'] ) . '" size="30"' . $aria_req . ' /></p>',
		'url' => '<p><label for="url">' . __( 'Website', 'domainreference' ) . '</label>' . '<input id="url" name="url" type="text" value="' . esc_attr( $commenter['comment_author_url'] ) . '" size="30" /></p>' ) ) );

能够使用的参数基本上包括了评论框的各个方面的细节。WordPress Codex entry on comment_form() 中对可用的参数有较为全面的介绍,并指明了参数的默认值(也就是不做修改时的样子)。

省事的话,也可以不定义参数数组 $args = array(…,而是直接将要修改的某个参数放在数组里直接调用。如下面的例子。

例如,默认情况下,在评论框的下面有一行字提示用户可以在评论时使用某些 HTML 代码,存储这些提示文字的参数是 comment_notes_after。想修改为别的提示,比如指向网站上某个说明页面的链接(如隐私政策页面),就可以直接将原始函数调用改为:

<?php comment_form(array(
        'comment_notes_after' => '<p>请访问我们的 <a href="privacy.html">隐私政策</a> 页面。</p>'
    ));
?>

再例如,可以通过下面的形式,将默认的评论框标题 Leave a Reply 改写为别的,甚至可以是中文字符:

<?php comment_form(array('title_reply'=>'雁过留声,人过留名')); ?>

如果需要设置多个参数,需要在每个参数后面使用英文半角的逗号( , )隔开(最后一个参数后除外)。

如果要修改评论框的字段( fields )就稍微麻烦一些(此类应用建议使用下面的方法 2)。需要在上面参数数组 array 的里面创建一个字段数组(下面例子中将其命名为(赋值给) $fields ),然后通过 filter 来调用它。新数组 $fields 将被 ‘fields’ 参数调用。下面的例子中在 $fields 数组中指定了 author 字段的内容(包含了显示它所需要的所有 HTML 代码):

<?php comment_form(array(
        $fields = array(
            'author' => '<p>' . '<label for="author">' . __( 'Your Name' ) . '</label><input id="author" name="author" type="text"  value="Your First and Last Name" size="30"' . $aria_req . ' /></p>'
            );
    ));
?>  

这样就可以更加精细地控制评论框中“作者”(author)的显示方式。上例中将默认的标签 “Name” 改成了 “Your Name”,并将默认值(value)设置成了“Your First and Last Name”。现在只需要在参数数组 array 中调用该字段定义即可:

<?php comment_form(array(
        $fields = array(
            'author' => '<p>' . '<label for="author">' . __( 'Your Name' ) . '</label><input id="author" name="author" type="text"  value="Your First and Last Name" size="30"' . $aria_req . ' /></p>'
            );

        'fields'              => apply_filters( 'comment_form_default_fields', $fields ), 
        'comment_notes_after' => '<p>请访问我们的 <a href="privacy.html">隐私政策</a> 页面。</p>'
    ));
?>

其中的一句:

apply_filters( 'comment_form_default_fields', $fields )

就是告诉 WordPress 要使用你提供的代码(这里使用 $fields 变量来定义)来替换评论框的默认字段 comment_form_default_fields。需要注意的是,上面的代码中 $fields 里只定义了 author 字段,所以如果你将上面的代码应用到自己的主题的话,评论框显示出来就只有“姓名”那个栏目了。当然,你也可以比照这个例子继续编写其它字段,email(邮件地址)和 url(网站地址)的代码。

这里给个直接修改参数形式的,稍作修改的评论框三个字段的修改代码,其中按照 HTML5 的建议增加了 placeholder

comment_form(
    array(
        'fields' => array(
            'author' => '<p class="comment-form-author"><label for="author">昵称</label> <span class="required">*</span><input type="text" placeholder="姓名或昵称" aria-required="true" size="30" value="' . esc_attr( $commenter['comment_author'] ) . '" name="author" id="author"></p>',
            'email' => '<p class="comment-form-email"><label for="email">邮箱</label> <span class="required">*</span><input type="text" placeholder="电子邮件地址" aria-required="true" size="30" value="' . esc_attr( $commenter['comment_author_email'] ) . '" name="email" id="email"></p>',
            'url' => '<p class="comment-form-url"><label for="url">站点</label><input type="text" placeholder="个人主页网址" size="30" value="'.$comment_author_url.'" name="url" id="url"></p>'
            )
        )
 );

方法 2: 在 functions.php 中使用 HOOK FILTER

这种方法比较适合于

  • 省略或改写字段(姓名、邮件、网址)
  • 当你想使用更加贴近核心也是最彻底的方法的时候

该方法采用 WordPress 的滤器(filters)来实现。使用 filter,可以在评论框最后输出之前对其进行修改(所以会覆盖掉在 comments.php 中的修改)。

这个就需要在主题的 functions.php 文件中操作了。将编写的代码放到 functions.php 文件的结尾即可(如果结尾有 ?>,则应放在 ?> 之前)。

如果你的主题没有 functions.php 文件,自己创建一个就行了(简单的 Windows 记事本程序就可以操作了),但是要注意的是,自己创建的时候应该先在该文档中输入下面的代码做为开头,

<?php 

然后另起一行输入自定义的代码。先创建一个函数(function)来定义需要进行的操作。不过似乎只能用来操作(修改显示方式等)字段(fields),比如三个输入内容 author(姓名)、email(电邮)和 url(网址)。

例如,移除某字段:

add_filter('comment_form_default_fields', 'mytheme_remove_commentform_fields');
function mytheme_remove_commentform_fields($fields){
    $fields['email'] = '';  // 后面的参数留空表示移除 email 字段
    $fields['url'] = '';  // 移除 website 字段
    return $fields;
}

程序的名称就随意啦,只要保证上面一行 add_filter 中调用的与之一致就行了。

再比如修改 author 字段的形式:

function alter_comment_form_fields($fields){
    $fields['author'] = '<p>' . '<label for="author">' . __( 'Your name, please' ) . '</label> ' . ( $req ? '<span>*</span>' : '' ) .
                    '<input id="author" name="author" type="text" placeholder="John Smith" value="' . esc_attr( $commenter['comment_author'] ) . '" size="30"' . $aria_req . ' /></p>';
    $fields['email'] = '';  // 移除 email 字段
    $fields['url'] = '';  // 移除 website 字段

    return $fields;
}

需要注意的是,如果要修改某个字段,必须将该字段相关的所有部分 —— 标签、输入框等 —— 都定义在里面,否则……自己看看就知道了。

实际上也可以通过挂钩 filter 来增加新的字段。只不过,如果没有相应的 WordPress 数据库操作,新加的字段并不会存储到数据库中,只能是个摆设。新加字段的方法是:

function my_fields($fields) {
     $fields['new'] = '<p class="comment-form-new"><label for="new">新字段'</label> ' . ( $req ? '<span class="required">*</span>' : '' ) . '<input id="new" name="new" size="30" type="text" value="' . esc_attr( $commenter['comment_author_new'] ) . '" /></p>'; 
    return $fields; 
}
add_filter('comment_form_default_fields','my_fields');

这里给个采用 filter 方式的,稍作修改的评论框三个字段的修改代码,与前面参数传递方式那个实现的操作是一模一样的,只不过这个要用在 functions.php 文件里头。

function alter_comment_form_fields($fields){
    $fields['author'] = '<p class="comment-form-author"><label for="author">昵称</label> <span class="required">*</span><input type="text" placeholder="姓名或昵称" aria-required="true" size="30" value="' . esc_attr( $commenter['comment_author'] ) . '" name="author" id="author"></p>';
    $fields['email'] = '<p class="comment-form-email"><label for="email">邮箱</label> <span class="required">*</span><input type="text" placeholder="电子邮件地址" aria-required="true" size="30" value="' . esc_attr( $commenter['comment_author_email'] ) . '" name="email" id="email"></p>';
    $fields['url'] = '<p class="comment-form-url"><label for="url">站点</label><input type="text" placeholder="个人主页网址" size="30" value="'.$comment_author_url.'" name="url" id="url"></p>';
    return $fields;
}

add_filter('comment_form_default_fields','alter_comment_form_fields');

直接将上面的代码放到你的 functions.php 文件中,稍作修改即可。不过,如果要改变评论框出现的位置,那还是需要动一下 comments.php 文件的。(更新)非常感谢 Muze 指出上面代码中的错误,现已更正。

实际上,将下面的代码保存下来,随时可以往里面填写东西来实现修改(每行前面的 // 表示注释掉改行,即让它不起作用,所以,要用的话就把 // 删掉):

function alter_comment_form_fields($fields){
    //$fields['author'] = ''; //removes name field
    //$fields['email'] = '';  //removes email field
    //$fields['url'] = '';  //removes website field
    return $fields;
}

add_filter('comment_form_default_fields','alter_comment_form_fields');

后记

写这个的时候查了查资料,参考了2篇文章:

  1. http://chipcullen.com/altering-the-comment-form-in-wordpress/
  2. http://www.1stwebdesigner.com/wordpress/comment-form-customization/

如果你有什么建议和疑问,请在下方留言。©

本文发表于水景一页。永久链接:<https://cnzhx.net/blog/altering-wordpress-comment-form/>。转载请保留此信息及相应链接。

16 条关于 “个性化 WordPress 评论框” 的评论

  1. 想請問一下,為什麼我的迴響字樣會在評論框的左下角而不是在左上角,我是用內建函式 這是我的網頁網址http://140.113.86.128/~kerker/wordpress/ 可以告訴我問題在哪嗎?
    謝謝

    • 欢迎光临!
      这个是用 CSS 来实现的。象你的网站,可以用类似下面的 CSS 规则:
      .comment-title {
      position: absolute;
      top: 10px;
      right: 10px;
      }

      同时还需要将文章标题的右边空出来一点(具体空多少要看你的“回应”需要占多大的地方):
      .article-title {
      margin-right: 30px;
      }

      我浏览你的网站没有看到样式表(style.css),所以无法给你准确的 px 值。

      • 謝謝,因為還在建立當中,我剛把迴響的字樣拿掉了,所以看不出問題,現在我把迴響的字樣用回來,就晏晟我剛講的問題,我是有用style.css去控制樣式啊

          • 我發現是因為迴響字樣後面就直接接textarea所以才會這樣,所以我給他後面加了換行符號就看起來正常,但是應該是不用這樣處理才對吧,不知道真正的問題在哪

            • 嗯,不好意思,搞错了。我开始以为你说的是那个显示评论(回应)数量的框框,却原来你说的是评论框文本区域的标签。
              你说的情况只要将文本框的宽度设置得大一些就能解决了,比如使用下面的 CSS:
              #comment {
              width: 98%;
              }

              当然,你在 回应
              后面加个换行也行。

            • 謝謝喔,社大一點真的就搞定了,不過為什麼你的文本框不用這麼大也可以

              • 如果你不想让评论框太宽,可以将 label 的样式增加一个:
                .comment-form-comment label {
                display: block;
                }

                然后下面的文本框就可以随意设置宽度了。

  2. 如何让评论框显示在评论上边呢?我把表单放在上边,当一篇新文章没有评论,它就不显示了啊!扰乱一下界面,放段代码,这是comments.php :

    • 可以看到你这个代码也是不完整的,因为WP的安全检查会自动过滤一些字符。上面的代码给你删了啊。
      你说的情况,可能是把评论框的代码放到了检查是否有评论的那个 if 语句里面了,调到下面这行之前就好了。

       if ( have_comments() ) : 

雁过留声,人过留名

您的电子邮箱地址不会被公开。 必填项已用 * 标注

特别提示:与当前文章主题无关的讨论相关但需要较多讨论求助信息请发布到水景一页讨论区的相应版块,谢谢您的理解与合作!请参考本站互助指南
您可以在评论中使用如下的 HTML 标记来辅助表达: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>