Rearrange elements outputted by comment_form()

I’m currently developing a custom theme from scratch.

In the past week, I’ve been trying to change the order of the HTML elements output by the comment_form().

Read More

I basically don’t know any PHP, and I was unable to find information on the comment_form() that successfully covers how to rearrange the layout of its output, including the WordPress Codex.

Can anyone please explain how to rearrange the elements outputted by the comment_form(), preferably without having to be proficient in PHP and the inner workings of WordPress?

Please don’t provide solutions that rely on re-positioning elements with CSS; this can’t be the way you’re intended to customize the output.

If it turns out there isn’t an optimal way to achieve this, would it then be possible to customize comments.php without using the comment_form(), like you would before the function was introduced?

The following links cover some of the most relevant methods I’ve tried. They either don’t work at all or don’t achieve the correct result:

http://freetexthost.com/wplcq61i3d

(Sorry, but I’m not allowed to post more than two links directly in the post.)

Thank you.

Related posts

1 comment

  1. Re-arranging the comment fields

    The comment text area has been moved to the top in WordPress 4.4:

    default 4.4

    What if we prefer the old setup, where it was at the bottom?

    Re-arranging the author, url and email comment fields

    We can modify the display order, of the author, url and email fields, with:

    /**
     * Re-arranging the author, url and email comment fields
     */
    add_filter( 'comment_form_defaults', function( $defaults )
    {
        $_defaults = [];
    
        // Re-arrange the fields to your needs:
        $fields = [ 'author', 'url', 'email' ];
    
        foreach( $fields as $field )
            $_defaults['fields'][$field] = $defaults['fields'][$field]; 
    
        return $_defaults;
    } );
    

    but we will have to find another approach to re-order the comment text area an the submit button.

    Custom Workaround

    To re-arrange all five comment fields, we can use the custom wpse_comment_fields filter:

    add_filter( 'wpse_comment_fields', function( $fields )
    {       
        return $fields;
    } );
    

    in the functions.php file or in a plugin.

    Example: Author field at top

    Let’s move the author field to the top:

    /**
     * Display the 'author' comment field at top:
     */
    add_filter( 'wpse_comment_fields', function( $fields )
    {
        // Re-arrange fields
        $fields = [ 'author', 'comment', 'url', 'email', 'submit' ];
    
        return $fields;
    } );
    

    The comment form will then display as:

    custom 1

    Example: Comment field at the bottom and remove the Url field

    Here we display the comment field at the bottom and remove the url field:

    /**
     * Display the 'comment' field at the bottom and remove the 'url' field:
     */
    add_filter( 'wpse_comment_fields', function( $fields )
    {
        // Re-arrange fields
        $fields = [ 'email', 'author', 'comment', 'submit' ];
    
        return $fields;
    } );
    

    Then the comment form will show:

    custom 2

    Demo Plugin

    Here’s our demo plugin that supports the wpse_comment_fields filter (PHP 5.4+):

    <?php
    /**
     * Plugin Name: Rearrange Comment Fields
     * Plugin URI:  http://wordpress.stackexchange.com/a/207449/26350
     * Author:      Birgir Erlendsson (birgire)
     * Description: Support for rearranging the comment fields: 'comment', 'auhtor', 'url', 'email' and 'submit' through the 'wpse_comment_fields' filter.
     * Version:     0.0.1
     */
    
    add_action( 'comment_form_before', function()
    {
        if( class_exists( 'WPSE_Rearrange_Comment_Fields' ) )
        {
            $fields = apply_filters( 
                'wpse_comment_fields', 
                [ 'comment', 'author', 'url', 'email', 'submit' ]
            );
    
            $o = new WPSE_Rearrange_Comment_fields;
            $o->set_fields( $fields )
              ->init();
        }
    });
    
    class WPSE_Rearrange_Comment_Fields
    {
        private $html       = [];
        private $defaults   = [];
        private $fields     = [];
    
        public function set_fields( array $fields )
        {
            $this->fields = $fields;
            return $this;
        }
    
        public function init()
        {
            // Default
            $this->defaults = [ 'comment', 'author', 'url', 'email', 'submit' ];
    
            // Check for defaults
            if( empty( $this->fields ) )
                $this->fields = $this->defaults;
    
            // Hooks
            add_action( 'comment_form',                 [$this, 'display'],                     PHP_INT_MAX );
            add_filter( 'comment_form_field_comment',   [$this, 'comment_form_field_comment'],  PHP_INT_MAX );
            add_filter( 'comment_form_submit_field',    [$this, 'comment_form_submit_field'],   PHP_INT_MAX );
            foreach( [ 'author', 'url', 'email' ] as $field )
                add_filter( "comment_form_field_{$field}",  [$this, 'comment_form_field'], PHP_INT_MAX );       
        }
    
        public function display()
        {
            // Display fields in the custom order                   
            $html = '';
            foreach( (array) $this->fields as $field )
            {
                if( in_array( $field, $this->defaults ) ) 
                    $html .= $this->html[$field]; 
            }
            echo $html;
        }
    
        public function comment_form_submit_field( $submit_field )
        {
            $this->html['submit'] = $submit_field;
            return '';
        }
    
        public function comment_form_field_comment( $comment_field )
        {
            $this->html['comment'] = $comment_field;
            return '';
        }
    
        public function comment_form_field( $field )
        {
            $key = str_replace( 'comment_form_field_', '', current_filter() );
            $this->html[$key] = $field;
            return '';
        }
    
    } // end class
    

Comments are closed.