0

I'm trying to add 5 custom fields to comment form. Just use 2 hooks to display custom fields after default fields - 'comment_form_logged_in_after' and 'comment_form_after_fields' like this:

function kvkoolitus_registration_additional_fields () {

  echo '<p class="comment-form-code">'.
  '<label for="code">' . __( 'Personal code', 'kvkoolitus' ) . ' <span class="required">*</span> </label>'.
  '<input id="code" name="code" type="text" size="30"  tabindex="5" /></p>';

  echo '<p class="comment-form-phone">'.
  '<label for="phone">' . __( 'Phone','kvkoolitus' ) . ' <span class="required">*</span> </label>'. 
  '<input id="phone" name="phone" type="text" size="30"  tabindex="5" /></p>';

  echo '<p class="comment-form-address">'.
  '<label for="address">' . __( 'Address','kvkoolitus' ) . '</label>'.
  '<input id="address" name="address" type="text" size="30"  tabindex="5" /></p>';

  echo '<p class="comment-form-company">'.
  '<label for="company">' . __( 'Company','kvkoolitus' ) . '</label>'.
  '<input id="company" name="company" type="text" size="30"  tabindex="5" /></p>';

  echo '<p class="comment-form-profession">'.
  '<label for="profession">' . __( 'Profession','kvkoolitus' ) . '</label>'.
  '<input id="profession" name="profession" type="text" size="30"  tabindex="5" /></p>'; 
}

add_action( 'comment_form_logged_in_after', 'kvkoolitus_registration_additional_fields' );
add_action( 'comment_form_after_fields', 'kvkoolitus_registration_additional_fields' );

When someone is logged in, first come required fields (name, email), additional fields and then comment field, just like I need. But if user is not logged in, comment field display at first position. Why is this happen and how to solve this? wrong order

4
  • The plugin is at fault here, or perhaps there is another earlier hook you should be using. For example, is there a comment_form_before_fields hook, which would get your custom fields rendered before the comment textarea field? You need to look at the plugin source code or documentation, to see about this.
    – C C
    Commented Jul 13, 2016 at 14:43
  • When I use a hook 'comment_form_before_fields' and 'comment_form_logged_in_before' hooks, it puts required fields (name, email) at the bottom of the form. Comment field is still first in order.
    – anton
    Commented Jul 13, 2016 at 14:50
  • contact the plugin developer...it's their problem...
    – C C
    Commented Jul 13, 2016 at 14:58
  • Actually I try to do this by myself, so I need to know how to add custom fields to comment form and display them in the right order)))
    – anton
    Commented Jul 13, 2016 at 15:01

1 Answer 1

0

Demo - Setup

Here's a demo how we could control the display of comment fields and their order:

Let's create a custom class:

$mycf = new MyCommentFields;

Then we define our extra fields:

$myfields = [];

$myfields['myaddress'] = sprintf(
    '<p class="comment-form-myaddress">
         <label for="myaddress">%s <span class="required">*</span></label>
         <input id="myaddress" name="myaddress" type="text" size="30" tabindex="5" />
     </p>', 
    esc_html__( 'Address', 'kvkoolitus' )
); 

$myfields['myphone'] = sprintf(
    '<p class="comment-form-myphone">
         <label for="myphone">%s <span class="required">*</span></label>
         <input id="myphone" name="myphone" type="text" size="30" tabindex="5" />
     </p>', 
    esc_html__( 'Phone', 'kvkoolitus' )
);

and set it with:

$mycf->set_extra_fields_logged_in(  $myfields );
$mycf->set_extra_fields_logged_out( $myfields );

Next we set the display-order for those fields:

$mycf->set_fields_order_logged_in( 
    [ 
        'myaddress', 
        'myphone', 
        'comment', 
    ] 
);

and:

$mycf->set_fields_order_logged_out( 
    [ 
        'author', 
        'email', 
        'url', 
        'myaddress', 
        'myphone', 
        'comment' 
    ] 
);

Then we initialize it:

$mycf->init();

We could then hook this into the comment_form_before action.

Demo - Class

Here's our demo class (PHP 5.4+):

class MyCommentFields
{
    private $extra_fields_logged_in;
    private $extra_fields_logged_out;
    private $fields_order_logged_in;
    private $fields_order_logged_out;

    public function init()
    {
        // logged-out case
        add_filter( 'comment_form_fields',          [ $this, 'comment_form_fields' ] );

        // logged-in case
        add_filter( 'comment_form_field_comment',   [ $this, 'comment_form_field_comment' ] );      
    }

