Come modificare la sidebar ottenuta da get_sidebar() tramite functions.php
Ho questo codice in un file template, che carica sidebar-sidebar_a.php
:
get_sidebar('sidebar_a');
Vorrei aggiungere una funzione a sidebar.php che abbia l'effetto di modificarlo in questo se viene soddisfatta una condizione:
get_sidebar('other');
in modo che invece carichi sidebar-other.php
.
Pensavo che questo avrebbe funzionato, ma sembra non avere alcun effetto:
add_action('get_sidebar', 'my_sidebar_logic');
function my_sidebar_logic($sidebar) {
// Carica una sidebar diversa se l'utente è loggato
if (is_user_logged_in()) {
return 'other';
}
return $sidebar;
}
Cosa posso fare per ottenere l'effetto desiderato?
Get sidebar è un wrapper molto leggero attorno a locate_template
, che semplicemente cerca nella directory del tema figlio e del tema genitore la sidebar specificata.
get_sidebar
in wp-includes/general-template.php
:
$templates = array();
if ( isset($name) )
$templates[] = "sidebar-{$name}.php";
$templates[] = 'sidebar.php';
// Codice retrocompatibile che verrà rimosso in una versione futura
if ('' == locate_template($templates, true))
load_template( ABSPATH . WPINC . '/theme-compat/sidebar.php');
}
E locate_template
(in wp-includes/template.php
):
<?php
/**
* Recupera il nome del file template con la priorità più alta che esiste.
*
* Cerca prima in STYLESHEETPATH e poi in TEMPLATEPATH, così i temi che
* ereditano da un tema genitore possono sovrascrivere un singolo file.
*
* @since 2.7.0
*
* @param string|array $template_names File template da cercare, in ordine.
* @param bool $load Se true, il file template verrà caricato se trovato.
* @param bool $require_once Se usare require_once o require. Di default true. Non ha effetto se $load è false.
* @return string Il nome del file template se trovato.
*/
function locate_template($template_names, $load = false, $require_once = true ) {
$located = '';
foreach ( (array) $template_names as $template_name ) {
if ( !$template_name )
continue;
if ( file_exists(STYLESHEETPATH . '/' . $template_name)) {
$located = STYLESHEETPATH . '/' . $template_name;
break;
} else if ( file_exists(TEMPLATEPATH . '/' . $template_name) ) {
$located = TEMPLATEPATH . '/' . $template_name;
break;
}
}
if ( $load && '' != $located )
load_template( $located, $require_once );
return $located;
}
Il motivo per cui il tuo hook in get_sidebar
non funziona è perché è un'azione. Viene semplicemente eseguita. Non permette di modificare il risultato. La tua sidebar verrà comunque inclusa indipendentemente dall'azione agganciata.
Questo ti lascia con alcune opzioni.
1. Passa una variabile a get_sidebar
La soluzione di Chip Bennett: passa una variabile alla funzione get_sidebar
. Non male.
2. Scrivi la tua logica per la sidebar
E usala al posto di get_sidebar
. Un esempio semplice:
<?php
function mytheme_sidebar($name)
{
$name = apply_filters('mytheme_sidebar', $name);
get_sidebar($name);
}
Poi usa il tuo filtro per modificare la sidebar
<?php
add_filter('mytheme_sidebar', 'mytheme_custom_sidebar');
function mytheme_custom_sidebar($name)
{
return is_user_logged_in() ? 'loggedin' : $name;
}
Questa sarà la soluzione più flessibile. Se è un tema pubblico, gli utenti finali potranno personalizzare le cose. Se è per un cliente, quando inevitabilmente ti chiederanno altre modifiche, sarà facilmente fattibile.
3. Approfondisci
get_sidebar
semplicemente include i file appropriati del tema. dynamic_sidebar
è dove viene svolto il lavoro vero.
Se guardi dentro quella funzione, la riga più interessante è:
$sidebars_widgets = wp_get_sidebars_widgets();
wp_get_sidebars_widgets
recupera tutti i widget attualmente registrati per tutte le sidebar del sito.
<?php
/**
* Recupera la lista completa delle sidebar e dei loro widget.
*
* Aggiornerà la lista dei widget della sidebar, se necessario. Salverà anche la lista aggiornata, se necessario.
*
* @since 2.2.0
* @access private
*
* @param bool $deprecated Non utilizzato (deprecato).
* @return array Lista aggiornata dei widget in formato array versione 3 quando chiamata dall'amministrazione.
*/
function wp_get_sidebars_widgets($deprecated = true) {
if ( $deprecated !== true )
_deprecated_argument( __FUNCTION__, '2.8.1' );
global $wp_registered_widgets, $_wp_sidebars_widgets, $sidebars_widgets;
// Se caricato dalla pagina frontale, consulta $_wp_sidebars_widgets invece delle opzioni
// per vedere se wp_convert_widget_settings() ha fatto manipolazioni in memoria.
if ( !is_admin() ) {
if ( empty($_wp_sidebars_widgets) )
$_wp_sidebars_widgets = get_option('sidebars_widgets', array());
$sidebars_widgets = $_wp_sidebars_widgets;
} else {
$sidebars_widgets = get_option('sidebars_widgets', array());
}
if ( is_array( $sidebars_widgets ) && isset($sidebars_widgets['array_version']) )
unset($sidebars_widgets['array_version']);
$sidebars_widgets = apply_filters('sidebars_widgets', $sidebars_widgets);
return $sidebars_widgets;
}
La riga chiave qui: apply_filters('sidebars_widget', ...)
. Eccellente.
Registra una sidebar secondaria solo per utenti loggati:
<?php
add_action('widgets_init', 'wpse64492_register');
function wpse64492_register()
{
register_sidebar(array(
'name' => __('Sidebar per Utenti Loggati', 'wpse64492'),
'id' => 'logged-in'
));
}
Poi agganciati a sidebars_widgets
e scambia la sidebar normale con quella per utenti loggati.
<?php
add_filter('sidebars_widgets', 'wpse64492_switch');
function wpse64492_switch($widgets)
{
if(is_admin())
return $widgets;
$key = 'sidebar-1'; // la sidebar che vuoi modificare!
if(isset($widgets[$key]) && is_user_logged_in() && isset($widgets['logged-in']))
$widgets[$key] = $widgets['logged-in'];
return $widgets;
}

Temi
Basta racchiuderlo nella logica più sottile e meno intrusiva: un filtro.
// Nel tuo tema: Chiama la sidebar predefinita
get_sidebar( apply_filters( 'wpse64492_sidebar', '' ) );
Poi puoi cambiare nel tuo file functions.php:
function wpse64492_sidebar_name( $name = '' )
{
// Chiama sidebar-single.php nelle visualizzazioni singole dei post
is_single() AND $name = 'single';
return $name;
}
add_filter( 'wpse64492_sidebar', 'wpse64492_sidebar_name' );
Plugin
Se vuoi farlo da un plugin, usa l'azione:
<?php
/** Plugin Name: (#64492) Cambia sidebar per richiesta */
function wpse64492_sidebar( $name )
{
// Logica condizionale: Un'altra sidebar per la pagina 2+ negli archivi impaginati
if ( is_paged() )
{
// Evita la ricorsione: rimuovi se stesso
remove_filter( current_filter(), __FUNCTION__ );
return get_sidebar( 'paged' );
}
// Ritorno predefinito
return $name;
}
add_action( 'get_sidebar', 'wpse64492_sidebar' );
