让我们使用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
在其中一个捆绑主题中创建模板部分。