    public function set_extra_fields_logged_in( array $extra_fields_logged_in )
    {
        $this->extra_fields_logged_in = $extra_fields_logged_in;
    }

    public function set_extra_fields_logged_out( array $extra_fields_logged_out )
    {
        $this->extra_fields_logged_out = $extra_fields_logged_out;
    }

    public function set_fields_order_logged_in( array $fields_order_logged_in )
    {
        $this->fields_order_logged_in = $fields_order_logged_in;
    }

    public function set_fields_order_logged_out( array $fields_order_logged_out )
    {
        $this->fields_order_logged_out = $fields_order_logged_out;
    }

    public function comment_form_field_comment( $field )
    {
        // logged-in case
        if( is_user_logged_in() && ! empty( $this->extra_fields_logged_in ) ) 
        {
            $tmp = '';
            foreach( $this->fields_order_logged_in as $key )
            {
                if( 'comment' === $key  )
                    $tmp .= $field;
                elseif( isset( $this->extra_fields_logged_in[$key] ) )
                    $tmp .= $this->extra_fields_logged_in[$key];
            }
            if( $tmp )
                $field = $tmp;
        }
        return $field;
    }

    public function comment_form_fields( $fields )
    {
        // logged-out case
        if( ! is_user_logged_in() && ! empty( $this->extra_fields_logged_out ) ) 
        {
            $tmp = [];
            foreach( $this->fields_order_logged_out as $key )
            {
                if( isset( $fields[$key] ) )
                    $tmp[$key] = $fields[$key];             
                elseif( isset( $this->extra_fields_logged_out[$key] ) )
                    $tmp[$key] = $this->extra_fields_logged_out[$key];
            }   
            if( ! empty( $tmp ) ) 
                $fields = $tmp;
        }       
        return $fields;
    }

} // end class

Hopefully you can adjust the demo to your needs.

Previous answer:

Here's one hack, to prepend extra fields, that should work for both logged-in and logged-out case:

add_filter( 'comment_form_fields', function( $fields )
{
      echo '<p class="comment-form-code">'.
           '<label for="code">' . __( 'Personal code', 'kvkoolitus' ) . ' <span class="required">*</span> </label>'.
           '<input id="code" name="code" type="text" size="30"  tabindex="5" /></p>';

      echo '<p class="comment-form-phone">'.
           '<label for="phone">' . __( 'Phone','kvkoolitus' ) . ' <span class="required">*</span> </label>'. 
           '<input id="phone" name="phone" type="text" size="30"  tabindex="5" /></p>';

      echo '<p class="comment-form-address">'.
           '<label for="address">' . __( 'Address','kvkoolitus' ) . '</label>'.
           '<input id="address" name="address" type="text" size="30"  tabindex="5" /></p>';

      echo '<p class="comment-form-company">'.
           '<label for="company">' . __( 'Company','kvkoolitus' ) . '</label>'.
           '<input id="company" name="company" type="text" size="30"  tabindex="5" /></p>';

      echo '<p class="comment-form-profession">'.
           '<label for="profession">' . __( 'Profession','kvkoolitus' ) . '</label>'.
           '<input id="profession" name="profession" type="text" size="30"  tabindex="5" /></p>'; 

    return $fields;
} );

Note that the dynamic comment_form_field_{$name} filter for the logged-out case will not be available for those fields.

Otherwise one could inject the new fields into the $comments_fields within the comment_form_fields filter and make sure they come before the default fields. This will only display for the logged-out case. Then for the logged-out case the comment_form_logged_in_after hook is available.

18
  • hmm..with your solution comment field outputed at the end of the form for both cases, logged in and logged out users, just like I wanted. But right now, default fields (name and email) outputs at the end of the form for users, which are not logged in.
    – anton
    Commented Jul 13, 2016 at 16:35
  • did you check the order of fields in the HTML source, just in case it's CSS changing the order ? @anton
    – birgire
    Commented Jul 13, 2016 at 17:36
  • HTML sourse is the same: code, phone, address, company, profession, comment and just then goes author and email
    – anton
    Commented Jul 13, 2016 at 17:54
  • yes that was the order I was aiming for, injecting your custom fields above the default fields ;-) so you don't want that order or ... ? PS: Your description "When someone is logged in, first come required fields (name, email)," doesn't match the screenshot and are not usually required for logged in users @anton
    – birgire
    Commented Jul 13, 2016 at 18:03
  • I need to display fields in this order: name, email, code, phone, address, company, profession, comment. If someone is logged in, default name and email field should be hidden, because we already know this information. Like on screenshot.
    – anton
    Commented Jul 13, 2016 at 18:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.