J'essaie d'afficher dans un widget php de la barre latérale, tous les messages avec le même post_title dans une catégorie spécifique. Je trouve ce code sur Internet mais je ne sais pas comment l'utiliser. Merci pour votre aide.
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;
}
Edit: Voici le code actuel que j'utilise.
<?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;
});
Permet d’utiliser les fonctionnalités intégrées que WordPress a à offrir. Il n'est presque toujours pas conseillé d'utiliser du SQL personnalisé chaque fois que WordPress propose des fonctions natives pour effectuer le travail spécifique.
Pour interroger nos publications, nous utiliserons WP_Query
. Le seul problème est que WP_Query
ne prend pas en charge la fonctionnalité permettant de rechercher des publications avec certains titres. Heureusement, nous pouvons filtrer la requête SQL de construction juste avant qu'elle interroge la base de données. Pour cela, nous allons utiliser le filtre posts_where
pour introduire notre propre paramètre personnalisé, wpse_title_match
( et non, cela n’a rien à voir avec la lutte ).
Nous devons ajouter les éléments suivants dans un plugin ( recommandé ) ou dans votre fichier de fonctions de thèmes.
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 );
À ce stade, il sera préférable de vous construire un widget approprié que de tout laisser tomber dans un widget php
Voici un plugin de widget modifié que j'ai récemment fait ici
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' );
});
Ce que j'aime aussi faire est de toujours supprimer complètement un widget lorsqu'il est totalement hors contexte pour éviter que la barre latérale ne restitue un espace vide lorsqu'aucun autre widget n'est affiché.
Nous pouvons essayer la même approche que celle que j'ai décrite ici . Vous pouvez simplement ajouter ceci au bas du plugin
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;
});
Tout le code ci-dessus est non testé et nécessite PHP 5.4+
Vous devez ajuster les arguments WP_Query
du widget en fonction de vos besoins. Partout où j'ai ajouté des valeurs en majuscules, vous devez renseigner les valeurs appropriées
Les deux fonctions de filtre peuvent être ajoutées dans le même plugin, ainsi le plugin complet ressemblera à ceci
<?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;
});
Vous pouvez étendre le code dans la boucle en consultant le code source des parties du modèle content.php
dans l'un des thèmes fournis.