web-dev-qa-db-fra.com

Comment mettre à jour l'aperçu lorsque le paramètre personnalisé a été modifié dans mon widget personnalisé

J'ai décidé de trop utiliser un widget et de lui ajouter des paramètres personnalisés.

L'apparence du widged est contrôlée par la fonction javascript (j'utilise le slick slider ici, qui est supposé être configurable via les paramètres du widget)

Voici donc la classe de widgets: (comme exemple d'ici http://www.wpbeginner.com/wp-tutorials/how-to-create-a-custom-wordpress-widget/ )

 <?php

// Creating the widget
class wpb_widget extends WP_Widget
{

    function __construct()
    {
        parent::__construct(
        // Base ID of your widget
        'wpb_widget',

        // Widget name will appear in UI
        __('WPBeginner Widget', 'wpb_widget_domain'),

        // Widget description
        array(
        'description' => __( 'Sample widget based on WPBeginner Tutorial', 'wpb_widget_domain' ),
        'customize_selective_refresh' => true,
        )
            );


             // Enqueue style if widget is active (appears in a sidebar) or if in Customizer preview.
        if ( is_active_widget( false, false, $this->id_base ) || is_customize_preview() ) {
            add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
        }
    }

// Creating widget front-end

    public function widget($args, $instance)
    {
        $title = apply_filters( 'widget_title', $instance['title'] );

        // before and after widget arguments are defined by themes
        echo $args['before_widget'];
        if (! empty( $title )) {
            echo $args['before_title'] . $title . $args['after_title'];
        }

        // This is where you run the code and display the output
        echo __( 'Hello, World!', 'wpb_widget_domain' );
        echo("<div id='customId'>TEST</div>");
        echo $args['after_widget'];

    }

// Widget Backend 
    public function form($instance)
    {
        if (isset( $instance[ 'title' ] )) {
            $title = $instance[ 'title' ];
        } else {
            $title = __( 'New title', 'wpb_widget_domain' );
        }
        // Widget admin form
        ?>
    <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 esc_attr( $title ); ?>" 
        />
    </p>
<?php

}

public function enqueue_scripts() {

    $randomParameter =  random_int(1, 100);

    $dataToBePassed = array(
        'someParameter' => $randomParameter
    );

    wp_enqueue_script(
        'customjs',
        get_template_directory_uri() . '/js/customwidget.js',
        array( 'jquery','customize-preview' ),
        '',
        true
    );

    wp_localize_script('customjs', 'settings', $dataToBePassed);
}


    // Updating widget replacing old instances with new
    public function update($new_instance, $old_instance)
    {
        $instance = array();
        $instance['title'] = ( ! empty( $new_instance['title'] ) ) ? strip_tags( $new_instance['title'] ) : '';
        return $instance;
    }
} // Class wpb_widget ends here

voici un exemple de js lié:

(function ($) {
    console.log("custom widget js init");

    var configureCustomWidget = function(){
        var me = this,
            conf = settings || {someParameter:5};

        $('#customId').html("<h1>"+conf.someParameter+"</h1>");
    }

    configureCustomWidget();

    // Short-circuit selective refresh events if not in customizer preview or pre-4.5.
    if ('undefined' === typeof wp || !wp.customize || !wp.customize.selectiveRefresh) {
        return;
    }

    // Re-load widgets when a partial is rendered.
    wp.customize.selectiveRefresh.bind('partial-content-rendered', function (placement) {
        debugger;
    });

    // Refresh a moved partial containing 
    wp.customize.selectiveRefresh.bind('partial-content-moved', function (placement) {
        debugger;
    });

})(jQuery);

Sur la prévisualisation, tout va bien, mais le problème est que même si j’ai respecté les recommandations https://make.wordpress.org/core/2016/03/22/implementing- sélectif-refresh-support-pour-widgets/

ce n'est tout simplement pas réglé, car le script initialisé pour une raison quelconque wp.customize.selectiveRefresh n'est pas défini.

Comme ici: enter image description here

Donc, des idées sur la façon dont je peux basculer le widget lié javascript sur le changement de paramètre?

P.S.

C'est simplement simplifié, il y aura une option supplémentaire et je veux changer, disons simplement des champs de texte, nommés 'customId'. Et sur le changement, je veux qu’il fasse des changements en HTML, comme changer du style, etc.

UPD:

(histoire)

Tout d'abord, je crée le thème du site wordpress.

Ce thème devrait contenir des widgets.

L'un des widgets suppose une extension à partir des listes de catégories de produits woocommerce. Mais la liste des catégories de produits par défaut a obtenu le résultat comme une simple liste à puces avec description et photo.

Donc, pour le rendre plus chic, j'ai décidé de le faire ressembler à un curseur. Décidé d'utiliser une petite bibliothèque Js pour cela, nommé Slick

Et le truc, c'est qu'il est vraiment flexible et pourrait être configuré, par exemple, comme ça:

$('.myCustomSlider').slick({
  slidesToShow: 3,
  slidesToScroll: 1,
  autoplay: true
});

Et donc, j'ai décidé d'ajouter à mon widget des options comme vous pouvez le voir dans l'objet js ici, donc Slides to show, Slides to scroll etc.

Je pensais que sur l'écran de personnalisation du thème, ce serait bien, lorsque l'utilisateur modifierait la valeur de ces options et pourrait voir comment les changements se produisaient.

(implémentation)

Pour ne pas rendre cette question vraiment large - le code complet est ici

Donc, tout d’abord, dans mon thème, j’ai redéfini le widget product category par défaut. Les modifications étaient simples: il suffisait d’ajouter des paramètres personnalisés à un script de curseur:

 public function __construct()
    {
        $extraSettings = array(
          'slidesCount'  => array(
              'type'  => 'number',
              'step'  => 1,
              'min'   => 1,
              'max'   => '',
              'std'   => 3,
              'label' => __( 'Slides count per page', 'woocommerce' ),
          )
        );

        parent::__construct();

        $this->settings = array_merge($this->settings, $extraSettings);

         // To call script for the slider.
         if ( is_active_widget( false, false, $this->id_base ) || is_customize_preview() ) {
            add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
        }
    }

aussi, changé <ul> en <div class="product-categories slider"> comme ça

echo '<div class="product-categories slider">';

wp_list_categories( apply_filters( 'woocommerce_product_categories_widget_args', $list_args ) );

echo '</div>';

J'ai aussi écrasé le walker par défaut du widget (mais je viens de faire des changements dans la sortie des choses html) comme <li> à <div class='slide'>

Et puis il y a mon js personnalisé avec bind aux événements mentionnés ici .

Cela fonctionne un une fois chargé. Mais quand je change quelque chose, il n’ya aucune réaction là-bas. Et la raison est la même que celle décrite ci-dessus -wp.customize.selectiveRefresh n'est pas défini.

Mais la question principale est de savoir comment mettre à jour la partie client après la mise à jour de mes paramètres de widget personnalisés/surchargés.

J'espère que cela a clarifié certaines choses :)

1
Danil Gholtsman

En tant que rôle de pouce, vous ne devez pas étendre les widgets que vous ne contrôlez pas, à moins que leur auteur leur ait spécifiquement indiqué comment le faire. L'extension est un peu plus facile du côté PHP, mais il est plus difficile d'étendre l'interface utilisateur avec JS si les installations ne sont pas mises en place à l'avance.

Une méthode plus sûre (du moins du point de vue de la facilité de développement) consiste à "fourchir" le code du widget. Prenez le code, apportez les modifications nécessaires et appelez le widget sous un nouveau nom. Vous pouvez également modifier le nom "officiel" en fonction de vos besoins (annulez l'enregistrement de l'original et enregistrez le vôtre sous le même identifiant).

Cela signifie qu'avec chaque nouvelle version de WC, vous devrez vous assurer que vous n'avez pas besoin de mettre à jour votre code pour refléter un changement dans le widget "original", mais vous auriez probablement dû le faire même si vous étiez juste "étendre".

1
Mark Kaplun