1

I use to handle comments on my blog.

I also like to have pingbacks from various posts back and forth to each other (and from outside sources.

However, I noticed today that while the comment count at the bottom of a post will show the total number of "comments" (including pingbacks), only the Disqus comments are actually displayed.

How can I get pingbacks to appear as well as Disqus comments?

  • I found (and have installed) Force Ping Display with Disqus - seems like it's a less-than-ideal solution: surely there is a way of accomplishing this sans extra plugins? – warren Aug 3 '14 at 3:53
  • 1
    I think this question is borderline off-topic, but why is the solution you found less-than ideal? I added an answer, because I was a little bit curious about this topic ;-) – birgire Aug 3 '14 at 13:25
  • 1
    @birgire - core functionality of the tool (wordpress) shouldn't be hidden/broken by a plugin and require another one to fix it :) – warren Aug 4 '14 at 13:57
4
+50

The plugin you mentioned is only a single function so it shouldn't be too heavy on your setup. It uses the comments_template filter to inject the pingbacks/trackbacks list into your page.

But the plugin is using an extra manual SQL query and the template is constructed by hand, so there's a room for improvements/simplifications.

A simple demo plugin with wp_list_comments():

You can try for example:

<?php
/** Plugin Name: Display a list of pingbacks and trackbacks with the Disqus plugin **/

add_filter( 'comments_template', function( $theme_template) {

    // Check if the Disqus plugin is installed:
    if( ! function_exists( 'dsq_is_installed' ) || ! dsq_is_installed() )
        return $theme_template;

    // Comment callback:
    $callback = 'my_theme_comment';  // Adjust to your needs.       
    if( ! function_exists( $callback ) )
        $callback = null;

    // List comments with filters:
    $pings = wp_list_comments( 
        array(  
            'callback' => $callback, 
            'type'     => 'pings', 
            'style'    => 'ol', 
            'echo'     => 0 
        ) 
    ); 

    // Display:
    if( $pings )
        printf( "<div><ol class=\"pings commentlist\">%s</ol></div>", $pings );

    return $theme_template;

}, 9 );

If your theme uses a callback then you can adjust the my_theme_comment part accordingly. The Twenty Twelve theme uses the twentytwelve_comment callback but the Twenty Thirteen and Twenty Fourteen themes do not use such a callback, to my knowledge.

The $type => 'pings' input parameter is of importance, because it filters out every comment type except pingbacks and trackbacks.

Notice that we let wp_list_comments() do all the hard work setting up the template.

A modular demo solution without wp_list_comments():

You could also filter out the pings, from the comments_array filter, with:

add_action( 'wp', 
    function(){
        // Check if the Disqus plugin is installed:
        if( function_exists( 'dsq_is_installed' ) && dsq_is_installed() )
        {
            // Display the list of pings:     
            $pings = new PingsList( new PingsView, new PingsData );
            $pings->init();
        }
    }
);

where the main container class is:

class PingsList
{
    protected $pd   = null;
    protected $pw   = null;

    public function __construct( PingsView $pw, PingsData $pd )
    {
        $this->pw = $pw;
        $this->pd = $pd;
    }   
    public function init()
    {
        $this->pd->init();      
        add_filter( 'comments_template',    array( $this, 'comments_template' ), 9 );
    }
    public function comments_template( $theme_template )
    {
        $this->pw->template( $this->pd->get_data() );
        return $theme_template ;
    }
} // end class

and the data source is:

interface IPingsData
{
    public function init();
    public function get_data();
}
class PingsData implements IPingsData
{
    protected $pings    = array();

    public function init( )
    {
        add_filter( 'comments_array', array( $this, 'comments_array' ), 10, 2 );
    }
    public function get_data()
    {       
        return $this->pings;
    }
    public function comments_array( $comments, $post_id )
    {
        foreach( $comments as $key => $comment )
        {
            if( in_array( $comment->comment_type, array( 'pingback', 'trackback' ) ) )
            {
                $this->pings[] = $comment; 
            }
        }
        return $comments;
    }       
} // end class

and the layout is defined with:

interface IPingsView
{
    public function template( $pings );
}
class PingsView implements IPingsView
{       
    public function template( $pings = array() )
    {
    ?>
    <div id="pings">
        <h2><?php printf( __( 'Pingbacks/Trackbacks (%d)' ), count( $pings ) );?> </h2>
        <ol class="pings commentlist">
        <?php foreach( $pings as $ping ): $GLOBALS['comment'] = $ping; ?>           
            <li <?php comment_class(); ?> id="comment-<?php comment_ID(); ?>">
                <p>
                    <?php comment_author_link(); ?> 
                    <?php edit_comment_link( 
                          __( '(Edit)' ), '<span class="edit-link">', '</span>' ); ?>
                </p>
                <div class="comment-content">
                    <?php comment_text(); ?>
                </div>
            </li>               
        <?php endforeach; ?>
        </ol>
    </div>
    <?php
    }
} // end class

You can then adjust the layout to your needs.

Here's an example of the output with this solution implemented:

pings with disqus

A solution with an extra get_comments():

Another way (with some extra work and queries!) would be to construct the list, with for example:

add_filter( 'comments_template', 
    function( $theme_template)
    {
        $pings = get_comments(
            array( 
              'post_id' => get_the_ID(),
              'type'    => 'pings', 
              'status'  => 'approve' ) 
        );

        foreach( (array) $pings as $ping )
        {
            // ... output ...
        }
        return $theme_template;
    }
, 9 );

where get_comments() is just a wrapper for the WP_Comment_Query class. I would probably not go this route and use the other solutions instead.

You could also use the WP_Comment_Query class directly, but it's not as sophisticated as the WP_Query class.

I hope this helps.

  • ps: in the demo we want to type-hint with the interfaces instead of the classes (that also works). Therefore the constructor parameters should be: IPingsView $pw, IPingsData $pd. – birgire Aug 6 '14 at 10:00
1

This will display them before the DISQUS comment form but not the count

add_filter( 'comments_template', function( $pings_before_dsq_comments) {

if( !function_exists( 'dsq_is_installed' ) || !dsq_is_installed() )
    return $pings_before_dsq_comments;

wp_list_comments( 
 array(
'style'             => 'ul',
'type'              => 'pings'
)); 

return $pings_before_dsq_comments;
}, 9 );

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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