Aggiungere un div per racchiudere il contenuto del widget dopo il titolo
Sto cercando di aggiungere un div al contenuto di un widget nella mia sidebar dinamica.
Ecco il codice di registrazione;
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>',
));
Ma questo codice genera una struttura così:
<div class="sidebar-box">
<div class="title">{TITOLO DEL WIDGET}</div>
{CONTENUTO DEL WIDGET}
</div>
Ecco quello che sto cercando di ottenere:
<div class="sidebar-box">
<div class="title">{TITOLO DEL WIDGET}</div>
<div class="content">
{CONTENUTO DEL WIDGET}
</div>
</div>
Come si può realizzare?

Oltre alla risposta di Toscho, ecco ciò che ti serve per una soluzione robusta:
// se non c'è titolo allora aggiungi il wrapper del contenuto del widget prima del 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;
}
Dalla risposta di 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">',
));
Questo codice fa quanto segue:
- controlla le impostazioni per la sidebar registrata per i widget che terminano con 2 tag
<div>
di chiusura - verifica se non c'è un titolo
- se non c'è, modifica l'output di
before_widget
per mostrare il div di apertura del contenuto del widget
Puoi utilizzare questo approccio per modificare gli argomenti della sidebar in altri modi basandoti sulle impostazioni dell'istanza del widget.

Ho un problema con questo: alcuni widget (come quelli predefiniti di WP, ad esempio) impostano un titolo predefinito se lo lasci vuoto. Quindi la tua funzione aggiunge il div perché in quel momento non c'è un titolo nei parametri, ma poi il widget lo aggiunge e il codice risulta incasinato. Sai come verificare il titolo "dall'interno" del widget? Grazie

Non senza aggiungere un controllo widget per widget o del codice terribilmente complesso per renderizzare il widget in silenzio e poi analizzarlo per trovare un titolo... Ci penserò

Forse agganciarsi a questo http://codex.wordpress.org/Function_Reference/the_widget potrebbe aiutare? Lo usano (per altri motivi) in questo articolo http://wp.smashingmagazine.com/2012/12/11/inserting-widgets-with-shortcodes/

Mi è piaciuta l'idea di entrambe le risposte di @tosco e @sanchothefat - tuttavia ho avuto difficoltà con quella combinazione perché mentre empty( $settings[ 'title' ]
potrebbe effettivamente restituire true, il widget stesso potrebbe comunque emettere un titolo predefinito se nessuno è impostato. Questo titolo viene poi avvolto nel markup before_title
e after_title
e di nuovo la pagina si rompe. Questo è il caso di alcuni widget predefiniti comunque.
È più semplice attenersi ai parametri standard di registrazione dei widget:
register_sidebar(array(
'id' => 'sidebar1',
'name' => __( 'Sidebar 1', 'bonestheme' ),
'description' => __( 'La prima sidebar (primaria).', 'bonestheme' ),
'before_widget' => '<div class="block">',
'after_widget' => '</div>',
'before_title' => '<div class="block-title">',
'after_title' => '</div>',
));
e poi aggiungere un'azione di filtro come nella risposta di Marventus qui:
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');

Aggiungi il secondo div
al parametro del titolo:
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">',
));

Questo fallisce se non c'è un titolo per il widget - però può essere fatto

Ecco cosa devi fare per ottenere questo risultato:
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">',
))
Quando non c'è un titolo otterrai:
<div class="sidebar-box"><div class="content">
{CONTENT}
</div></div>
Quando c'è un titolo otterrai:
<div class="sidebar-box"><div class="content">
</div><div class="title">
{TITLE}
<div class="content">
{CONTENT}
</div></div>
Per assicurarti che il primo div content vuoto non venga visualizzato nel secondo caso, aggiungi questo al tuo CSS:
.sidebar-box .content:empty {display:none !important;}

Dopo aver esaminato le risposte precedenti, penso di aver risolto il problema identificato da Cmorales nella soluzione di sanchothefat. Definisci il tuo widget come segue:
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' => ''
) );
È importante rimuovere i valori predefiniti di before_title
e after_title
. Dopo alcuni tentativi ho notato che il primo filtro che mostrava un titolo predefinito era widget_title
. Quindi utilizza il filtro widget_title
in questo modo:
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;
}
In sostanza, <div class="panel-heading"><h3 class="panel-title">
è il mio before_title
e </h3></div>
è il mio after_title
. Infine, usa dynamic_sidebar_params
per anteporre un div di chiusura per il nostro contenuto:
function dynamic_sidebar_params( $params ) {
$params[0]['after_widget'] = '</div>' . $params[0]['after_widget'];
return $params;
}
Non è elegante, ma funziona.

Ho apportato una piccola modifica al codice in modo da non dover modificare register_sidebar. Registro una sidebar nel modo standard:
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>',
));
Ecco il codice modificato basato sulla soluzione di Sanchothefat:
/**
* Se nessun titolo è fornito, aggiunge il wrapper widget-content a before_widget
* Se il titolo è fornito, aggiunge il content wrapper a 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;
}

Come menzionato nei commenti, alcuni widget core aggiungono il proprio titolo che poi viene avvolto due volte con il div del contenuto. Per rimuoverli, potresti semplicemente restituire una stringa vuota. L'unico svantaggio è che devi inserire manualmente tutti i titoli.
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 );
Correggimi se mi sto perdendo qualcosa, ma penso che sia abbastanza solido.
