Cum să schimbi sidebar-ul încărcat de get_sidebar() din functions.php

7 sept. 2012, 19:40:56
Vizualizări: 15.5K
Voturi: 2

Am acest cod într-un fișier de template, care încarcă sidebar-sidebar_a.php:

get_sidebar('sidebar_a');

Aș dori să adaug o funcție în sidebar.php care să schimbe sidebar-ul încărcat în acest fel dacă o anumită condiție este îndeplinită:

get_sidebar('other');

astfel încât să încarce sidebar-other.php în schimb.

Am crezut că această soluție va funcționa, dar nu pare să aibă niciun efect:

add_action('get_sidebar', 'my_sidebar_logic');

function my_sidebar_logic($sidebar) {
    // Încarcă un alt sidebar dacă utilizatorul este autentificat
    if (is_user_logged_in()) {
        return 'other';
    }

    return $sidebar;
}

Ce pot face pentru a obține efectul dorit?

0
Toate răspunsurile la întrebare 4
0

get_sidebar este un wrapper foarte simplu în jurul funcției locate_template, care doar caută în directorul temei copil și al temei părinte un sidebar dat.

get_sidebar în wp-includes/general-template.php:

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

$templates[] = 'sidebar.php';

// Cod pentru compatibilitate backwards care va fi eliminat într-o versiune viitoare
if ('' == locate_template($templates, true))
    load_template( ABSPATH . WPINC . '/theme-compat/sidebar.php');

}

Și locate_template (în wp-includes/template.php):

<?php
/**
 * Returnează numele fișierului de template cu cea mai mare prioritate care există.
 *
 * Caută mai întâi în STYLESHEETPATH înainte de TEMPLATEPATH, astfel încât temele
 * care moștenesc de la o temă părinte să poată suprascrie doar un singur fișier.
 *
 * @since 2.7.0
 *
 * @param string|array $template_names Fișier(e) de template de căutat, în ordine.
 * @param bool $load Dacă este true, fișierul de template va fi încărcat dacă este găsit.
 * @param bool $require_once Dacă se folosește require_once sau require. Valoarea implicită este true. Nu are efect dacă $load este false.
 * @return string Numele fișierului de template dacă este găsit.
 */
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;
}

Motivul pentru care hook-ul tău în get_sidebar nu funcționează este pentru că este o acțiune. Doar se declanșează. Nu îți permite să modifici rezultatul. Sidebar-ul tău va fi totuși inclus indiferent de acțiunea ta hook-uită.

Aceasta îți lasă câteva opțiuni.

1. Trimite o variabilă în get_sidebar

Soluția lui Chip Bennett: trimite o variabilă în funcția get_sidebar. Nu e rea.

2. Scrie-ți propria logică pentru Sidebar

Și folosește-o în locul get_sidebar. Un exemplu simplu:

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

Apoi folosește propriul tău filtru pentru a modifica sidebar-ul

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

Aceasta va fi cea mai flexibilă soluție. Dacă este o temă publică, utilizatorii finali vor putea personaliza lucrurile. Dacă este pentru un client, când inevitabil vor cere mai multe funcționalități, va fi ușor de implementat.

3. Caută mai adânc

get_sidebar doar include fișierele potrivite ale temei. dynamic_sidebar este unde se face munca adevărată.

Dacă te uiți în interiorul acelei funcții, cea mai interesantă linie este:

$sidebars_widgets = wp_get_sidebars_widgets();

wp_get_sidebars_widgets preia toate widget-urile înregistrate pentru toate sidebar-urile site-ului.

<?php
/**
 * Returnează lista completă de sidebar-uri și widget-urile lor.
 *
 * Va actualiza lista de widget-uri a sidebar-ului, dacă este necesar. De asemenea, va salva
 * lista actualizată, dacă este necesar.
 *
 * @since 2.2.0
 * @access private
 *
 * @param bool $deprecated Nu este folosit (deprecated).
 * @return array Lista actualizată de widget-uri în formatul array versiunea 3 atunci când este apelată din 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;

    // Dacă se încarcă din frontend, se consultă $_wp_sidebars_widgets în loc de opțiuni
    // pentru a vedea dacă wp_convert_widget_settings() a făcut modificări în memorie.
    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;
}

Linia cheie acolo: apply_filters('sidebars_widget', ...). Perfect.

Înregistrează un sidebar secundar doar pentru utilizatorii autentificați:

<?php
add_action('widgets_init', 'wpse64492_register');
function wpse64492_register()
{
    register_sidebar(array(
        'name'  => __('Sidebar pentru Autentificați', 'wpse64492'),
        'id'    => 'logged-in'
    ));
}

Apoi folosește hook-ul sidebars_widgets pentru a înlocui sidebar-ul normal cu versiunea pentru autentificați.

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

    $key = 'sidebar-1'; // sidebar-ul pe care vrei să îl modifici!

    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

Doar treceți o variabilă la get_sidebar():

// Determinăm sidebar-ul
$sidebar = ( is_user_logged_in() ? 'other' : 'sidebar_a' );
// Obținem sidebar-ul
get_sidebar( $sidebar );
7 sept. 2012 19:49:57
0

Teme

Înfășurați-o pur și simplu în cea mai subțire și mai puțin invazivă logică: Un filtru.

// În tema dvs.: Apelează bara laterală implicită
get_sidebar( apply_filters( 'wpse64492_sidebar', '' ) );

Apoi puteți comuta în fișierul functions.php:

function wpse64492_sidebar_name( $name = '' )
{
    // Apelează sidebar-single.php la vizualizarea individuală a articolelor
    is_single() AND $name = 'single';

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

Plugin-uri

Dacă doriți să faceți acest lucru dintr-un plugin, utilizați acțiunea:

<?php
/** Plugin Name: (#64492) Schimbă barele laterale pe cerere */
function wpse64492_sidebar( $name )
{
    // Logică condiționată: Altă bară laterală pentru pagina 2+ în arhivele paginate
    if ( is_paged() )
    {
        // Evită recursiunea: elimină-se pe sine
        remove_filter( current_filter(), __FUNCTION__ );
        return get_sidebar( 'paged' );
    }

    // Returnare implicită
    return $name;
}
add_action( 'get_sidebar', 'wpse64492_sidebar' );
17 oct. 2012 06:23:14
2

Puteți apela și bara laterală reală în funcție.

add_action('get_sidebar', 'my_sidebar_logic');

function my_sidebar_logic($sidebar) {
    // Încarcă o altă bară laterală dacă utilizatorul este autentificat
    if (is_user_logged_in()) {
          get_sidebar('other');
    }   
}
7 sept. 2012 19:50:28
Comentarii

Aceasta nu duce la o buclă recursivă?

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

Ah, probabil ai dreptate, nu am înțeles complet întrebarea, mă gândeam la dynamic sidebar

Wyck Wyck
7 sept. 2012 20:06:52