web-dev-qa-db-fra.com

Comment: ajouter une classe à la liste d'éléments de liste de widgets de la barre latérale

La dernière version de Bootstrap (v3.0) ajoute un nouveau composant List Group qui présente la structure suivante:

<ul class="list-group">
  <li class="list-group-item">Cras justo odio</li>
  <li class="list-group-item">Dapibus ac facilisis in</li>
  <li class="list-group-item">Morbi leo risus</li>
  <li class="list-group-item">Porta ac consectetur ac</li>
  <li class="list-group-item">Vestibulum at eros</li>
</ul>
  1. J'aimerais pouvoir ajouter une classe au ul (i.e. <ul class="list-group">)
  2. Je voudrais appeler mon widgetCatégorie/ sidebar pour prendre en charge ce nouveau composant, mais comme vous le voyez, cela nécessite des classes surchaqueli article.

En lisant des articles similaires, une option que j’ai trouvée est de utiliser jQuery pour ajouter la classe à chaque li, mais je suis préoccupé par leFOUC.

Existe-t-il une fonction WordPress qui me permet d'atteindre mon objectif?

S'il vous plaît donnez votre avis,

Mise à jour:

J'ai pu ajouter des classes à chacun des li en créant un Walker personnalisé qui étend Walker_Category (voir le code ci-dessous), mais cela ne me permet toujours pas d'accéder à ul qui nécessite également l'ajout d'une classe (par exemple <ul class="list-group">).

class Walker_Category_BS extends Walker_Category {
    function start_el( &$output, $category, $depth = 0, $args = array() ) {
        extract($args);

        $cat_name = esc_attr( $category->name );
        $cat_name = apply_filters( 'list_cats', $cat_name, $category );
        $link = '<a href="' . esc_url( get_term_link($category) ) . '" ';
        if ( $use_desc_for_title == 0 || empty($category->description) )
            $link .= 'title="' . esc_attr( sprintf(__( 'View all posts filed under %s' ), $cat_name) ) . '"';
        else
            $link .= 'title="' . esc_attr( strip_tags( apply_filters( 'category_description', $category->description, $category ) ) ) . '"';
        $link .= '>';
        $link .= $cat_name . '</a>';

        if ( !empty($feed_image) || !empty($feed) ) {
            $link .= ' ';

            if ( empty($feed_image) )
                $link .= '(';

            $link .= '<a href="' . esc_url( get_term_feed_link( $category->term_id, $category->taxonomy, $feed_type ) ) . '"';

            if ( empty($feed) ) {
                $alt = ' alt="' . sprintf(__( 'Feed for all posts filed under %s' ), $cat_name ) . '"';
            } else {
                $title = ' title="' . $feed . '"';
                $alt = ' alt="' . $feed . '"';
                $name = $feed;
                $link .= $title;
            }

            $link .= '>';

            if ( empty($feed_image) )
                $link .= $name;
            else
                $link .= "<img src='$feed_image'$alt$title" . ' />';

            $link .= '</a>';

            if ( empty($feed_image) )
                $link .= ')';
        }

        if ( !empty($show_count) )
            $link .= ' (' . intval($category->count) . ')';

        if ( 'list' == $args['style'] ) {
            $output .= "\t<li";
            $class = 'list-group-item cat-item cat-item-' . $category->term_id;
            if ( !empty($current_category) ) {
                $_current_category = get_term( $current_category, $category->taxonomy );
                if ( $category->term_id == $current_category )
                    $class .=  ' current-cat';
                elseif ( $category->term_id == $_current_category->parent )
                    $class .=  ' current-cat-parent';
            }
            $output .=  ' class="' . $class . '"';
            $output .= ">$link\n";
        } else {
            $output .= "\t$link<br />\n";
        }
    } /* end start_el */

} /* end Walker_Category_BS */

Mise à jour 02:

Après avoir visionné default-widgets.php dans le noyau, j'ai décidé de créer un nouveau widget (WP_Widget_Categories_BS, voir le code ci-dessous) dans lequel, en gros, j'ai copié tout le code du widget de catégorie par défaut et simplement modifié le UL pour ajouter la classe nécessaire.

<?php 

/**
 * Categories widget class
 *
 * @since 2.8.0
 */
class WP_Widget_Categories_BS extends WP_Widget {

    function __construct() {
        $widget_ops = array( 'classname' => 'widget_categories_bs', 'description' => __( "A list or dropdown of categories for Bootstrap 3.0" ) );
        parent::__construct('categories', __('Boostrap Categories'), $widget_ops);
    }

