Agregar un div para envolver el contenido del widget después del título del widget

10

Estoy tratando de agregar 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>',
    ));

Pero este código causa así;

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

Esto es lo que estoy tratando de hacer;

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

¿Cómo se puede hacer?

MBraiN
fuente

Respuestas:

18

Además de la respuesta de Toscho, esto es lo que necesita para una solución sólida:

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

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:

  • comprueba la configuración de la barra lateral registrada para widgets que terminan en 2 <div>s de cierre
  • comprueba si no hay título
  • si no, modifica la before_widgetsalida para mostrar el contenido del widget de apertura div

Puede usar este enfoque para cambiar los argumentos de la barra lateral de otras maneras según la configuración de la instancia del widget.

Sanchothefat
fuente
Tengo un problema con eso: algunos widgets (como los predeterminados de WP, por ejemplo) establecen un título predeterminado si lo dejas en blanco. Entonces, su función agrega el div porque no hay un título en los parámetros en ese punto, pero el widget lo agrega después y el código está en mal estado. ¿Sabes cómo verificar el título desde "dentro" del widget? Gracias
Cmorales
No sin añadir un widget con cheque del widget o algún código terriblemente compleja para mostrar el widget en silencio y luego analizarlo para un título ... Tendrá un pensar
sanchothefat
¿Quizás ayudaría engancharse a este codex.wordpress.org/Function_Reference/the_widget ? Lo usan (por otra razón) en este artículo wp.smashingmagazine.com/2012/12/11/…
Cmorales
1
the_widget()no se usa en la dynamic_sidebar()función, es una forma de llamar a cualquier widget con las opciones que especifique en su lugar. Sin embargo, es otro lugar para filtrar, por lo que mi solución no cubre esa eventualidad. Saludos
sanchothefat
2

Agregue el segundo dival parámetro de 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">',
    ));
fuxia
fuente
Eso falla si no hay un título de widget, aunque se puede hacer
sanchothefat
Sí, falla cuando no hay título ..
MBraiN
Agregué una respuesta con algún código para solucionar el problema de los títulos. Probablemente debería fusionarse con el de Toscho, pero ya tiene un representante épico :)
sanchothefat
2

Me gustó la idea de las respuestas @tosco y @sanchothefat; sin embargo, he tenido problemas con esa combinación porque, si bien empty( $settings[ 'title' ]podría ser cierto, el widget en sí podría generar un título predeterminado si no se configura ninguno. Este título se envuelve en las before_titley after_titlede marcado y de nuevo los saltos de página. Ese es el caso con algunos de los widgets predeterminados de todos modos.

Es más fácil limitarse 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 agregue una acción de filtro según 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');
rabmcnab
fuente
3
y eso solo funciona para "Text Widgets"
Silver Moon
1

Esto es lo que haces para lograr esto:

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 haya título, obtendrá:

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

Cuando haya un título obtendrás:

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

Para asegurarse de que el primer content-div vacío no se muestre en el último caso, agregue esto a su CSS:

.sidebar-box .content:empty {display:none !important;}
cjbj
fuente
0

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

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

Es importante que se eliminen los valores predeterminados before_titley after_title. Después de algunas pruebas y errores, noté que el primer filtro que mostraba un título predeterminado era widget_title. Luego use el widget_titlefiltro así:

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_titley </h3></div>es mi after_title. Finalmente, use dynamic_sidebar_paramspara anteponer un div de cierre para nuestro ajuste de contenido:

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

No es bonito, pero funciona.

Spencer
fuente
Inicialmente estaba muy entusiasmado con este enfoque, pero me encontré con un problema con los widgets que usan esc_html ($ title) (es decir, BuddyPress). Cuando ese es el caso, el HTML agregado se muestra escapado y no representado en el front-end.
Ryan
0

Solo cambio ligeramente el código para que no necesite tocar register_sidebar . Registre una barra lateral de manera regular:

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

Y a continuación se muestra el código modificado de la solución de 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.
fuente
0

Como se menciona en los comentarios, algunos widgets principales agregan su propio título que luego se envuelve dos veces con el contenido div. Para eliminarlos, simplemente puede devolver una cadena vacía. El único inconveniente es que debe 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 falta algo aquí, pero creo que es bastante sólido.

Azragh
fuente