Kiedy zacząłem tę odpowiedź, powinna to być tylko mała uwaga. Cóż, nie udało mi się. Przepraszam! Zostań ze mną, w głębi jest ukryty skarb…
Jak są przechowywane widżety WordPress
Lista widżetów jest przechowywana w opcji o nazwie 'sidebars_widgets'
. A var_export()
może dać coś takiego:
array (
'wp_inactive_widgets' =>
array (
),
'top-widget' =>
array (
),
'bottom-widget' =>
array (
),
'array_version' => 3,
)
Ignoruj 'wp_inactive_widgets'
i 'array_version'
. Nie musimy się tym przejmować.
Pozostałe klucze są identyfikatorem zarejestrowanych pasków bocznych. W takim przypadku paski boczne mogły zostać zarejestrowane za pomocą tego kodu:
// 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' => ''
)
);
}
Domyślnie paski boczne są puste po rejestracji. Oczywiście.
Dla każdej zarejestrowanej klasy widżetu tworzona jest osobna opcja, zawierająca wszystkie niezbędne opcje. Opcja jest poprzedzona ciągiem widget_
. Aby uzyskać opcje dla wszystkich aktywnych widżetów RSS, musimy przyjrzeć się…
get_option( 'widget_rss' );
Możliwe wyjście:
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,
),
)
Zwróć uwagę na liczbę 2 . Wszystkie argumenty dla wielu instancji są przechowywane w tej jednej opcji posortowanej według liczb.
Aby zobaczyć, które klasy widżetów są już znane WordPressowi, przejdź do wp-admin/options.php
i przewiń w dół, aż zobaczysz coś takiego:
Tak, dane serializowane. Nie, nie możesz ich tutaj przeczytać. Nie martw się, nie musisz.
Widżet demonstracyjny
Aby lepiej zilustrować wewnętrzne funkcjonowanie, napisałem bardzo prosty widżet demonstracyjny:
/**
* 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
);
}
}
Uwaga konstruktor: 't5_demo_widget'
jest $id_base
identyfikatorem tego widgetu. Jak widać na zrzucie ekranu, jego argumenty są przechowywane w opcji widget_t5_demo_widget
. Wszystkie niestandardowe widżety będą traktowane w ten sposób. Nie musisz zgadywać nazwy. A skoro masz napisane swoje widżety (prawdopodobnie) znasz wszystkie argumenty ze swoimi klasa $instance
parametrów.
Podstawy motywu
Najpierw musisz zarejestrować niektóre paski boczne i niestandardowy widget. Prawidłowe działanie tego jest łatwy do zapamiętania: 'widgets_init'
. Umieść wszystko w pojemniku - klasa lub funkcja. Dla uproszczenia użyję funkcji o nazwie t5_default_widget_demo()
.
Cały poniższy kod przechodzi do functions.php
. Klasa T5_Demo_Widget
powinna być już załadowana. Po prostu umieściłem go w tym samym pliku…
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' => ''
)
);
}
Do tej pory takie proste. Nasz motyw jest teraz gotowy na widżet, widżet demo jest znany. Teraz zabawa.
$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;
}
Naprawdę nie chcesz niszczyć ustawień użytkownika. Jeśli na paskach bocznych jest już trochę treści, twój kod nie powinien na niej działać. Dlatego zatrzymujemy się w tym przypadku.
Okej, zakładając, że paski boczne są puste… potrzebujemy licznika:
$counter = 1;
Widżety są ponumerowane . Te liczby są drugim identyfikatorem WordPress.
Niech tablica to zmieni:
$active_widgets = get_option( 'sidebars_widgets' );
Potrzebujemy też licznika (więcej na ten temat później):
$counter = 1;
A oto jak używamy licznika, nazw paska bocznego i argumentów widgetu (cóż, mamy tylko jeden 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++;
Zwróć uwagę, jak tworzony jest identyfikator widżetu: id_base
minus, -
licznik. Zawartość widget jest przechowywany w innej zmiennej $demo_widget_content
. Oto licznik, w którym klucz i argumenty widgetu są przechowywane w tablicy.
Zwiększamy licznik o jeden, gdy skończymy, aby uniknąć kolizji.
To było łatwe. Teraz widżet RSS. Więcej pól, więcej zabawy!
$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++;
Oto coś nowego: update_option()
spowoduje to zapisanie argumentu widgetu RSS w osobnej opcji. WordPress znajdzie je automatycznie później.
Nie zapisaliśmy argumentów widżetu demonstracyjnego, ponieważ teraz dodajemy drugą instancję do naszego drugiego paska bocznego…
// 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 );
… I zachowaj wszystkie argumenty za t5_demo_widget
jednym razem. Nie trzeba dwa razy aktualizować tej samej opcji.
Cóż, wystarczy widżetów na dziś, zapiszmy sidebars_widgets
też:
update_option( 'sidebars_widgets', $active_widgets );
Teraz WordPress będzie wiedział, że istnieją zarejestrowane widżety i gdzie przechowywane są argumenty dla każdego widżetu. A var_export()
na pasku bocznym będzie wyglądać następująco:
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,
)
Kompletny kod ponownie:
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 );
}
Jeśli przejdziesz do wp-admin/widgets.php
teraz, zobaczysz trzy wstępnie ustawione widżety:
I to wszystko. Posługiwać się …
dynamic_sidebar( 'top-widget' );
dynamic_sidebar( 'bottom-widget' );
… Aby wydrukować widżety.
Istnieje niewielka usterka: w celu wstępnej rejestracji musisz dwa razy załadować interfejs. Jeśli ktoś może tu pomóc, będę bardzo wdzięczny.