Añadir un div para envolver el contenido del widget después del título

3 dic 2012, 11:57:10
Vistas: 21.7K
Votos: 10

Estoy intentando añadir un div al contenido de un widget en mi barra lateral dinámica.

Aquí está el código de registro:

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><div class="content">',
    ));

Pero este código genera esto:

<div class="sidebar-box">
    <div class="title">{TÍTULO DEL WIDGET}</div>
     {CONTENIDO DEL WIDGET}
</div>

Esto es lo que estoy tratando de lograr:

<div class="sidebar-box">
    <div class="title">{TÍTULO DEL WIDGET}</div>
    <div class="content">
           {CONTENIDO DEL WIDGET}
    </div> 
</div>

¿Cómo se puede hacer?

0
Todas las respuestas a la pregunta 7
4
19

Además de la respuesta de Toscho, aquí está lo que necesitas para una solución robusta:

// si no hay título, entonces añade el contenedor de contenido del widget antes 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;
}

De la respuesta de 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">',
));

Lo que esto hace es:

  • verifica la configuración de la barra lateral registrada para widgets que terminan con 2 cierres de <div>
  • comprueba si no hay título
  • si no lo hay, modifica la salida de before_widget para mostrar el div de apertura del contenido del widget

Podrías usar este enfoque para cambiar los argumentos de la barra lateral de otras formas basadas en la configuración de la instancia del widget.

3 dic 2012 14:54:49
Comentarios

Tengo un problema con eso: algunos widgets (como los predeterminados de WP, por ejemplo) establecen un título por defecto si lo dejas en blanco. Entonces tu función añade el div porque no hay un título en los parámetros en ese momento, pero el widget lo añade después y el código queda desordenado. ¿Sabes cómo verificar el título "desde dentro" del widget? Gracias

Cmorales Cmorales
25 ene 2013 03:36:34

No sin añadir una verificación widget por widget o algún código terriblemente complejo para renderizar el widget en silencio y luego analizarlo en busca de un título... Lo pensaré

sanchothefat sanchothefat
25 ene 2013 19:07:57

¿Quizás engancharse a esto http://codex.wordpress.org/Function_Reference/the_widget ayudaría? Lo usan (por otro motivo) en este artículo http://wp.smashingmagazine.com/2012/12/11/inserting-widgets-with-shortcodes/

Cmorales Cmorales
29 ene 2013 02:53:32

the_widget() no se utiliza en la función dynamic_sidebar(), es un medio para llamar a cualquier widget con opciones que especifiques en su lugar. Es otro lugar para filtrar, aunque mi solución no cubre esa eventualidad. Saludos

sanchothefat sanchothefat
29 ene 2013 19:14:37
1

Me gustó la idea de ambas respuestas de @tosco y @sanchothefat, sin embargo tuve problemas con esa combinación porque aunque empty( $settings[ 'title' ] podría devolver verdadero, el widget en sí podría mostrar un título por defecto si no se establece ninguno. Este título luego se envuelve en el marcado before_title y after_title y de nuevo la página se rompe. Ese es el caso con algunos de los widgets por defecto de WordPress.

Es más fácil simplemente apegarse a los parámetros estándar de registro de widgets:

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>',
));

Y luego añadir una acción de filtro como en la respuesta de Marventus aquí:

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');
25 sept 2013 17:37:58
Comentarios

y eso solo funciona para "Widgets de Texto"

Prashant Pugalia Prashant Pugalia
15 dic 2014 16:23:18
3

Añade el segundo div al parámetro del título:

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">',
    ));
3 dic 2012 11:59:38
Comentarios

Eso falla si no hay un título para el widget - aunque se puede solucionar

sanchothefat sanchothefat
3 dic 2012 12:15:11

Sí, falla cuando no hay título...

MBraiN MBraiN
3 dic 2012 14:06:38

He añadido una respuesta con código para solucionar el problema de los títulos. Probablemente debería fusionarse con la de Toscho, pero él ya tiene una reputación épica :)

sanchothefat sanchothefat
3 dic 2012 14:56:47
1

Esto es lo que debes hacer para lograrlo:

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">',
    ))

Cuando no hay título obtendrás:

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

Cuando hay un título obtendrás:

<div class="sidebar-box"><div class="content">
</div><div class="title">
{TÍTULO}
<div class="content">
{CONTENIDO}
</div></div>

Para asegurarte de que el primer div de contenido vacío no se muestre en el último caso, añade esto a tu css:

.sidebar-box .content:empty {display:none !important;}
14 nov 2015 18:17:36
Comentarios

Muy inteligente manera y funciona.

Mohammed Mohammed
21 ene 2021 20:38:43
1

Después de revisar las respuestas anteriores, creo que solucioné el problema que Cmorales identificó con la respuesta de sanchothefat. Define tu widget de la siguiente manera:

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

Es importante eliminar los valores predeterminados de before_title y after_title. Después de varias pruebas, noté que el primer filtro que mostraba un título predeterminado era widget_title. Luego usa el filtro widget_title de la siguiente manera:

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

Básicamente, <div class="panel-heading"><h3 class="panel-title"> es mi before_title y </h3></div> es mi after_title. Finalmente, usa dynamic_sidebar_params para anteponer un div de cierre para nuestro contenedor de contenido:

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

No es la solución más elegante, pero funciona.

3 abr 2014 21:52:22
Comentarios

Inicialmente estaba muy emocionado con este enfoque, pero me encontré con un problema en los widgets que utilizan esc_html($title) (como BuddyPress). Cuando ese es el caso, el HTML añadido se muestra escapado y no se renderiza en el front end.

Ryan Ryan
25 ago 2014 05:53:35
0

Acabo de modificar ligeramente el código para no tener que tocar register_sidebar. Registrar una barra lateral de la manera habitual:

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

Y a continuación, el código modificado de la solución de Sanchothefat:

/**
 * Si no se proporciona un título, añade el envoltorio widget-content a before_widget
 * Si se proporciona un título, añade el envoltorio de contenido 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;
}
23 mar 2019 01:15:39
0

Como se mencionó en los comentarios, algunos widgets principales agregan su propio título que luego se envuelve dos veces con el div de contenido. Para eliminarlos, podrías simplemente devolver una cadena vacía. El único inconveniente es que tienes que ingresar todos los títulos manualmente.

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

Corrígeme si me equivoco en algo aquí, pero creo que es bastante sólido.

14 feb 2020 17:18:03