web-dev-qa-db-fra.com

Comment créer un widget n'autorisant qu'une seule instance?

Comment créer un widget qui ne permet d'ajouter qu'une seule instance d'un widget via l'interface Wordpress?

Le comportement par défaut des widgets permet d'ajouter plusieurs instances.

J'utilise l'exemple de code de http://codex.wordpress.org/Widgets_API

J'ai vu une question similaire où la réponse était d'utiliser l'ancien code de widget, mais j'aimerais continuer à utiliser ce code plus moderne si possible.

J'ai vu des plugins tels que Twitter pour Wordpress qui donnent un contrôle exact sur le nombre d'instances autorisées.

Merci,
mat

3
Matt Sephton

Basculer après la 1ère instance et abandonner

Dans l'exemple suivant, vous pouvez trouver une variable static qui n'est pas définie sur la première instance. Si le widget est appelé pour la première fois, nous le définissons sur true. Lors de la deuxième exécution, nous abandonnons et return sans rien servir à l'utilisateur.

class My_Widget extends WP_Widget {
    // You static instance switch
    static $instance;

    function My_Widget() {
            // We set the static class var to true on the first run
            if ( ! $this->instance ) {
                    $this->instance = true;
            } 
            // abort silently for the second instance of the widget
            else {
                    return;
            }
        // widget actual processes
    }
    function form($instance) {
        // outputs the options form on admin
    }
    function update($new_instance, $old_instance) {
        // processes widget options to be saved
    }
    function widget($args, $instance) {
        // outputs the content of the widget
    }
}
register_widget('My_Widget');

Code tiré de l'article du Codex associé de l'API Widgets


Gestion du tableau de widgets globaux

Une autre option pourrait être de vérifier le tableau global contenant tous les widgets enregistrés:

function wpse32103_show_widgets()
{
    $dump  = '<pre>';
    $dump .= var_export( $GLOBALS['wp_registered_widgets'], false );
    $dump .= '</pre>';

    return print $dump;
}
add_action( 'shutdown', 'wpse32103_show_widgets' );

La sortie du tableau associatif contient le nom en tant que clé, ajouté par -2 (le numéro est incrémenté). Vous pouvez effectuer une recherche dans le tableau à l'aide du crochet init ou admin_init et simplement désélectionner si vous avez trouvé une deuxième instance. Peut-être quelque chose comme ce qui suit:

function wpse32103_show_widgets()
{
        global $wp_registered_widgets;

        // Go and search for your widgets name with the above written function
        $target = 'FILL IN YOUR FOUND ARRAY KEY HERE. Without -2 (or any other appending number)';

        // Container for your targeted widget(s)
        $unsets = array();
        foreach ( array_keys( $wp_registered_widgets ) as $widget )
        {
            // remove dashes
            $widget_check = str_replace( '-', '', $widget );
            // remove numbers
            $widget_check = preg_replace( '/[^0-9]/', '', $widget );

            // if we match, do it in our container
            if ( $widget_check === $target )
                $unsets[] = $widget;
        }

        // less than one element in the container: abort
        if ( ! count ( $unsets ) > 1 )
            return;

        // preserve first element
        array_shift( array_values( $unsets ) );

        // unset all left instances from the global array
        foreach ( $unsets as $unset )
            unset ( $wp_registered_widgets[ $unset ] );

        return;
}
add_action( 'init', 'wpse32103_show_widgets' );
1
kaiser

Edit: Doh, vient de voir que vous ne voulez pas utiliser l'ancien code. Oh bien, je vais le laisser juste au cas où ça aiderait quelqu'un.

WP a ajouté plusieurs widgets dans 2.8 . Donc, j'ai repéré un tutorial qui couvrait la création d'un widget dans WP 2.7. Voici le code:

add_action("widgets_init", array('Widget_name', 'register'));
register_activation_hook( __FILE__, array('Widget_name', 'activate'));
register_deactivation_hook( __FILE__, array('Widget_name', 'deactivate'));
class Widget_name {
  function activate(){
    $data = array( 'option1' => 'Default value' ,'option2' => 55);
    if ( ! get_option('widget_name')){
      add_option('widget_name' , $data);
    } else {
      update_option('widget_name' , $data);
    }
  }
  function deactivate(){
    delete_option('widget_name');
  }
    function control(){
        $data = get_option('widget_name');
        ?>
        <p><label>Option 1<input name="widget_name_option1"
    type="text" value="<?php echo $data['option1']; ?>" /></label></p>
        <p><label>Option 2<input name="widget_name_option2"
    type="text" value="<?php echo $data['option2']; ?>" /></label></p>
        <?php
         if (isset($_POST['widget_name_option1'])){
            $data['option1'] = attribute_escape($_POST['widget_name_option1']);
            $data['option2'] = attribute_escape($_POST['widget_name_option2']);
            update_option('widget_name', $data);
        }
    }
  function widget($args){
    echo $args['before_widget'];
    echo $args['before_title'] . 'Your widget title' . $args['after_title'];
    echo 'I am your widget';
    echo $args['after_widget'];
  }
  function register(){
        wp_register_sidebar_widget( 'my_widget_id', 'Widget name', array('Widget_name', 'widget'));
    wp_register_widget_control( 'my_widget_id', 'Widget name', array('Widget_name', 'control'));
  }
}

J'ai remplacé les appels à register_sidebar_widget et register_widget_control par wp_register_sidebar_widget et wp_register_widget_control respectivement, afin de corriger les avertissements relatifs à l'utilisation de fonctions obsolètes. Sinon, il s'agit d'un simple copier/coller du tutoriel auquel j'ai lié.

1
Dave Romsey

Voici une preuve de concept pour un widget à usage unique dérivé de cette réponse :

https://github.com/glueckpress/single-use-widget

Limitation: Ne fonctionne que dans le Customizer, pas sur la page d'administration du widget.

0
glueckpress