ajouter par programme des widgets aux barres latérales

60

Je voudrais ajouter par programme des widgets à mes deux barres latérales que j'ai. Je n'ai trouvé aucun moyen officiel de le faire?

J'ai commencé à regarder dans la base de données. J'ai constaté que c'est l'option 'sidebars_widgets' qui place les widgets dans les barres latérales. Lorsque vous examinez les options, un nom est ajouté à la fin du nom du widget, par exemple: nom_du_green-6. D'où vient ce nombre?

Avez-vous une idée sur la façon de résoudre ce problème?

    
posée Marlun 22.08.2011 - 13:45

4 réponses

86

Lorsque j'ai commencé cette réponse, il ne devrait s'agir que d'une petite note. Eh bien, j'ai échoué. Pardon! Reste avec moi, il y a un goody caché au fond…

Comment les widgets WordPress sont stockés

La liste des widgets est stockée dans une option nommée 'sidebars_widgets' . Un var_export() peut donner quelque chose comme ce qui suit:

array (
  'wp_inactive_widgets' => 
  array (
  ),
  'top-widget' => 
  array (
  ),
  'bottom-widget' => 
  array (
  ),
  'array_version' => 3,
)

Ignorez 'wp_inactive_widgets' et 'array_version' . Nous n'avons pas à nous soucier de ceux-ci.
Les autres clés sont l'identifiant des barres latérales enregistrées. Dans ce cas, les barres latérales peuvent avoir été enregistrées avec ce code:

// Register two sidebars.
$sidebars = array ( 'a' => 'top-widget', 'b' => 'bottom-widget' );
foreach ( $sidebars as $sidebar )
{
    register_sidebar(
        array (
            'name'          => $sidebar,
            'id'            => $sidebar,
            'before_widget' => '',
            'after_widget'  => ''
        )
    );
}

Par défaut, les barres latérales sont vides après l'enregistrement. Bien sûr.

Pour chaque classe de widget enregistrée, une option distincte est créée, contenant toutes les options nécessaires. L'option est préfixée par la chaîne widget_ . Pour obtenir les options pour tous les widgets RSS actifs, nous devons examiner…

get_option( 'widget_rss' );

Sortie possible:

array (
  2 => 
  array (
    'title' => 'WordPress Stack Exchange',
    'url' => 'http://wordpress.stackexchange.com/feeds',
    'link' => 'http://wordpress.stackexchange.com/questions',
    'items' => 5,
    'show_summary' => 1,
    'show_author' => 0,
    'show_date' => 0,
  ),
)

Notez le nombre 2 . Les arguments de plusieurs instances sont tous stockés dans cette seule option, triés par numéros.

Pour voir quelles classes de widgets sont déjà connues de WordPress, allez à wp-admin/options.php et faites défiler vers le bas jusqu'à ce que vous voyiez quelque chose comme ceci:

Oui,donnéessérialisées.Non,vousnepouvezpasleslireici.Nevousinquiétezpas,vousn'êtespasobligé.

Unwidgetdedémonstration

Pourmieuxillustrerlefonctionnementinterne,j'aiécritunwidgetdedémonstrationtrèssimple:

/***Supersimplewidget.*/classT5_Demo_WidgetextendsWP_Widget{publicfunction__construct(){//id_base,visiblenameparent::__construct('t5_demo_widget','T5DemoWidget');}publicfunctionwidget($args,$instance){echo$args['before_widget'],wpautop($instance['text']),$args['after_widget'];}publicfunctionform($instance){$text=isset($instance['text'])?esc_textarea($instance['text']):'';printf('<textareaclass="widefat" rows="7" cols="20" id="%1$s" name="%2$s">%3$s</textarea>',
            $this->get_field_id( 'text' ),
            $this->get_field_name( 'text' ),
            $text
        );
    }
}

Notez le constructeur: 't5_demo_widget' est le $id_base , l'identifiant de ce widget. Comme vous pouvez le voir sur la capture d'écran, ses arguments sont stockés dans l'option widget_t5_demo_widget . Tous vos widgets personnalisés seront traités comme ceci. Vous n'avez pas à deviner le nom. Et depuis que vous avez écrit vos widgets (probablement), vous connaissez tous les arguments des paramètres ' $instance ' de votre classe.

Principes de base du thème

Vous devez d’abord enregistrer des barres latérales et le widget personnalisé. Il est facile de se souvenir de l’action à prendre à cet égard: 'widgets_init' . Mettez tout dans un conteneur - une classe ou une fonction. Pour plus de simplicité, je vais utiliser une fonction nommée t5_default_widget_demo() .

