显示标题相同的所有帖子

时间:2016-03-10 作者:Guenfood

我试图在一个侧栏php小部件中显示特定类别中具有相同post\\u标题的所有帖子。我在网上找到了这个代码,但不知道如何使用它,谢谢你的帮助。

function get_multiple_posts_by_title($title) {
    global $wpdb;
    $posts_ids = array();

    $posts = $wpdb->get_results( $wpdb->prepare( “SELECT ID FROM $wpdb->posts WHERE post_title = %s AND     post_type=’post_type’”, $title), OBJECT );
    foreach ($posts as $post) {
         $posts_ids[] = $post->ID;
    }

    return $posts_ids;
}
编辑:这是我使用的实际代码。

<?php
/*
Plugin Name: WPSE Get Duplicate Post Titles
Plugin URI:  http://wordpress.stackexchange.com/q/220279/31545
Description: Displays posts with the same title in the sidear
Version:     1.0.0
Author:      Pieter Goosen
Author URI:  http://wordpress.stackexchange.com/users/31545/pieter-goosen
License:     GPL2
License URI: https://www.gnu.org/licenses/gpl-2.0.html
*/

add_filter( \'posts_where\', function ( $where, $q ) use ( &$wpdb )
{
    // Get the value from our new wpse_title_match query var
    $title_match = $q->get( \'wpse_title_match\' );

    // Make sure we have a value, if not, bail
    if ( !$title_match )
        return $where;

    /**
     * Lets alter the SQL WHERE clause
     *
     * Note, this will be an exact 1 to 1 match, adjust as necessary
     */
    $where .= $wpdb->prepare(
        " AND {$wpdb->posts}.post_title = %s ",
        $title_match
    );

    return $where;
}, 10, 2 );

class WPSE_Get_Duplicate_Post_titles extends WP_Widget 
{

    public function __construct() 
    {
        parent::__construct(
            \'widget_get_duplicate_post_titles\', 
            _x( \'Post Title duplicates\', \'Post Title duplicates\' ), 
            [ \'description\' => __( \'Displays posts which share the same post title.\' ) ] 
        );
        $this->alt_option_name = \'widget_get_duplicate_post_titles\';

        add_action( \'save_post\',    [$this, \'flush_widget_cache\'] );
        add_action( \'deleted_post\', [$this, \'flush_widget_cache\'] );
        add_action( \'switch_theme\', [$this, \'flush_widget_cache\'] );
    }

    public function widget( $args, $instance ) 
    {
        $cache = [];
        if ( ! $this->is_preview() ) {
            $cache = wp_cache_get( \'widget_bpfi\', \'widget\' );
        }

        if ( ! is_array( $cache ) ) {
            $cache = [];
        }

        if ( ! isset( $args[\'widget_id\'] ) ) {
            $args[\'widget_id\'] = $this->id;
        }

        if ( isset( $cache[ $args[\'widget_id\'] ] ) ) {
            echo $cache[ $args[\'widget_id\'] ];
            return;
        }

        ob_start();

        $title          = ( ! empty( $instance[\'title\'] ) ) ? $instance[\'title\'] : __( \'Post Title Duplicates\' );
        /** This filter is documented in wp-includes/default-widgets.php */
        $title          = apply_filters( \'widget_title\', $title, $instance, $this->id_base );

        // ADD YOUR CUSTOM PHP CODE HERE FOR EXECUTION TO DISPLAY ON FRONT END
        // First make sure this a single post page
        if ( is_single() ) { // We are on a single page
            // Get the current post object
            $post_object = $GLOBALS[\'wp_the_query\']->get_queried_object();

            // Run our query to get the posts with duplicate titles
            $args = [
                \'posts_per_page\'   => -1, // Get all posts
                \'post_type\'        => \'post\',
                \'wpse_title_match\' => $post_object->post_title,
                \'post__not_in\'     => [$post_object->ID], // Exclude current post
                \'tax_query\'        => [
                    [
                        \'taxonomy\' => \'category\',
                        \'terms\'    => \'chroniques\'
                    ]
                ],
                // Any other arguments
            ];
            $loop = new WP_Query( $args );

            // Run the loop
            if ( $loop->have_posts() ) {
                while ( $loop->have_posts ) {
                    $loop->the_post();

                    // Display your posts
                    the_title() . "\\n";

                }
                wp_reset_postdata();
            }
        }

        echo $args[\'after_widget\']; 

        if ( ! $this->is_preview() ) {
            $cache[ $args[\'widget_id\'] ] = ob_get_flush();
            wp_cache_set( \'widget_bpfi\', $cache, \'widget\' );
        } else {
            ob_end_flush();
        }
    }

    public function update( $new_instance, $old_instance ) 
    {
        $instance                   = $old_instance;
        $instance[\'title\']          = strip_tags( $new_instance[\'title\'] );
        $this->flush_widget_cache();

        $alloptions = wp_cache_get( \'alloptions\', \'options\' );
        if ( isset($alloptions[\'widget_get_duplicate_post_titles\']) )
            delete_option(\'widget_get_duplicate_post_titles\');

        return $instance;
    }

    public function flush_widget_cache() 
    {
        wp_cache_delete(\'widget_bpfi\', \'widget\');
    }

    public function form( $instance ) 
    {

        $title      = isset( $instance[\'title\'] ) ? esc_attr( $instance[\'title\'] ) : \'\';
        ?>

        <p>
            <label for="<?php echo $this->get_field_id( \'title\' ); ?>"><?php _e( \'Title:\' ); ?></label>
            <input class="widefat" id="<?php echo $this->get_field_id( \'title\' ); ?>" name="<?php echo $this->get_field_name( \'title\' ); ?>" type="text" value="<?php echo $title; ?>" />
        </p>

    <?php
    }

}

add_action( \'widgets_init\', function () 
{
    register_widget( \'WPSE_Get_Duplicate_Post_titles\' );
});

add_filter( \'sidebars_widgets\', function ( $sidebars_widgets )
{
    // Return our filter when we are on admin screen
    if ( is_admin() )
        return $sidebars_widgets;

    // Make sure we are not on the blog page, if we are, bail
    if ( is_single() )
        return $sidebars_widgets;

    /**
     * Widget we need to target. This should be the name/id we used to register it
     *
     * EXAMPLE
     *   parent::__construct(
            \'widget_get_duplicate_post_titles\', 
            _x( \'Blog Page Featured Image\', \'Blog page featured image\' ), 
            [ \'description\' => __( \'Displays the featured image for the pge set as blog page.\' ) ] 
        );
     *
     */
    $custom_widget  = \'widget_get_duplicate_post_titles\';

    // See if our custom widget exists is any sidebar, if so, get the array index
    foreach ( $sidebars_widgets as $sidebars_key=>$sidebars_widget ) {
        // Skip the wp_inactive_widgets set, we do not need them
        if ( $sidebars_key == \'wp_inactive_widgets\' )
        continue;

        // Only continue our operation if $sidebars_widget are not an empty array
        if ( $sidebars_widget ) {
            foreach ( $sidebars_widget as $k=>$v ) {

                /**
                 * Look for our custom widget, if found, unset it from the $sidebars_widgets array
                 * @see stripos()
                 */
                if ( stripos( $v, $custom_widget ) !== false ) 
                    unset( $sidebars_widgets[$sidebars_key][$k] );
            } // endforeach $sidebars_widget
        } // endif $sidebars_widget
    } // endforeach $sidebars_widgets

    return $sidebars_widgets;
});

1 个回复
最合适的回答,由SO网友:Pieter Goosen 整理而成

让我们使用WordPress提供的内置功能。每当WordPress提供本机函数来执行特定任务时,几乎总是不建议使用自定义SQL。

要查询我们的帖子,我们将使用WP_Query. 唯一的问题是,WP_Query 不支持我们查找具有特定帖子标题的帖子的功能。幸运的是,我们可以在构建SQL查询查询db之前对其进行过滤。为此,我们将使用posts_where 过滤器引入我们自己的自定义参数,wpse_title_match (不,这与摔跤无关)。

我们需要在插件(推荐)或主题函数文件中添加以下内容

add_filter( \'posts_where\', function ( $where, $q ) use ( &$wpdb )
{
    // Get the value from our new wpse_title_match query var
    $title_match = $q->get( \'wpse_title_match\' );

    // Make sure we have a value, if not, bail
    if ( !$title_match )
        return $where;

    /**
     * Lets alter the SQL WHERE clause
     *
     * Note, this will be an exact 1 to 1 match, adjust as necessary
     */
    $where .= $wpdb->prepare(
        " AND {$wpdb->posts}.post_title = %s ",
        $title_match 
    );

    return $where;
}, 10, 2 );
此时,最好为自己构建一个合适的小部件,而不是将所有内容都放在php小部件中

这是我最近做的一个修改过的小部件插件here

class WPSE_Get_Duplicate_Post_titles extends WP_Widget 
{

    public function __construct() 
    {
        parent::__construct(
            \'widget_get_duplicate_post_titles\', 
            _x( \'Post Title duplicates\', \'Post Title duplicates\' ), 
            [ \'description\' => __( \'Displays posts which share the same post title.\' ) ] 
        );
        $this->alt_option_name = \'widget_get_duplicate_post_titles\';

        add_action( \'save_post\',    [$this, \'flush_widget_cache\'] );
        add_action( \'deleted_post\', [$this, \'flush_widget_cache\'] );
        add_action( \'switch_theme\', [$this, \'flush_widget_cache\'] );
    }

    public function widget( $args, $instance ) 
    {
        $cache = [];
        if ( ! $this->is_preview() ) {
            $cache = wp_cache_get( \'widget_bpfi\', \'widget\' );
        }

        if ( ! is_array( $cache ) ) {
            $cache = [];
        }

        if ( ! isset( $args[\'widget_id\'] ) ) {
            $args[\'widget_id\'] = $this->id;
        }

        if ( isset( $cache[ $args[\'widget_id\'] ] ) ) {
            echo $cache[ $args[\'widget_id\'] ];
            return;
        }

        ob_start();

        $title          = ( ! empty( $instance[\'title\'] ) ) ? $instance[\'title\'] : __( \'Post Title Duplicates\' );
        /** This filter is documented in wp-includes/default-widgets.php */
        $title          = apply_filters( \'widget_title\', $title, $instance, $this->id_base );

        // ADD YOUR CUSTOM PHP CODE HERE FOR EXECUTION TO DISPLAY ON FRONT END
        // First make sure this a single post page
        if ( is_single() ) { // We are on a single page
            // Get the current post object
            $post_object = $GLOBALS[\'wp_the_query\']->get_queried_object();

            // Run our query to get the posts with duplicate titles
            $args = [
                \'posts_per_page\'   => -1, // Get all posts
                \'post_type\'        => \'post\',
                \'wpse_title_match\' => $post_object->post_title,
                \'post__not_in\'     => [$post_object->ID], // Exclude current post
                \'tax_query\'        => [
                    [
                        \'taxonomy\' => \'category\',
                        \'field\'    => \'slug\',
                        \'terms\'    => \'chroniques\'
                    ]
                ],
                // Any other arguments
            ];
            $loop = new WP_Query( $args );

            // Run the loop
            if ( $loop->have_posts() ) {
                while ( $loop->have_posts() ) {
                    $loop->the_post();

                    // Display your posts
                    the_title() . "\\n";

                }
                wp_reset_postdata();
            }
        }

        echo $args[\'after_widget\']; 

        if ( ! $this->is_preview() ) {
            $cache[ $args[\'widget_id\'] ] = ob_get_flush();
            wp_cache_set( \'widget_bpfi\', $cache, \'widget\' );
        } else {
            ob_end_flush();
        }
    }

    public function update( $new_instance, $old_instance ) 
    {
        $instance                   = $old_instance;
        $instance[\'title\']          = strip_tags( $new_instance[\'title\'] );
        $this->flush_widget_cache();

        $alloptions = wp_cache_get( \'alloptions\', \'options\' );
        if ( isset($alloptions[\'widget_get_duplicate_post_titles\']) )
            delete_option(\'widget_get_duplicate_post_titles\');

        return $instance;
    }

    public function flush_widget_cache() 
    {
        wp_cache_delete(\'widget_bpfi\', \'widget\');
    }

    public function form( $instance ) 
    {

        $title      = isset( $instance[\'title\'] ) ? esc_attr( $instance[\'title\'] ) : \'\';
        ?>

        <p>
            <label for="<?php echo $this->get_field_id( \'title\' ); ?>"><?php _e( \'Title:\' ); ?></label>
            <input class="widefat" id="<?php echo $this->get_field_id( \'title\' ); ?>" name="<?php echo $this->get_field_name( \'title\' ); ?>" type="text" value="<?php echo $title; ?>" />
        </p>

    <?php
    }

}

add_action( \'widgets_init\', function () 
{
    register_widget( \'WPSE_Get_Duplicate_Post_titles\' );
});
我还喜欢做的是,当一个小部件完全脱离上下文时,总是完全删除它,以避免在没有显示其他小部件时侧栏呈现空白

我们可以尝试与我描述的相同的方法here. 你可以在插件的底部添加这个

add_filter( \'sidebars_widgets\', function ( $sidebars_widgets )
{
    // Return our filter when we are on admin screen
    if ( is_admin() )
        return $sidebars_widgets;

    // Make sure we are not on the blog page, if we are, bail
    if ( is_single() )
        return $sidebars_widgets;

    /**
     * Widget we need to target. This should be the name/id we used to register it
     *
     * EXAMPLE
     *   parent::__construct(
            \'widget_get_duplicate_post_titles\', 
            _x( \'Blog Page Featured Image\', \'Blog page featured image\' ), 
            [ \'description\' => __( \'Displays the featured image for the page set as blog page.\' ) ] 
        );
     *
     */
    $custom_widget  = \'widget_get_duplicate_post_titles\';

    // See if our custom widget exists is any sidebar, if so, get the array index
    foreach ( $sidebars_widgets as $sidebars_key=>$sidebars_widget ) {
        // Skip the wp_inactive_widgets set, we do not need them
        if ( $sidebars_key == \'wp_inactive_widgets\' )
        continue;

        // Only continue our operation if $sidebars_widget are not an empty array
        if ( $sidebars_widget ) {
            foreach ( $sidebars_widget as $k=>$v ) {

                /**
                 * Look for our custom widget, if found, unset it from the $sidebars_widgets array
                 * @see stripos()
                 */
                if ( stripos( $v, $custom_widget ) !== false ) 
                    unset( $sidebars_widgets[$sidebars_key][$k] );
            } // endforeach $sidebars_widget
        } // endif $sidebars_widget
    } // endforeach $sidebars_widgets

    return $sidebars_widgets;
});
上面的所有代码都未经测试,需要PHP 5.4+

您应该调整WP_Query 小部件中的参数以满足您的需要。在我用大写字母添加值的任何地方,都应该填写适当的值

两个过滤函数都可以添加到同一个插件中,因此完整的插件如下所示

最终代码

<?php
/*
Plugin Name: WPSE Get Duplicate Post Titles
Plugin URI:  https://wordpress.stackexchange.com/q/220279/31545
Description: Displays posts with the same title in the sidear
Version:     1.0.0
Author:      Pieter Goosen
Author URI:  https://wordpress.stackexchange.com/users/31545/pieter-goosen
License:     GPL2
License URI: https://www.gnu.org/licenses/gpl-2.0.html
*/

add_filter( \'posts_where\', function ( $where, $q ) use ( &$wpdb )
{
    // Get the value from our new wpse_title_match query var
    $title_match = $q->get( \'wpse_title_match\' );

    // Make sure we have a value, if not, bail
    if ( !$title_match )
        return $where;

    /**
     * Lets alter the SQL WHERE clause
     *
     * Note, this will be an exact 1 to 1 match, adjust as necessary
     */
    $where .= $wpdb->prepare(
        " AND {$wpdb->posts}.post_title = %s ",
        $title_match
    );

    return $where;
}, 10, 2 );

class WPSE_Get_Duplicate_Post_titles extends WP_Widget 
{

    public function __construct() 
    {
        parent::__construct(
            \'widget_get_duplicate_post_titles\', 
            _x( \'Post Title duplicates\', \'Post Title duplicates\' ), 
            [ \'description\' => __( \'Displays posts which share the same post title.\' ) ] 
        );
        $this->alt_option_name = \'widget_get_duplicate_post_titles\';

        add_action( \'save_post\',    [$this, \'flush_widget_cache\'] );
        add_action( \'deleted_post\', [$this, \'flush_widget_cache\'] );
        add_action( \'switch_theme\', [$this, \'flush_widget_cache\'] );
    }

    public function widget( $args, $instance ) 
    {
        $cache = [];
        if ( ! $this->is_preview() ) {
            $cache = wp_cache_get( \'widget_bpfi\', \'widget\' );
        }

        if ( ! is_array( $cache ) ) {
            $cache = [];
        }

        if ( ! isset( $args[\'widget_id\'] ) ) {
            $args[\'widget_id\'] = $this->id;
        }

        if ( isset( $cache[ $args[\'widget_id\'] ] ) ) {
            echo $cache[ $args[\'widget_id\'] ];
            return;
        }

        ob_start();

        $title          = ( ! empty( $instance[\'title\'] ) ) ? $instance[\'title\'] : __( \'Post Title Duplicates\' );
        /** This filter is documented in wp-includes/default-widgets.php */
        $title          = apply_filters( \'widget_title\', $title, $instance, $this->id_base );

        // ADD YOUR CUSTOM PHP CODE HERE FOR EXECUTION TO DISPLAY ON FRONT END
        // First make sure this a single post page
        if ( is_single() ) { // We are on a single page
            // Get the current post object
            $post_object = $GLOBALS[\'wp_the_query\']->get_queried_object();

            // Run our query to get the posts with duplicate titles
            $args = [
                \'posts_per_page\'   => -1, // Get all posts
                \'post_type\'        => \'post\',
                \'wpse_title_match\' => $post_object->post_title,
                \'post__not_in\'     => [$post_object->ID], // Exclude current post
                \'tax_query\'        => [
                    [
                        \'taxonomy\' => \'category\',
                        \'field\'    => \'slug\',
                        \'terms\'    => \'chroniques\'
                    ]
                ],
                // Any other arguments
            ];
            $loop = new WP_Query( $args );

            // Run the loop
            if ( $loop->have_posts() ) {
                while ( $loop->have_posts() ) {
                    $loop->the_post();

                    // Display your posts
                    the_title() . "\\n";

                }
                wp_reset_postdata();
            }
        }

        echo $args[\'after_widget\']; 

        if ( ! $this->is_preview() ) {
            $cache[ $args[\'widget_id\'] ] = ob_get_flush();
            wp_cache_set( \'widget_bpfi\', $cache, \'widget\' );
        } else {
            ob_end_flush();
        }
    }

    public function update( $new_instance, $old_instance ) 
    {
        $instance                   = $old_instance;
        $instance[\'title\']          = strip_tags( $new_instance[\'title\'] );
        $this->flush_widget_cache();

        $alloptions = wp_cache_get( \'alloptions\', \'options\' );
        if ( isset($alloptions[\'widget_get_duplicate_post_titles\']) )
            delete_option(\'widget_get_duplicate_post_titles\');

        return $instance;
    }

    public function flush_widget_cache() 
    {
        wp_cache_delete(\'widget_bpfi\', \'widget\');
    }

    public function form( $instance ) 
    {

        $title      = isset( $instance[\'title\'] ) ? esc_attr( $instance[\'title\'] ) : \'\';
        ?>

        <p>
            <label for="<?php echo $this->get_field_id( \'title\' ); ?>"><?php _e( \'Title:\' ); ?></label>
            <input class="widefat" id="<?php echo $this->get_field_id( \'title\' ); ?>" name="<?php echo $this->get_field_name( \'title\' ); ?>" type="text" value="<?php echo $title; ?>" />
        </p>

    <?php
    }

}

add_action( \'widgets_init\', function () 
{
    register_widget( \'WPSE_Get_Duplicate_Post_titles\' );
});

add_filter( \'sidebars_widgets\', function ( $sidebars_widgets )
{
    // Return our filter when we are on admin screen
    if ( is_admin() )
        return $sidebars_widgets;

    // Make sure we are not on the blog page, if we are, bail
    if ( is_single() )
        return $sidebars_widgets;

    /**
     * Widget we need to target. This should be the name/id we used to register it
     *
     * EXAMPLE
     *   parent::__construct(
            \'widget_get_duplicate_post_titles\', 
            _x( \'Blog Page Featured Image\', \'Blog page featured image\' ), 
            [ \'description\' => __( \'Displays the featured image for the pge set as blog page.\' ) ] 
        );
     *
     */
    $custom_widget  = \'widget_get_duplicate_post_titles\';

    // See if our custom widget exists is any sidebar, if so, get the array index
    foreach ( $sidebars_widgets as $sidebars_key=>$sidebars_widget ) {
        // Skip the wp_inactive_widgets set, we do not need them
        if ( $sidebars_key == \'wp_inactive_widgets\' )
        continue;

        // Only continue our operation if $sidebars_widget are not an empty array
        if ( $sidebars_widget ) {
            foreach ( $sidebars_widget as $k=>$v ) {

                /**
                 * Look for our custom widget, if found, unset it from the $sidebars_widgets array
                 * @see stripos()
                 */
                if ( stripos( $v, $custom_widget ) !== false ) 
                    unset( $sidebars_widgets[$sidebars_key][$k] );
            } // endforeach $sidebars_widget
        } // endif $sidebars_widget
    } // endforeach $sidebars_widgets

    return $sidebars_widgets;
});
编辑可以通过查看content.php 在其中一个捆绑主题中创建模板部分。