Ajout d'un div pour envelopper le contenu du widget après le titre du widget

10

J'essaie d'ajouter une div au contenu d'un widget dans ma barre latérale dynamique.

Voici le code d'enregistrement;

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

Mais ce code provoque comme ça;

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

Voici ce que j'essaie de faire;

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

Comment cela peut-il être fait?

MBraiN
la source

Réponses:

18

En plus de la réponse de Toscho, voici ce dont vous avez besoin pour une solution robuste:

// 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 réponse 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">',
));

Ce que cela signifie:

  • vérifie les paramètres de la barre latérale enregistrée pour les widgets se terminant par 2 fermetures <div>s
  • vérifie s'il n'y a pas de titre
  • sinon, il modifie la before_widgetsortie pour afficher la div du contenu du widget d'ouverture

Vous pouvez utiliser cette approche pour modifier les arguments de la barre latérale d'une autre manière en fonction des paramètres de l'instance de widget.

sanchothefat
la source
J'ai un problème avec cela: certains widgets (comme ceux par défaut de WP, par exemple) définissent un titre par défaut si vous laissez ce champ vide. Votre fonction ajoute donc le div car il n'y a pas de titre dans les paramètres à ce stade, mais le widget l'ajoute ensuite et le code est foiré. Savez-vous comment vérifier le titre "à l'intérieur" du widget? Merci
Cmorales
Non sans ajouter un widget par chèque widget ou un code effroyablement complexe pour rendre le widget en silence , puis l' analyser pour un titre ... Auront THINK
sanchothefat
Peut-être que le raccordement à ce codex.wordpress.org/Function_Reference/the_widget aiderait? Ils l'utilisent (pour une autre raison) dans cet article wp.smashingmagazine.com/2012/12/11/…
Cmorales
1
the_widget()n'est pas utilisé dans la dynamic_sidebar()fonction, c'est un moyen d'appeler n'importe quel widget avec les options que vous spécifiez en place. C'est un autre endroit pour filtrer, donc ma solution ne couvre pas cette éventualité. Acclamations
sanchothefat
2

Ajoutez le second divau paramètre title:

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
la source
Cela échoue s'il n'y a pas de titre de widget - cela peut être fait cependant
sanchothefat
Oui ça échoue quand il n'y a pas de titre ..
MBraiN
J'ai ajouté une réponse avec du code pour résoudre le problème des titres. Devrait probablement être fusionné avec Toscho, mais il a déjà un représentant épique :)
sanchothefat
2

J'ai aimé l'idée des réponses @tosco et @sanchothefat - mais j'ai eu du mal avec cette combinaison parce que empty( $settings[ 'title' ]bien qu'il puisse en effet retourner vrai, le widget lui-même pourrait afficher un titre par défaut si aucun n'est défini. Ce titre est ensuite enveloppé dans les before_titleet after_titlebalisage et encore les sauts de page. C'est de toute façon le cas avec certains des widgets par défaut.

Plus facile de simplement s'en tenir aux paramètres d'enregistrement de widget standard;

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

puis ajoutez une action de filtrage selon la réponse de Marventus ici;

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
la source
3
et cela ne fonctionne que pour les "Text Widgets"
Silver Moon
1

Voici ce que vous faites pour y parvenir:

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

Quand il n'y a pas de titre, vous obtiendrez:

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

Quand il y a un titre, vous obtiendrez:

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

Pour vous assurer que le premier contenu-div vide ne s'affiche pas dans ce dernier cas, ajoutez-le à votre CSS:

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

Après avoir regardé les réponses précédentes, je pense avoir corrigé le problème identifié par Cmorales avec la réponse de sanchothefat. Définissez votre widget comme suit:

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

Il est important que les paramètres par défaut before_titleet after_titlesoient supprimés. Après quelques essais et erreurs, j'ai remarqué que le premier filtre qui montrait un titre par défaut était widget_title. Ensuite, utilisez le widget_titlefiltre comme suit:

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

Fondamentalement, <div class="panel-heading"><h3 class="panel-title">c'est mon before_titleet </h3></div>c'est mon after_title. Enfin, utilisez dynamic_sidebar_paramspour ajouter un div de fermeture pour notre habillage de contenu:

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

Ce n'est pas joli, mais ça marche.

Spencer
la source
Était initialement très excité par cette approche, mais j'ai rencontré un problème avec les widgets qui utilisent esc_html ($ title) (ie BuddyPress). Dans ce cas, le code HTML ajouté est affiché échappé et non rendu sur le front-end.
Ryan
0

Je change juste légèrement le code pour ne pas avoir besoin de toucher register_sidebar . Enregistrez une barre latérale de manière régulière:

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

Et ci-dessous est le code modifié de la solution 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.
la source
0

Comme mentionné dans les commentaires, certains widgets principaux ajoutent leur propre titre qui est ensuite enveloppé deux fois avec la div de contenu. Pour les supprimer, vous pouvez simplement retourner une chaîne vide. Le seul inconvénient est que vous devez saisir tous les titres manuellement.

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

Corrigez-moi si je manque quelque chose ici, mais je pense que c'est assez solide.

Azragh
la source