Quando ho iniziato questa risposta, dovrebbe essere solo una piccola nota. Beh, ho fallito. Scusate! Resta con me, c'è una chicca nascosta nel profondo ...
Come sono memorizzati i widget di WordPress
L'elenco dei widget è memorizzato in un'opzione denominata 'sidebars_widgets'
. A var_export()
può dare qualcosa di simile al seguente:
array (
'wp_inactive_widgets' =>
array (
),
'top-widget' =>
array (
),
'bottom-widget' =>
array (
),
'array_version' => 3,
)
Ignora 'wp_inactive_widgets'
e 'array_version'
. Non dobbiamo preoccuparci di quelli.
Le altre chiavi sono identificative per le barre laterali registrate. In questo caso le barre laterali potrebbero essere state registrate con questo codice:
// 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' => ''
)
);
}
Per impostazione predefinita, le barre laterali sono vuote dopo la registrazione. Ovviamente.
Per ogni classe di widget registrata viene creata un'opzione separata, contenente tutte le opzioni necessarie. L'opzione è preceduta dalla stringa widget_
. Per ottenere le opzioni per tutti i widget RSS attivi, dobbiamo esaminare ...
get_option( 'widget_rss' );
Uscita possibile:
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,
),
)
Nota il numero 2 . Gli argomenti per più istanze sono tutti memorizzati in questa opzione ordinata per numeri.
Per vedere quali classi di widget sono già note a WordPress, vai wp-admin/options.php
e scorri verso il basso fino a vedere qualcosa del genere:
Sì, dati serializzati. No, non puoi leggerli qui. Non ti preoccupare, non è necessario.
Un widget demo
Per illustrare meglio il funzionamento interno ho scritto un widget demo molto semplice:
/**
* 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
);
}
}
Nota il costruttore: 't5_demo_widget'
è $id_base
l'identificatore per questo widget. Come puoi vedere nella schermata, i suoi argomenti sono memorizzati nell'opzione widget_t5_demo_widget
. Tutti i tuoi widget personalizzati verranno trattati in questo modo. Non devi indovinare il nome. E poiché hai scritto i tuoi widget (probabilmente) conosci tutti gli argomenti dei $instance
parametri della tua classe .
Nozioni di base sul tema
Per prima cosa devi registrare alcune barre laterali e il widget personalizzato. L'azione appropriata per questo è facile da ricordare: 'widgets_init'
. Metti tutto in un contenitore - una classe o una funzione. Per semplicità userò una funzione chiamata t5_default_widget_demo()
.
Tutto il seguente codice va in functions.php
. La classe T5_Demo_Widget
dovrebbe essere già caricata. L'ho appena inserito nello stesso file ...
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' => ''
)
);
}
Finora così semplice. Il nostro tema è ora pronto per il widget, il widget demo è noto. Adesso il divertimento.
$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;
}
Non vuoi davvero distruggere le impostazioni dell'utente. Se è già presente del contenuto nelle barre laterali, il codice non deve essere eseguito su di esso. Ecco perché ci fermiamo in questo caso.
Ok, supponiamo che le barre laterali siano vuote ... abbiamo bisogno di un contatore:
$counter = 1;
I widget sono numerati . Questi numeri sono secondi identificatori per WordPress.
Facciamo in modo che l'array lo cambi:
$active_widgets = get_option( 'sidebars_widgets' );
Abbiamo bisogno anche di un contatore (ne parleremo più avanti):
$counter = 1;
Ed ecco come usiamo il contatore, i nomi della barra laterale e gli argomenti del widget (beh, abbiamo solo un argomento:) 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++;
Nota come viene creato l'identificatore del widget: il id_base
, un meno -
e il contatore. Il contenuto del widget è memorizzato in un'altra variabile $demo_widget_content
. Ecco il contatore della chiave e gli argomenti del widget sono memorizzati in un array.
Incrementiamo il contatore di uno quando abbiamo finito per evitare collisioni.
È stato facile. Ora un widget RSS. Più campi, più divertimento!
$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++;
Ecco qualcosa di nuovo: update_option()
questo memorizzerà l'argomento del widget RSS in un'opzione separata. WordPress li troverà automaticamente in seguito.
Non abbiamo salvato gli argomenti del widget demo perché ora aggiungiamo una seconda istanza alla nostra seconda barra laterale ...
// 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 salva tutti gli argomenti per la t5_demo_widget
corsa. Non è necessario aggiornare la stessa opzione due volte.
Bene, abbastanza widget per oggi, salviamo sidebars_widgets
anche noi:
update_option( 'sidebars_widgets', $active_widgets );
Ora WordPress saprà che ci sono alcuni widget registrati e dove sono memorizzati gli argomenti per ciascun widget. A var_export()
sul sidebar_widgets sarà simile a questo:
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,
)
Il codice completo di nuovo:
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 vai a wp-admin/widgets.php
ora vedrai tre widget preimpostati:
E questo è tutto. Uso …
dynamic_sidebar( 'top-widget' );
dynamic_sidebar( 'bottom-widget' );
... per stampare i widget.
C'è un piccolo problema tecnico: devi caricare il front-end due volte per la registrazione iniziale. Se qualcuno può darci una mano, ti sarò molto grato.