Come modificare la sidebar ottenuta da get_sidebar() tramite functions.php

7 set 2012, 19:40:56
Visualizzazioni: 15.5K
Voti: 2

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?

0
Tutte le risposte alla domanda 4
0

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

7 set 2012 21:39:26
0

Passa semplicemente una variabile a get_sidebar():

// Determina la sidebar
$sidebar = ( is_user_logged_in() ? 'other' : 'sidebar_a' );
// Ottieni la sidebar
get_sidebar( $sidebar );
7 set 2012 19:49:57
0

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' );
17 ott 2012 06:23:14
2

Puoi chiamare la sidebar effettiva anche all'interno della funzione.

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()) {
          get_sidebar('other');
    }   
}
7 set 2012 19:50:28
Commenti

Questo non risulta in un loop ricorsivo?

Chip Bennett Chip Bennett
7 set 2012 19:54:18

Ah probabilmente hai ragione, non ho compreso appieno la domanda, stavo pensando a dynamic sidebar

Wyck Wyck
7 set 2012 20:06:52