Dodanie div w celu zawinięcia zawartości widżetu po tytule widżetu

10

Próbuję dodać div do zawartości widżetu na moim dynamicznym pasku bocznym.

Oto kod rejestru;

register_sidebar(array(
        'name' => "Sidebar1",
        'id' => 'home-sidebar-1',
        'before_widget' => '<div class="sidebar-box">',
        'after_widget' => '</div>',
        'before_title' => '<div class="title">',
        'after_title' => '</div>',
    ));

Ale ten kod powoduje tak;

<div class="sidebar-box">
    <div class="title">{WIDGET TITLE}</div>
     {WIDGET CONTENT}
</div>

Oto, co próbuję zrobić;

<div class="sidebar-box">
    <div class="title">{WIDGET TITLE}</div>
    <div class="content">
           {WIDGET CONTENT}
    </div> 
</div>

Jak można to zrobić?

MBraiN
źródło

Odpowiedzi:

18

Oprócz odpowiedzi Toscho oto, czego potrzebujesz do solidnego rozwiązania:

// if no title then add widget content wrapper to before widget
add_filter( 'dynamic_sidebar_params', 'check_sidebar_params' );
function check_sidebar_params( $params ) {
    global $wp_registered_widgets;

    $settings_getter = $wp_registered_widgets[ $params[0]['widget_id'] ]['callback'][0];
    $settings = $settings_getter->get_settings();
    $settings = $settings[ $params[1]['number'] ];

    if ( $params[0][ 'after_widget' ] == '</div></div>' && isset( $settings[ 'title' ] ) && empty( $settings[ 'title' ] ) )
        $params[0][ 'before_widget' ] .= '<div class="content">';

    return $params;
}

Z odpowiedzi Toscho:

register_sidebar(array(
    'name' => "Sidebar1",
    'id' => 'home-sidebar-1',
    'before_widget' => '<div class="sidebar-box">',
    'after_widget' => '</div></div>',
    'before_title' => '<div class="title">',
    'after_title' => '</div><div class="content">',
));

To robi:

  • sprawdza ustawienia zarejestrowanego paska bocznego dla widżetów kończących się na 2 zamykające <div>s
  • sprawdza, czy nie ma tytułu
  • jeśli nie, modyfikuje dane before_widgetwyjściowe, aby wyświetlić div treści otwierającego widgetu

Możesz użyć tego podejścia do zmiany argumentów paska bocznego na inne sposoby, w zależności od ustawień instancji widgetu.

sanchothefat
źródło
Mam z tym problem: niektóre widżety (takie jak na przykład domyślne WP) ustawiają domyślny tytuł, jeśli pozostawisz to puste. Więc twoja funkcja dodaje div, ponieważ w tym momencie nie ma tytułu w params, ale widżet dodaje go później, a kod jest pomieszany. Czy wiesz, jak sprawdzić tytuł z „wewnątrz” widżetu? Dzięki
Cmorales,
Nie bez dodawania widżetu przez sprawdzanie widżetów lub jakiegoś strasznie złożonego kodu, aby renderować widżet po cichu, a następnie parsować go w celu uzyskania tytułu ...
Pomyślę
Może pomoże ci podpięcie się do tego codex.wordpress.org/Function_Reference/the_widget ? Używają go (z innego powodu) w tym artykule wp.smashingmagazine.com/2012/12/11/…
Cmorales
1
the_widget()nie jest używany w dynamic_sidebar()funkcji, jest to sposób na wywołanie dowolnego widżetu z opcjami określonymi w miejscu. Jest to jednak inne miejsce do filtrowania, więc moje rozwiązanie nie obejmuje takiej ewentualności. Pozdrawiam
sanchothefat
2

Dodaj drugi divdo parametru tytułu:

register_sidebar(array(
        'name' => "Sidebar1",
        'id' => 'home-sidebar-1',
        'before_widget' => '<div class="sidebar-box">',
        'after_widget' => '</div></div>',
        'before_title' => '<div class="title">',
        'after_title' => '</div><div class="content">',
    ));
fuxia
źródło
To się nie powiedzie, jeśli nie ma tytułu widżetu - można to jednak zrobić
sanchothefat
Tak, kończy się niepowodzeniem, gdy nie ma tytułu.
MBraiN
Dodałem odpowiedź z kodem, aby naprawić problem z tytułami. Prawdopodobnie powinien zostać połączony z Toscho naprawdę, ale ma już epickiego przedstawiciela :)
sanchothefat
2