    function widget( $args, $instance ) {
        extract( $args );

        $title = apply_filters('widget_title', empty( $instance['title'] ) ? __( 'Categories' ) : $instance['title'], $instance, $this->id_base);
        $c = ! empty( $instance['count'] ) ? '1' : '0';
        $h = ! empty( $instance['hierarchical'] ) ? '1' : '0';
        $d = ! empty( $instance['dropdown'] ) ? '1' : '0';

        echo $before_widget;
        if ( $title )
            echo $before_title . $title . $after_title;

        $cat_args = array('orderby' => 'name', 'show_count' => $c, 'hierarchical' => $h);
        if ( $d ) {
            $cat_args['show_option_none'] = __('Select Category');
            wp_dropdown_categories(apply_filters('widget_categories_dropdown_args', $cat_args));
?>

<script type='text/javascript'>
/* <![CDATA[ */
    var dropdown = document.getElementById("cat");
    function onCatChange() {
        if ( dropdown.options[dropdown.selectedIndex].value > 0 ) {
            location.href = "<?php echo home_url(); ?>/?cat="+dropdown.options[dropdown.selectedIndex].value;
        }
    }
    dropdown.onchange = onCatChange;
/* ]]> */
</script>

<?php
        } else {
?>
        <ul class="list-group">
<?php
        $cat_args['title_li'] = '';
        wp_list_categories(apply_filters('widget_categories_args', $cat_args));
?>
        </ul>
<?php
        }

        echo $after_widget;
    }

    function update( $new_instance, $old_instance ) {
        $instance = $old_instance;
        $instance['title'] = strip_tags($new_instance['title']);
        $instance['count'] = !empty($new_instance['count']) ? 1 : 0;
        $instance['hierarchical'] = !empty($new_instance['hierarchical']) ? 1 : 0;
        $instance['dropdown'] = !empty($new_instance['dropdown']) ? 1 : 0;

        return $instance;
    }

    function form( $instance ) {
        //Defaults
        $instance = wp_parse_args( (array) $instance, array( 'title' => '') );
        $title = esc_attr( $instance['title'] );
        $count = isset($instance['count']) ? (bool) $instance['count'] :false;
        $hierarchical = isset( $instance['hierarchical'] ) ? (bool) $instance['hierarchical'] : false;
        $dropdown = isset( $instance['dropdown'] ) ? (bool) $instance['dropdown'] : false;
?>
        <p><label for="<?php echo $this->get_field_id('title'); ?>"><?php _e( 'Title:' ); ?></label>
        <input class="widefat" id="<?php echo $this->get_field_id('title'); ?>" name="<?php echo $this->get_field_name('title'); ?>" type="text" value="<?php echo $title; ?>" /></p>

        <p><input type="checkbox" class="checkbox" id="<?php echo $this->get_field_id('dropdown'); ?>" name="<?php echo $this->get_field_name('dropdown'); ?>"<?php checked( $dropdown ); ?> />
        <label for="<?php echo $this->get_field_id('dropdown'); ?>"><?php _e( 'Display as dropdown' ); ?></label><br />

        <input type="checkbox" class="checkbox" id="<?php echo $this->get_field_id('count'); ?>" name="<?php echo $this->get_field_name('count'); ?>"<?php checked( $count ); ?> />
        <label for="<?php echo $this->get_field_id('count'); ?>"><?php _e( 'Show post counts' ); ?></label><br />

        <input type="checkbox" class="checkbox" id="<?php echo $this->get_field_id('hierarchical'); ?>" name="<?php echo $this->get_field_name('hierarchical'); ?>"<?php checked( $hierarchical ); ?> />
        <label for="<?php echo $this->get_field_id('hierarchical'); ?>"><?php _e( 'Show hierarchy' ); ?></label></p>
<?php
    }

} // end WP_Widget_Categories_BS

Combiné avec un Walker personnalisé que j'ai créé (Walker_Category_BS), j'ai maintenant ce que je voulais.

Analyse

Est-ce la meilleure façon de le faire? Je ne sais pas comme je n’ai reçu aucun retour jusqu’à présent, c’est la première fois que je fais cela (d’où la question), mais… ça marche! Je pourrais utiliser une critique.

Avertissement de débogage

En ce qui concerne ma catégorie personnalisée Walker Walker_Category_BS, je vois ce message.

"Normes strictes: la déclaration de Walker_Category_BS :: start_el () doit être compatible avec Walker :: start_el (& $ output, $ object, $ depth = 0, $ args = Array, $ current_object_id = 0) dans C:\wamp\www\mysite\wp-content\themes\mytheme\assets\inc\Walker_Category_BS.php "

Cela semble être un avertissement, en quelque sorte.

4
sleeper

Mise à jour: 19/12/15 : Voici un plugin sur Github que j'ai développé (en utilisant la méthode de la réponse que j'ai fournie ci-dessous) en ajoutant le support pour changer tous les widgets en bootstrap des composants/styling.


 Wordpress Widgets Bootstrapped 