Tout le code suivant va dans le functions.php . La classe T5_Demo_Widget devrait déjà être chargée. Je viens de le mettre dans le même fichier…

add_action( 'widgets_init', 't5_default_widget_demo' );

function t5_default_widget_demo()
{
    // Register our own widget.
    register_widget( 'T5_Demo_Widget' );

    // Register two sidebars.
    $sidebars = array ( 'a' => 'top-widget', 'b' => 'bottom-widget' );
    foreach ( $sidebars as $sidebar )
    {
        register_sidebar(
            array (
                'name'          => $sidebar,
                'id'            => $sidebar,
                'before_widget' => '',
                'after_widget'  => ''
            )
        );
    }

Jusqu'ici, si simple. Notre thème est maintenant widget prêt, le widget de démonstration est connu. Maintenant le plaisir.

$active_widgets = get_option( 'sidebars_widgets' );

if ( ! empty ( $active_widgets[ $sidebars['a'] ] )
    or ! empty ( $active_widgets[ $sidebars['b'] ] )
)
{   // Okay, no fun anymore. There is already some content.
    return;
}

Vous ne voulez vraiment pas détruire les paramètres utilisateur. S'il y a déjà du contenu dans les barres latérales, votre code ne devrait pas l'exécuter. C’est pourquoi nous nous arrêtons dans ce cas.

D'accord, supposons que les barres latérales soient vides… nous avons besoin d'un compteur:

$counter = 1;

Les widgets sont numérotés . Ces numéros sont des identifiants secondaires pour WordPress.

Demandons au tableau de le changer:

$active_widgets = get_option( 'sidebars_widgets' );

Nous avons aussi besoin d'un compteur (plus à ce sujet plus tard):

$counter = 1;

Et voici comment nous utilisons le compteur, les noms de la barre latérale et les arguments du widget (nous n’avons qu’un argument: text ).

// Add a 'demo' widget to the top sidebar …
$active_widgets[ $sidebars['a'] ][0] = 't5_demo_widget-' . $counter;
// … and write some text into it:
$demo_widget_content[ $counter ] = array ( 'text' => "This works!\n\nAmazing!" );

$counter++;

Notez comment l'identificateur de widget est créé: le id_base , le moins - et le compteur. Le contenu du widget est stocké dans une autre variable $demo_widget_content . Voici le compteur clé et les arguments du widget sont stockés dans un tableau.

Nous incrémentons le compteur de un lorsque nous avons terminé pour éviter les collisions.

C'était facile. Maintenant un widget RSS. Plus de champs, plus de plaisir!

$active_widgets[ $sidebars['a'] ][] = 'rss-' . $counter;
// The latest 15 questions from WordPress Stack Exchange.
$rss_content[ $counter ] = array (
    'title'        => 'WordPress Stack Exchange',
    'url'          => 'http://wordpress.stackexchange.com/feeds',
    'link'         => 'http://wordpress.stackexchange.com/questions',
    'items'        => 15,
    'show_summary' => 0,
    'show_author'  => 1,
    'show_date'    => 1,
);
update_option( 'widget_rss', $rss_content );

$counter++;

Voici quelque chose de nouveau: update_option() ceci stockera l'argument du widget RSS dans une option distincte. WordPress les trouvera automatiquement plus tard.
Nous n’avons pas enregistré les arguments du widget de démonstration car nous avons ajouté une deuxième instance à notre deuxième barre latérale maintenant…

// Okay, now to our second sidebar. We make it short.
$active_widgets[ $sidebars['b'] ][] = 't5_demo_widget-' . $counter;
#$demo_widget_content = get_option( 'widget_t5_demo_widget', array() );
$demo_widget_content[ $counter ] = array ( 'text' => 'The second instance of our amazing demo widget.' );
update_option( 'widget_t5_demo_widget', $demo_widget_content );

… et enregistrez tous les arguments du t5_demo_widget en un instant. Pas besoin de mettre à jour la même option deux fois.

Bien, assez de widgets pour aujourd'hui, sauvons aussi le sidebars_widgets :

update_option( 'sidebars_widgets', $active_widgets );

Maintenant, WordPress saura qu’il existe des widgets enregistrés et où sont stockés les arguments de chaque widget. Un var_export() sur le sidebar_widgets ressemblera à ceci:

array (
  'wp_inactive_widgets' => 
  array (
  ),
  'top-widget' => 
  array (
    0 => 't5_demo_widget-1',
    1 => 'rss-2',
  ),
  'bottom-widget' => 
  array (
    0 => 't5_demo_widget-3',
  ),
  'array_version' => 3,
)

Le complet < a href="https://github.com/toscho/T5-Default-Widget-Demo" title="J'espère vraiment que Chip Bennett ne le verra jamais. J'ai violé toutes les exigences de thème connues."> code :

add_action( 'widgets_init', 't5_default_widget_demo' );

function t5_default_widget_demo()
{
    // Register our own widget.
    register_widget( 'T5_Demo_Widget' );

    // Register two sidebars.
    $sidebars = array ( 'a' => 'top-widget', 'b' => 'bottom-widget' );
    foreach ( $sidebars as $sidebar )
    {
        register_sidebar(
            array (
                'name'          => $sidebar,
                'id'            => $sidebar,
                'before_widget' => '',
                'after_widget'  => ''
            )
        );
    }

    // Okay, now the funny part.

    // We don't want to undo user changes, so we look for changes first.
    $active_widgets = get_option( 'sidebars_widgets' );

    if ( ! empty ( $active_widgets[ $sidebars['a'] ] )
        or ! empty ( $active_widgets[ $sidebars['b'] ] )
    )
    {   // Okay, no fun anymore. There is already some content.
        return;
    }

    // The sidebars are empty, let's put something into them.
    // How about a RSS widget and two instances of our demo widget?

    // Note that widgets are numbered. We need a counter:
    $counter = 1;

    // Add a 'demo' widget to the top sidebar …
    $active_widgets[ $sidebars['a'] ][0] = 't5_demo_widget-' . $counter;
    // … and write some text into it:
    $demo_widget_content[ $counter ] = array ( 'text' => "This works!\n\nAmazing!" );
    #update_option( 'widget_t5_demo_widget', $demo_widget_content );

    $counter++;

    // That was easy. Now a RSS widget. More fields, more fun!
    $active_widgets[ $sidebars['a'] ][] = 'rss-' . $counter;
    // The latest 15 questions from WordPress Stack Exchange.
    $rss_content[ $counter ] = array (
        'title'        => 'WordPress Stack Exchange',
        'url'          => 'http://wordpress.stackexchange.com/feeds',
        'link'         => 'http://wordpress.stackexchange.com/questions',
        'items'        => 15,
        'show_summary' => 0,
        'show_author'  => 1,
        'show_date'    => 1,
    );
    update_option( 'widget_rss', $rss_content );

    $counter++;

    // Okay, now to our second sidebar. We make it short.
    $active_widgets[ $sidebars['b'] ][] = 't5_demo_widget-' . $counter;
    #$demo_widget_content = get_option( 'widget_t5_demo_widget', array() );
    $demo_widget_content[ $counter ] = array ( 'text' => 'The second instance of our amazing demo widget.' );
    update_option( 'widget_t5_demo_widget', $demo_widget_content );

    // Now save the $active_widgets array.
    update_option( 'sidebars_widgets', $active_widgets );
}

Si vous allez à wp-admin/widgets.php , vous verrez maintenant trois widgets prédéfinis:

Et c'est tout. Utilisez…

dynamic_sidebar( 'top-widget' );
dynamic_sidebar( 'bottom-widget' );

… pour imprimer les widgets.

Il y a un petit problème: vous devez charger le serveur frontal deux fois pour l'enregistrement initial. Si quelqu'un peut aider ici, je vous en serai très reconnaissant.

    
réponse donnée fuxia 04.05.2012 - 04:23
3

Merci de partager votre solution. J'ai utilisé ce qui a été décrit dans cette question pour créer un morceau de code qui peut être utilisé pour initialiser très facilement des barres latérales. C'est très flexible, vous pouvez créer autant de widgets que vous voulez sans avoir à modifier le code. Utilisez simplement les crochets de filtre et passez des arguments dans un tableau. Voici le code commenté:

function initialize_sidebars(){

  $sidebars = array();
  // Supply the sidebars you want to initialize in a filter
  $sidebars = apply_filters( 'alter_initialization_sidebars', $sidebars );

  $active_widgets = get_option('sidebars_widgets');

  $args = array(
    'sidebars' => $sidebars,
    'active_widgets' => $active_widgets,
    'update_widget_content' => array(),
  );

  foreach ( $sidebars as $current_sidebar_short_name => $current_sidebar_id ) {

    $args['current_sidebar_short_name'] = $current_sidebar_short_name;
    // we are passing our arguments as a reference, so we can modify their contents
    do_action( 'your_plugin_sidebar_init', array( &$args ) );

  }
  // we only need to update sidebars, if the sidebars are not initialized yet
  // and we also have data to initialize the sidebars with
  if ( ! empty( $args['update_widget_content'] ) ) {

    foreach ( $args['update_widget_content'] as $widget => $widget_occurence ) {

      // the update_widget_content array stores all widget instances of each widget
      update_option( 'widget_' . $widget, $args['update_widget_content'][ $widget ] );

    }
    // after we have updated all the widgets, we update the active_widgets array
    update_option( 'sidebars_widgets', $args['active_widgets'] );

  }

}

Il s'agit d'une fonction d'assistance qui vérifie si la barre latérale contient déjà du contenu:

function check_sidebar_content( $active_widgets, $sidebars, $sidebar_name ) {

  $sidebar_contents = $active_widgets[ $sidebars[ $sidebar_name ] ];

  if ( ! empty( $sidebar_contents ) ) {

    return $sidebar_contents;

  }

  return false;

}

Nous devons maintenant créer une fonction liée à l'action "sidebar_init".

add_action( 'your_plugin_sidebar_init', 'add_widgets_to_sidebar' );

function add_widgets_to_sidebar( $args ) {

  extract( $args[0] );

  // We check if the current sidebar already has content and if it does we exit
  $sidebar_element = check_sidebar_content( $active_widgets, $sidebars, $current_sidebar_short_name );

  if ( $sidebar_element !== false  ) {

    return;

  }

  do_action( 'your_plugin_widget_init', array( &$args ) );

}

Et maintenant l'initialisation du widget:

add_action( 'your_plugin_widget_init', 'your_plugin_initialize_widgets' );

function your_plugin_initialize_widgets( $args ) {

  extract( $args[0][0] );

  $widgets = array();

  // Here the widgets previously defined in filter functions are initialized,
  // but only those corresponding to the current sidebar 
  $widgets = apply_filters( 'alter_initialization_widgets_' . $current_sidebar_short_name, $widgets );

  if ( ! empty( $widgets ) ) {

    do_action( 'create_widgets_for_sidebar', array( &$args ), $widgets );

  }

}

La dernière action consiste à créer les widgets dans chaque barre latérale:

add_action( 'create_widgets_for_sidebar', 'your_plugin_create_widgets', 10, 2 );

function your_plugin_create_widgets( $args, $widgets ) {

  extract( $args[0][0][0] );

  foreach ( $widgets as $widget => $widget_content ) {

    // The counter is increased on a widget basis. For instance, if you had three widgets,
    // two of them being the archives widget and one of the being a custom widget, then the
    // correct counter appended to each one of them would be archive-1, archive-2 and custom-1.
    // So the widget counter is not a global counter but one which counts the instances (the
    // widget_occurrence as I have called it) of each widget.
    $counter = count_widget_occurence( $widget, $args[0][0][0]['update_widget_content'] );

    // We add each instance to the active widgets...
    $args[0][0][0]['active_widgets'][ $sidebars[ $current_sidebar_short_name ] ][] = $widget . '-' . $counter;

    // ...and also save the content in another associative array.
    $args[0][0][0]['update_widget_content'][ $widget ][ $counter ] = $widget_content;

  }

}

Cette fonction permet de savoir combien d'instances d'un widget spécifique ont déjà été définies:

function count_widget_occurence( $widget, $update_widget_content ) {

  $widget_occurrence = 0;

  // We look at the update_widget_content array which stores each
  // instance of the current widget with the current counter in an 
  // associative array. The key of this array is the name of the 
  // current widget.
      // Having three archives widgets for instance would look like this:
      // 'update_widget_content'['archives'] => [1][2][3] 
  if ( array_key_exists( $widget, $update_widget_content ) ) {

    $widget_counters = array_keys( $update_widget_content[ $widget ] );

    $widget_occurrence = end( $widget_counters );

  }

  $widget_occurrence++;

  return $widget_occurrence;

}

La dernière chose à faire est d’attribuer des valeurs. Utilisez les fonctions de filtrage suivantes:

add_filter( 'alter_initialization_sidebars', 'current_initialization_sidebars' ) ;
// Use this filter hook to specify which sidebars you want to initialize
function current_initialization_sidebars( $sidebars ) {

  // The sidebars are assigned in this manner.
  // The array key is very important because it is used as a suffix in the initialization function
  // for each sidebar. The value is what is used in the html attributes.
  $sidebars['info'] = 'info-sidebar';

  return $sidebars;

}

Et:

add_filter( 'alter_initialization_widgets_info', 'current_info_widgets' );
// Add a filter hook for each sidebar you have. The hook name is derived from
// the array keys passed in the alter_initialization_sidebars filter. 
// Each filter has a name of 'alter_initialization_widgets_' and the array 
// key appended to it.

function current_info_widgets( $widgets ) {
  // This filter function is used to add widgets to the info sidebar. Add each widget
  // you want to assign to this sidebar to an array.

  return $widgets = array(
    // Use the name of the widget as specified in the call to the WP_Widget constructor
    // as the array key.

    // The archives widget is a widget which is shipped with wordpress by default.
    // The arguments used by this widget, as all other default widgets, can be found
    // in wp-includes/default-widgets.php. 

    'archives' => array(
      // Pass in the array options as an array
      'title' => 'Old Content',
      'dropdown' => 'on',
      // The 'on' value is arbitrarily chosen, the widget actually only checks for
      // a non-empty value on both of these options
      'count' => 'on',
    ),
 );

}

Idéalement, vous appelez initialize_sidebars dans une fonction de configuration appelée lors de l'activation d'un plugin ou d'un thème, comme ceci: Activation du thème:

add_action( 'after_switch_theme', 'my_activation_function' );
function my_activation_function() {
  initialize_sidebars();
}

Activation du plugin:

register_activation_hook( __FILE__, 'my_activation_function' );
function my_activation_function() {
  initialize_sidebars();
}

Pour résumer l’utilisation de ce conglomérat de fonctions:

  1. crée une fonction qui initialise les barres latérales liées au filtre "alter_initialization_sidebars".

  2. crée une fonction pour chaque barre latérale que vous venez d'ajouter qui est reliée au filtre 'alter_initialization_widgets_ $ sidebarname'. Remplacez $ sidebarname par le nom de chaque barre latérale créée à l'étape 1.

Vous pouvez également simplement copier ce code non commenté dans votre fichier de fonctions et commencer à créer immédiatement vos fonctions de filtrage: Code sur pastie (sans fonctions de filtrage d'initialisation)

    
réponse donnée BdN3504 12.10.2014 - 14:25
2

Tout d’abord, merci à @toscho pour la réponse détaillée.

Ceci est un exemple simple pour ceux qui recherchent une solution simple et des options de widget par défaut:

$active_sidebars = get_option( 'sidebars_widgets' ); //get all sidebars and widgets
$widget_options = get_option( 'widget_name-1' );
$widget_options[1] = array( 'option1' => 'value', 'option2' => 'value2' );

if(isset($active_sidebars['sidebar-id']) && empty($active_sidebars['sidebar-id'])) { //check if sidebar exists and it is empty

    $active_sidebars['sidebar-id'] = array('widget_name-1'); //add a widget to sidebar
    update_option('widget_name-1', $widget_options); //update widget default options
    update_option('sidebars_widgets', $active_sidebars); //update sidebars
}

Remarque 1: vous pouvez obtenir sidebar-id en allant dans le menu des widgets et en inspectant la barre latérale souhaitée. Le premier enfant <div id="widgets-holder-wrap"> <div> a le sidebar-id .

Note 2: Vous pouvez obtenir le widget_name aller dans le menu des widgets et inspecter le widget voulu. Vous verrez quelque chose comme <div id="widget-6_widget_name-__i__" class="widget ui-draggable"> .

Je souhaite que cela aide.

    
réponse donnée Manolo 19.08.2014 - 10:59
0

Voici comment vous le faites:

(ATTENTION, cela pourrait ENLEVER tous les widgets précédents si vous ne les remettiez pas dans le tableau widgets .)

    $widgets = array(
    'middle-sidebar' => array(
        'widget_name'
    ),
    'right-sidebar' => array(
        'widget2_name-1'
    )
);
update_option('sidebars_widgets', $widgets);

Le numéro-peut être utilisé si vous souhaitez ajouter ultérieurement des options au widget avec quelque chose comme ceci:

    update_option('widget_widget_name', array(
    1 => array(
        'title' => 'The tile',
        'number' => 4
    ),
    '_multiwidget' => 1
));
    
réponse donnée its_me 10.03.2017 - 06:25

Lire d'autres questions sur les étiquettes