Podobał mi się pomysł zarówno na @tosco, jak i @sanchothefat - jednak zmagałem się z tą kombinacją, ponieważ chociaż empty( $settings[ 'title' ]rzeczywiście może zwrócić wartość true, sam widget może wyświetlać domyślny tytuł, jeśli nie zostanie ustawiony. Tytuł ten jest następnie owinięte w before_titlei after_titleznaczników i ponownie przerwach stronie. Tak jest w przypadku niektórych domyślnych widżetów.

Łatwiej jest trzymać się standardowych parametrów rejestracji widżetów;

register_sidebar(array(
    'id' => 'sidebar1',
    'name' => __( 'Sidebar 1', 'bonestheme' ),
    'description' => __( 'The first (primary) sidebar.', 'bonestheme' ),
    'before_widget' => '<div class="block">',
    'after_widget' => '</div>',
    'before_title' => '<div class="block-title">',
    'after_title' => '</div>',
));

a następnie dodaj akcję filtrującą zgodnie z odpowiedzią Marventusa tutaj;

http://wordpress.org/support/topic/add-html-wrapper-around-widget-content

function widget_content_wrap($content) {
    $content = '<div class="block-content">'.$content.'</div>';
    return $content;
}
add_filter('widget_text', 'widget_content_wrap');
rabmcnab
źródło
3
i to działa tylko w przypadku „widżetów tekstowych”
Srebrny Księżyc,
1

Oto, co możesz zrobić, aby to osiągnąć:

register_sidebar(array(
        'name' => "Sidebar1",
        'id' => 'home-sidebar-1',
        'before_widget' => '<div class="sidebar-box"><div class="content">',
        'after_widget' => '</div></div>',
        'before_title' => '</div><div class="title">',
        'after_title' => '</div><div class="content">',
    ))

Jeśli nie ma tytułu, otrzymasz:

<div class="sidebar-box"><div class="content">
{CONTENT}
</div></div>

Gdy pojawi się tytuł, otrzymasz:

<div class="sidebar-box"><div class="content">
</div><div class="title">
{TITLE}
<div class="content">
{CONTENT}
</div></div>

Aby upewnić się, że pierwszy pusty div treści nie wyświetla się w drugim przypadku, dodaj to do swojego css:

.sidebar-box .content:empty {display:none !important;}
cjbj
źródło
0

Po zapoznaniu się z poprzednimi odpowiedziami wydaje mi się, że rozwiązałem problem identyfikowany przez Cmoralesa z odpowiedzią sanchothefat. Zdefiniuj widget w następujący sposób:

register_sidebar( array(
    'name' => 'Sidebar',
    'id' => 'sidebar',
    'before_widget' => '<div class="panel panel-default %2$s" id="%1$s">',
    'after_widget' => '</div>',
    'before_title' => '',
    'after_title' => ''
) );

Ważne jest, aby usunąć wartości domyślne before_titlei after_title. Po kilku próbach i błędach zauważyłem, że pierwszym filtrem, który pokazywał domyślny tytuł, był widget_title. Następnie użyj widget_titlefiltra w następujący sposób:

function widget_title( $title ) {
    if ( $title )
        $title = '<div class="panel-heading"><h3 class="panel-title">' . $title . '</h3></div>';
    $title .= '<div class="panel-body">';
    return $title;
}

Zasadniczo <div class="panel-heading"><h3 class="panel-title">jest mój before_titlei </h3></div>jest mój after_title. Na koniec użyj, dynamic_sidebar_paramsaby wstawić zamykający div dla naszego zawijania zawartości:

function dynamic_sidebar_params( $params ) {
    $params[0]['after_widget'] = '</div>' . $params[0]['after_widget'];
    return $params;
}

To nie jest ładne, ale działa.

Spencer
źródło
Początkowo byłem bardzo podekscytowany tym podejściem, ale napotkałem problem z widżetami, które używają esc_html ($ title) (tj. BuddyPress). W takim przypadku dodany kod HTML jest wyświetlany jako znak zmiany znaczenia i nie jest renderowany w interfejsie użytkownika.
Ryan,
0

Po prostu nieznacznie zmieniam kod, aby nie trzeba było dotykać register_sidebar . Zarejestruj pasek boczny w zwykły sposób:

register_sidebar(array(
    'name' => "Sidebar1",
    'id' => 'home-sidebar-1',
    'before_widget' => '<div class="sidebar-box">',
    'after_widget' => '</div>',
    'before_title' => '<div class="title">',
    'after_title' => '</div>',
));

Poniżej znajduje się zmodyfikowany kod z rozwiązania Sanchothefat:

/**
 * If no title given then add widget-content wrapper to before_widget
 * If title given then add content wrapper to before_widget
*/
add_filter('dynamic_sidebar_params', 'check_widget_template');
function check_widget_template($params){
    global $wp_registered_widgets;

    $settings_obj = $wp_registered_widgets[$params[0]['widget_id']]['callback'][0];
    $the_settings = $settings_obj->get_settings();
    $the_settings = $the_settings[$params[1]['number']];

    if (isset($params[0]['id']) && $params[0]['id'] == 'home-sidebar-1') {
        if (!isset($the_settings['title']) && empty($the_settings['title'])) {
            $params[0]['before_widget'] .= '<div class="widget-inner">';
            $params[0]['after_widget']  .= '</div>';
        } else {
            $params[0]['after_widget']  .= '</div>';
            $params[0]['after_title']   .= '<div class="widget-inner">';
        }
    }

    return $params;
}
Razon K.
źródło
0

Jak wspomniano w komentarzach, niektóre podstawowe widżety dodają własny tytuł, który następnie jest dwukrotnie pakowany w div treści. Aby je usunąć, możesz po prostu zwrócić pusty ciąg. Jedynym minusem jest to, że musisz ręcznie wprowadzić wszystkie tytuły.

function remove_default_widget_title( $title, $instance = [], $id = '' ) {
    if ( isset($instance['title']) && trim($instance['title']) == '' ) {
        return '';
    }
    return $title;
};
add_filter( 'widget_title', 'remove_default_widget_title', 10, 3 );

Popraw mnie, jeśli coś mi brakuje, ale myślę, że to dość solidne.

Azragh
źródło