Réponse originale

Je comprends ne pas vouloir utiliser javascript, mais il me semble exagéré, à mon avis, de créer complètement un nouveau widget juste pour que la classe list-group soit ajoutée à la classe du widget <ul> html tag. If you look at what the list-group ne vous fait remarquer que tout ce que vous faites est de supprimer le remplissage par défaut du navigateur. en ajoutant des marges inférieures.

.list-group {
    padding-left: 0;
    margin-bottom: 0;
}

Très probablement, vous ne souhaiterez même pas les marges du bas car vous devez ajouter les marges par défaut au .widget ou à une barre latérale similaire before_widget class dans votre css de thèmes.

Par exemple: Définition des marges du widget de la barre latérale par défaut

.sidebar-primary .widget {
    margin-bottom: 20px;
}

En gros, le seul avantage réel de la classe est donc de supprimer le remplissage du navigateur par défaut pour les listes. C’est aussi quelque chose (à mon avis) que vous devriez probablement faire dans vos CSS car c’est de cette façon que bootstrap le gère.

.sidebar-primary .widget.widget_categories {
    padding-left: 0;
}

En ce qui concerne les classes list-group-item sur les éléments <li>, nous pouvons utiliser le filtre wp_list_categories pour cela. Et tant que nous y sommes, nous pourrions aussi bien changer le style de count en bootstraps formating ...

function bs_categories_list_group_filter ($variable) {
   $variable = str_replace('<li class="cat-item cat-item-', '<li class="list-group-item cat-item cat-item-', $variable);
   $variable = str_replace('(', '<span class="badge cat-item-count"> ', $variable);
   $variable = str_replace(')', ' </span>', $variable);
   return $variable;
}
add_filter('wp_list_categories','bs_categories_list_group_filter');

Si vous devez avoir list-group ajouté avec php et ne voulez pas utiliser css ou javascript, vous avez quelques autres options ...

Option 1 - Utilisez la mise en mémoire tampon de sortie dans vos modèles de thème:

ob_start();
dynamic_sidebar( 'registered-sidebar-name' );
$sidebar_output = ob_get_clean();
echo apply_filters( 'primary_sidebar_filter', $sidebar_output );

Ensuite, dans votre function.php, vous utiliseriez le primary_sidebar_filter et utiliseriez regex pour remplacer le code HTML par défaut.

function bs_add_list_group_to_cats( $sidebar_output ) {

    // Regex goes here...
    // Needs to be a somewhat sophisticated since it's running on the entire sidebar, not just the categories widget. 

    $regex = "";
    $replace_with = "";
    $widget_output = preg_replace( $regex , $replace_with , $widget_output );    

    return $sidebar_output;

}
add_filter( 'primary_sidebar_output', 'bs_add_list_group_to_cats' );

Option 2 - Utiliser la mise en mémoire tampon de sortie dans un plugin/en dehors de vos modèles:

C’est probablement la meilleure façon de procéder car cela vous donne beaucoup plus de liberté pour personnaliser vos widgets. Cela peut être ajouté sous forme de plugin grâce à Philip Newcomer ou directement sur votre functions.php avec ce code .

Ensuite, pour utiliser la nouvelle fonction de rappel pour le filtrage de votre widget de catégorie (pour ajouter un style bootstrap), vous devez ajouter ceci à votre functions.php:

function wpse_my_widget_output_filter( $widget_output, $widget_type, $widget_id ) {
    if ( 'categories' == $widget_type ) {
        $widget_output = str_replace('<ul>', '<ul class="list-group">', $widget_output);
        $widget_output = str_replace('<li class="cat-item cat-item-', '<li class="list-group-item cat-item cat-item-', $widget_output);
        $widget_output = str_replace('(', '<span class="badge cat-item-count"> ', $widget_output);
        $widget_output = str_replace(')', ' </span>', $widget_output);
    }      
      return $widget_output;
}
add_filter( 'widget_output', 'my_widget_output_filter_footer', 10, 3 ); 
5
Bryan Willis

qu'en est-il de la création d'une barre latérale séparée pour ce widget et de l'ajout d'une classe à l'aide de la fonction register_sidebar?

register_sidebar(array(
    'name' => 'First_sidebar',
    'id' => 'sidebar-1',
    'class'         => 'ul-class-name',
    'before_widget' => '<div class="well">',
    'after_widget' => '</div>',
    'before_title' => '<h4>',
    'after_title' => '</h4>'
));
1
codepixlabs

Mise à jour : J'ai corrigé l'avertissement de débogage et tout semble fonctionner. En l'absence de tout autre commentaire, j'accepterai ma propre solution décrite dans les mises à jour des questions d'origine.

1
sleeper