Adicione adicionalmente widgets a barras laterais

Gostaria de adicionar widgets por programação às minhas duas barras laterais que eu tenho. Não consegui encontrar nenhuma maneira oficial de fazer isso?

Comecei a procurar o database. Descobri que é a opção ‘sidebars_widgets’ que coloca widgets em barras laterais. Ao olhar para as opções, os nomes dos widgets possuem um número adicionado ao final como: widget_name-6. De onde vem esse número?

Alguma ideia de como consertar isso?

Solutions Collecting From Web of "Adicione adicionalmente widgets a barras laterais"

Quando eu comecei essa resposta, deveria ser apenas uma pequena nota. Bem, eu falhei. Desculpa! Fique comigo, há um bem escondido no fundo …

Como os widgets do WordPress estão armazenados

A lista de widgets é armazenada em uma opção chamada 'sidebars_widgets' . Um var_export() pode dar algo como o seguinte:

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

Ignore 'wp_inactive_widgets' e 'array_version' . Não precisamos nos preocupar com isso.
As outras chaves são identificadores para barras laterais registradas. Neste caso, as barras laterais podem ter sido registradas com este código:

 // 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' => '' ) ); } 

Por padrão, as barras laterais estão vazias após o registro. Claro.

Para cada class de widget registrada é criada uma opção separada, contendo todas as opções necessárias. A opção é prefixada pelo widget_ . Para obter as opções para todos os widgets RSS ativos, temos que analisar …

 get_option( 'widget_rss' ); 

Possível saída:

 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, ), ) 

Observe o número 2 . Os argumentos para várias instâncias são todos armazenados nesta opção, ordenada por números.

Para ver quais classs de widgets já são conhecidas pelo WordPress, vá para wp-admin/options.php e role para baixo até ver algo como isto:

captura de tela de opções de widget serializadas

Sim, dados serializados. Não, você não pode ler aqueles aqui. Não se preocupe, você não precisa.

Um widget de demonstração

