Cambiar qué sidebar obtiene get_sidebar() desde functions.php

7 sept 2012, 19:40:56
Vistas: 15.5K
Votos: 2

Tengo este código en un archivo de plantilla, que carga sidebar-sidebar_a.php:

get_sidebar('sidebar_a');

Me gustaría añadir una función a sidebar.php que tenga el efecto de cambiar eso a esto si se cumple alguna condición:

get_sidebar('other');

para que en su lugar cargue sidebar-other.php.

Pensé que esto funcionaría, pero parece no tener efecto:

add_action('get_sidebar', 'my_sidebar_logic');

function my_sidebar_logic($sidebar) {
    // Cargar una sidebar diferente si el usuario está logueado
    if (is_user_logged_in()) {
        return 'other';
    }

    return $sidebar;
}

¿Qué puedo hacer para conseguir el efecto que quiero?

0
Todas las respuestas a la pregunta 4
0

get_sidebar es una envoltura muy delgada alrededor de locate_template, que simplemente busca en el directorio del tema hijo y del tema padre la barra lateral especificada.

get_sidebar en wp-includes/general-template.php:

$templates = array();
if ( isset($name) )
    $templates[] = "sidebar-{$name}.php";

$templates[] = 'sidebar.php';

// Código de compatibilidad hacia atrás que será eliminado en una versión futura
if ('' == locate_template($templates, true))
    load_template( ABSPATH . WPINC . '/theme-compat/sidebar.php');

Y locate_template (en wp-includes/template.php):

<?php
/**
 * Recupera el nombre del archivo de plantilla con mayor prioridad que existe.
 *
 * Busca primero en STYLESHEETPATH antes que TEMPLATEPATH para que los temas que heredan
 * de un tema padre puedan sobrescribir un solo archivo.
 *
 * @since 2.7.0
 *
 * @param string|array $template_names Archivo(s) de plantilla a buscar, en orden.
 * @param bool $load Si es true, el archivo de plantilla se cargará si se encuentra.
 * @param bool $require_once Indica si usar require_once o require. Por defecto true. No tiene efecto si $load es false.
 * @return string El nombre del archivo de plantilla si se encuentra.
 */
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;
}

La razón por la que tu enlace a get_sidebar no funciona es porque es una acción. Simplemente se dispara. No te permite cambiar el resultado. Tu barra lateral seguirá siendo incluida independientemente de tu acción enlazada.

Esto te deja con algunas opciones:

1. Pasar una variable a get_sidebar

Solución de Chip Bennett: pasar una variable a la función get_sidebar. No está mal.

2. Escribe tu propia lógica de barra lateral

Y úsala en lugar de get_sidebar. Un ejemplo simple:

<?php
function mytheme_sidebar($name)
{
     $name = apply_filters('mytheme_sidebar', $name);
     get_sidebar($name);
}

Luego usa tu propio filtro para modificar la barra lateral:

<?php
add_filter('mytheme_sidebar', 'mytheme_custom_sidebar');
function mytheme_custom_sidebar($name)
{
    return is_user_logged_in() ? 'loggedin' : $name;
}

Esta será la opción más flexible. Si es un tema público, los usuarios finales podrán personalizar cosas. Si es para un cliente, cuando inevitablemente te pidan más cosas, será fácil de hacer.

3. Mira más profundo

get_sidebar simplemente incluye los archivos de tema apropiados. dynamic_sidebar es donde se realiza el trabajo.

Si miras dentro de esa función, la línea más interesante es:

$sidebars_widgets = wp_get_sidebars_widgets();

wp_get_sidebars_widgets obtiene todos los widgets registrados actualmente para todas las barras laterales del sitio.

<?php
/**
 * Recupera la lista completa de barras laterales y sus widgets.
 *
 * Actualizará la lista de widgets de la barra lateral si es necesario. También guardará la lista actualizada, si es necesario.
 *
 * @since 2.2.0
 * @access private
 *
 * @param bool $deprecated No se usa (obsoleto).
 * @return array Lista actualizada de widgets al formato de array versión 3 cuando se llama desde el admin.
 */
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;

    // Si se carga desde la página frontal, consulta $_wp_sidebars_widgets en lugar de opciones
    // para ver si wp_convert_widget_settings() ha hecho manipulaciones en 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 línea clave ahí: apply_filters('sidebars_widget', ...). Dinero.

Registra una barra lateral secundaria solo para usuarios logueados:

<?php
add_action('widgets_init', 'wpse64492_register');
function wpse64492_register()
{
    register_sidebar(array(
        'name'  => __('Barra lateral para logueados', 'wpse64492'),
        'id'    => 'logged-in'
    ));
}

Luego enlaza a sidebars_widgets y cambia la barra lateral normal por la versión para logueados.

<?php
add_filter('sidebars_widgets', 'wpse64492_switch');
function wpse64492_switch($widgets)
{
    if(is_admin())
        return $widgets;

    $key = 'sidebar-1'; // ¡la barra lateral que quieres cambiar!

    if(isset($widgets[$key]) && is_user_logged_in() && isset($widgets['logged-in']))
        $widgets[$key] = $widgets['logged-in'];

    return $widgets;
}
7 sept 2012 21:39:26
0

Solo pasa una variable a get_sidebar():

// Determinar la barra lateral
$sidebar = ( is_user_logged_in() ? 'other' : 'sidebar_a' );
// Obtener la barra lateral
get_sidebar( $sidebar );
7 sept 2012 19:49:57
0

Temas

Solo envuélvelo en la lógica más delgada y menos intrusiva: Un filtro.

// En tu tema: Llama la barra lateral por defecto
get_sidebar( apply_filters( 'wpse64492_sidebar', '' ) );

Luego puedes cambiar en tu archivo functions.php:

function wpse64492_sidebar_name( $name = '' )
{
    // Llama a sidebar-single.php en la vista individual de entradas
    is_single() AND $name = 'single';

    return $name;
}
add_filter( 'wpse64492_sidebar', 'wpse64492_sidebar_name' );

Plugins

Si deseas hacerlo desde un plugin, usa la acción:

<?php
/** Plugin Name: (#64492) Cambiar barras laterales por solicitud */
function wpse64492_sidebar( $name )
{
    // Lógica condicional: Otra barra lateral para página 2+ en archivos paginados
    if ( is_paged() )
    {
        // Evita recursión: remueve a sí mismo
        remove_filter( current_filter(), __FUNCTION__ );
        return get_sidebar( 'paged' );
    }

    // Retorno por defecto
    return $name;
}
add_action( 'get_sidebar', 'wpse64492_sidebar' );
17 oct 2012 06:23:14
2

También puedes llamar a la barra lateral actual dentro de la función.

add_action('get_sidebar', 'my_sidebar_logic');

function my_sidebar_logic($sidebar) {
    // Cargar una barra lateral diferente si el usuario está conectado
    if (is_user_logged_in()) {
          get_sidebar('other');
    }   
}
7 sept 2012 19:50:28
Comentarios

¿Esto no resulta en un bucle recursivo?

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

Ah, probablemente tengas razón, no comprendí completamente la pregunta, estaba pensando en dynamic sidebar

Wyck Wyck
7 sept 2012 20:06:52