J'ai écrit un widget personnalisé et je souhaite afficher deux instances du même widget dans la même zone. Lorsque je glisse et dépose une nouvelle instance de widget dans la zone de widgets du panneau d'administration, que je place de nouvelles données dans des champs personnalisés et que je sauvegarde, lorsque je reviens à la page d'accueil, je vois à la fois les nouveaux et les anciens widgets ayant le même contenu. Je pense que c’est peut-être un problème de fonction update
, mais j’ai écrit à la suite de la documentation wordpress pour que le résultat soit le même. Voici le code:
functions.php
/**
* Register new custom wiget
*/
class Sole_Source_Main_Widget extends WP_Widget {
public function __construct() {
$widget_options = array(
'classname' => 'sole_source_main_widget',
'description' => 'Main content widget'
);
parent::__construct('sole_source_main_widget', 'Sole Source Widget', $widget_options);
}
//back-end display
public function update( $new_instance, $old_instance ) {
$instance = $old_instance;
$instance['title'] = ( ! empty( $new_instance['title'] ) ) ? strip_tags( $new_instance['title'] ) : '';
$instance['description'] = ( ! empty( $new_instance['description'] ) ) ? strip_tags( $new_instance['description'] ) : '';
$instance['image'] = ( ! empty( $new_instance['image'] ) ) ? strip_tags( $new_instance['image'] ) : '';
return $instance;
}
public function form( $instance ) {
$title = ! empty( $instance['title'] ) ? $instance['title'] : ''; ?>
<?php $description = ! empty( $instance['description'] ) ? $instance['description'] : ''; ?>
<?php $image = ! empty( $instance['image'] ) ? $instance['image'] : ''; ?>
<p>
<label for="<?php echo $this->get_field_id( 'title' ); ?>">Title:</label>
<input type="text" id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" value="<?php echo esc_attr( $title ); ?>" />
<label for="<?php echo $this->get_field_id( 'description' ); ?>">Description:</label>
<input type="text" id="<?php echo $this->get_field_id( 'description' ); ?>" name="<?php echo $this->get_field_name( 'description' ); ?>" value="<?php echo esc_attr( $description ); ?>" />
<label for="<?php echo $this->get_field_id( 'image' ); ?>">Image URL:</label>
<input type="text" id="<?php echo $this->get_field_id( 'image' ); ?>" name="<?php echo $this->get_field_name( 'image' ); ?>" value="<?php echo esc_attr( $image ); ?>" />
</p><?php
}
//front-end display
public function widget( $args, $instance ) {
$title = apply_filters( 'widget_title', $instance[ 'title' ] );
$description = apply_filters('widget_title', $instance['description']);
$image = apply_filters('widget_title', $instance['image']);
?>
<?php echo $args['before_widget'] . $args['before_title']; ?> <img src="<?php echo $image; ?>"></img> <?php $args['after_title']; ?>
<?php echo $args['before_widget'] . $args['before_title'] . $title . $args['after_title']; ?>
<?php echo $args['before_widget'] . $args['before_title'] . $description . $args['after_title']; ?>
<?php echo $args['after_widget'];
}
}
add_action('widgets_init', function() {
register_widget('Sole_Source_Main_Widget');
});
sidebar.php
<aside id="secondary" class="widget-area col-sm-12 col-md-12 col-lg-12" role="complementary">
<div class="col-lg-6 col-md-12">
<?php dynamic_sidebar( 'main-widget' ); ?>
</div>
<div class="col-lg-6 col-md-12">
<?php dynamic_sidebar( 'main-widget' ); ?>
</div>
</aside><!-- #secondary -->
Je ne vois rien de mal avec la classe de widgets. Le problème que vous avez est que vous affichez la zone du widget, qui contient les widgets, deux fois dans votre sidebar.php
:
<aside id="secondary" class="widget-area col-sm-12 col-md-12 col-lg-12" role="complementary">
<div class="col-lg-6 col-md-12">
<?php dynamic_sidebar( 'main-widget' ); // this will display all the widgets in your main-widget sidebar ?>
</div>
<div class="col-lg-6 col-md-12">
<?php dynamic_sidebar( 'main-widget' ); // this will display again all the widgets in your main-widget sidebar ?>
</div>
</aside><!-- #secondary -->
Le second widget de chaque barre latérale est probablement caché à cause de CSS, mais je parie qu'il est là, deux fois, une à gauche et une à droite.
Donc, n'appelez pas dynamic_sidebar( 'main-widget' );
deux fois.
D'après ce que j'ai compris, vous voulez inclure les widgets dans certaines divs afin de pouvoir les placer sur deux colonnes. Pour cela, vous devez filtrer les paramètres before-widget
et after-widget
de chaque widget via le filtre dynamic_sidebar_params
. Ou, mieux encore, vous pourriez utiliser du CSS pour faire l'affaire.
Voici un code de démarrage PHP qui ajoutera des wrappers à chaque widget de votre zone de widget cible:
/**
* @param array $params
*/
function sole_add_widget_columns_wrapper( $params ) {
// Add the opening wrapper tag
$params[0]['before_widget'] = PHP_EOL . '<div class="col-lg-6 col-md-12">' . PHP_EOL . $params[0]['before_widget'];
// Add the closing wrapper tag
$params[0]['after_widget'] = $params[0]['after_widget'] . PHP_EOL . '</div><!-- close wrapper -->' . PHP_EOL;
}
/**
* @param string $index
*/
function sole_handle_main_widget_area_columns( $index ) {
// We only want to deal with the main widget area
if ( 'main-widget' !== $index ) {
return;
}
// Filter each widget params and add the wrappers
add_filter( 'dynamic_sidebar_params', 'sole_add_widget_columns_wrapper', 10, 1 );
// Hook an action to remove the filter above after we are done with this widget area.
// This way we don't affect other widget area that may come, on the same page, after this one.
add_action( 'dynamic_sidebar_after', 'sole_remove_main_widget_area_columns_filter', 10 );
}
add_action( 'dynamic_sidebar_before', 'sole_handle_main_widget_area_columns', 10 );
function sole_remove_main_widget_area_columns_filter() {
remove_filter( 'dynamic_sidebar_params', 'sole_add_widget_columns_wrapper', 10 );
}
Ce code encapsulera chaque widget, il ne mettra pas les widgets pairs et impairs dans deux wrappers de colonnes.