Para ilustrar o funcionamento interno melhor, escrevi um widget de demonstração muito simples:

 /** * 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( '', $this->get_field_id( 'text' ), $this->get_field_name( 'text' ), $text ); } } 

Observe o construtor: 't5_demo_widget' é a $id_base , o identificador para esse widget. Como você pode ver na canvas, seus argumentos são armazenados na opção widget_t5_demo_widget . Todos os seus widgets personalizados serão tratados assim. Você não precisa adivinhar o nome. E desde que você escreveu seus widgets (provavelmente), você conhece todos os argumentos dos parâmetros da $instance da sua class.

Noções básicas do tema

Primeiro, você precisa registrar algumas barras laterais e o widget personalizado. A ação apropriada para isso é fácil de lembrar: 'widgets_init' . Coloque tudo em um recipiente – uma class ou uma function. Por simplicidade, usarei uma function chamada t5_default_widget_demo() .

Todo o código a seguir está no functions.php . A class T5_Demo_Widget já deve ser carregada. Acabei de colocá-lo no mesmo arquivo …

 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' => '' ) ); } 

Até agora, tão simples. Nosso tema agora é um widget pronto, o widget de demonstração é conhecido. Agora, a diversão.

 $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; } 

Você realmente não quer destruir as configurações do usuário. Se já houver algum conteúdo nas barras laterais, seu código não deve ser exibido. É por isso que paramos neste caso.

Ok, assumiu que as barras laterais estão vazias … precisamos de um contador:

 $counter = 1; 

Os widgets estão numerados . Esses números são dois identificadores para o WordPress.

Vamos ter a matriz para mudá-la:

 $active_widgets = get_option( 'sidebars_widgets' ); 

Precisamos de um contador também (mais sobre isso mais tarde):

 $counter = 1; 

E aqui é como usamos o contador, os nomes das barras laterais e os argumentos do widget (bem, temos apenas um argumento: 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++; 

Observe como o identificador do widget é criado: id_base , a menos - e o contador. O conteúdo do widget é armazenado em outra variável $demo_widget_content . Aqui está o contador da chave e os argumentos do widget são armazenados em uma matriz.

Nós aumentamos o contador por um quando terminamos para evitar colisões.

Essa foi fácil. Agora, um widget RSS. Mais campos, mais divertido!

 $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++; 

Aqui está algo novo: update_option() isso irá armazenar o argumento do widget RSS em uma opção separada. O WordPress irá encontrá-los automaticamente mais tarde.
Nós não salvamos os argumentos do widget de demonstração porque adicionamos uma segunda instância à nossa segunda barra lateral agora …

 // 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 ); 

… e salve todos os argumentos para o t5_demo_widget em uma corrida. Não é necessário atualizar a mesma opção duas vezes.

Bem, widgets suficientes para hoje, vamos salvar os sidebars_widgets também:

 update_option( 'sidebars_widgets', $active_widgets ); 

Agora, o WordPress saberá que existem alguns widgets registrados e onde os argumentos para cada widget são armazenados. Um var_export() no sidebar_widgets ficará assim:

 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, ) 

O código completo novamente:

 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 ); } 

Se você for wp-admin/widgets.php agora você verá três widgets predefinidos:

captura de tela de widgets ativos

E é isso. Usar …

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

… para imprimir os widgets.

Há uma pequena falha: você deve carregar o front-end duas vezes para o registro inicial. Se alguém pode ajudar aqui, ficarei muito agradecido.

Obrigado por compartilhar sua solução. Utilizei o que foi descrito nesta questão para criar um pedaço de código que pode ser usado para inicializar as barras laterais com muita facilidade. É muito flexível, você pode criar tantos widgets quanto quiser sem ter que modificar o código. Basta usar o filtro de ganchos e passar em argumentos em uma matriz. Aqui está o código comentado:

 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'] ); } } 

Esta é uma function auxiliar que verifica se a barra lateral já possui conteúdo nele:

 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; } 

Agora precisamos criar uma function que seja conectada à ação ‘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 ) ); } 

E agora a boot do 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 ); } } 

A última ação é criar os widgets em cada barra lateral:

 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; } } 

Esta function é usada para acompanhar quantas instâncias de um widget específico já foram definidas:

 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; } 

A última coisa que precisamos fazer é realmente atribuir valores. Faça uso dessas funções de filtro:

 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; } 

E:

 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', ), ); } 

Idealmente, você chamaria as barras initialize_side em uma function de configuração que é chamada de ativação de plug-in ou tema como esta: Ativação do tema:

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

Ativação do plugin:

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

Para resumir o uso deste conglomerado de funções:

  1. crie uma function que inicialize as barras laterais que são conectadas ao filtro ‘alter_initialization_sidebars’.

  2. crie uma function para cada barra lateral que você acabou de adicionar, que é conectada ao filtro ‘alter_initialization_widgets_ $ sidebarname’. Substitua $ sidebarname pelo nome de cada barra lateral criada na etapa 1.

Você também pode simplesmente copiar este código descontado em seu arquivo de funções e começar a criar suas funções de filtro imediatamente: Código no pastie (sem funções de filtro de boot)

Em primeiro lugar, graças ao @toscho para a resposta detalhada.

Este é um exemplo simples para aqueles que estão procurando uma solução simples e opções de widget padrão:

 $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 } 

Nota 1: Você pode obter sidebar-id para o menu widgets e inspecionar a barra lateral desejada. O primeiro

filho tem o sidebar-id .

Nota 2: Você pode obter o widget_name no menu widgets e inspecionar o widget desejado. Você verá algo como

.

Eu gostaria que isso ajudasse.

É assim que se faz:

(AVISO, isso pode REMOVER todos os widgets anteriores se você não colocou os widgets originais na matriz de widgets ).

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

O número-número pode ser usado se você quiser adicionar opções no widget com algo como isto:

  update_option('widget_widget_name', array( 1 => array( 'title' => 'The tile', 'number' => 4 ), '_multiwidget' => 1 ));