Je voudrais ajouter par programme des widgets à mes deux barres latérales que j'ai. Je n'ai pas trouvé de moyen officiel de le faire?
J'ai commencé à chercher 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?
Une idée pour réparer ceci?
Quand j'ai commencé cette réponse, cela ne devrait être qu'une petite note. Eh bien, j'ai échoué. Pardon! Reste avec moi, il y a un goody caché au fond…
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,
)
Ignorer '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ée par nombre.
Pour voir quelles classes de widgets sont déjà connues de WordPress, allez à wp-admin/options.php
et faites défiler jusqu'à ce que vous voyiez quelque chose comme ceci:
Oui, données sérialisées. Non, vous ne pouvez pas les lire ici. Ne t'inquiète pas, tu n'es pas obligé.
Pour mieux illustrer le fonctionnement interne, j'ai écrit un widget de démonstration très simple:
/**
* Super simple widget.
*/
class T5_Demo_Widget extends WP_Widget
{
public function __construct()
{ // id_base , visible name
parent::__construct( 't5_demo_widget', 'T5 Demo Widget' );
}
public function widget( $args, $instance )
{
echo $args['before_widget'], wpautop( $instance['text'] ), $args['after_widget'];
}
public function form( $instance )
{
$text = isset ( $instance['text'] )
? esc_textarea( $instance['text'] ) : '';
printf(
'<textarea class="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 puisque vous avez écrit vos widgets (probablement), vous connaissez tous les arguments des paramètres $instance
de votre classe.
Vous devez d’abord enregistrer des barres latérales et le widget personnalisé. Il est facile de se rappeler l’action appropriée à suivre: '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 l'amusement.
$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.
OK, supposons que les barres latérales sont vides… nous avons besoin d'un compteur:
$counter = 1;
Les widgets sont numérotés. Ces numéros sont des identifiants secondaires pour WordPress.
Voyons le tableau pour 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 (eh bien, 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
, un 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 séparée. 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 pour le t5_demo_widget
dans une seule course. Pas besoin de mettre à jour la même option deux fois.
Et bien, assez de widgets pour aujourd'hui, sauvegardons 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,
)
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
maintenant, vous verrez trois widgets prédéfinis:
Et c'est tout. Utilisation …
dynamic_sidebar( 'top-widget' );
dynamic_sidebar( 'bottom-widget' );
… Pour imprimer les widgets.
Il y a un petit problème: vous devez charger le front-end deux fois pour l'enregistrement initial. _ {Si quelqu'un peut aider ici, je vous en serai très reconnaissant.} _
Merci de partager votre solution. J'ai utilisé ce qui a été décrit dans cette question pour créer un morceau de code pouvant ê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 filtre 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 suit: Activation de 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:
créez une fonction qui initialise les barres latérales qui est reliée au filtre 'alter_initialization_sidebars'.
créez 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)
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
dans le menu des widgets et inspecter la barre latérale souhaitée. Le premier enfant <div id="widgets-holder-wrap">
de <div>
a le sidebar-id
.
Remarque 2: Vous pouvez obtenir le widget_name
dans le menu des widgets et inspecter le widget souhaité. Vous verrez quelque chose comme <div id="widget-6_widget_name-__i__" class="widget ui-draggable">
.
Je souhaite que cela aide.
Voici comment vous le faites:
(ATTENTION, cela pourrait ENLEVER tous les widgets précédents si vous ne les avez pas remis 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:
update_option('widget_widget_name', array(
1 => array(
'title' => 'The tile',
'number' => 4
),
'_multiwidget' => 1
));