Ajouter une classe à before_widget à partir d'un widget personnalisé

10

J'ai un widget personnalisé simple qui demande sa largeur (qui sera utilisé plus tard dans le frontal). Le champ largeur est une liste déroulante de sélection, donc un utilisateur a des options prédéfinies.

J'aurai de nombreuses instances de mon widget, chacune aura sa propre configuration de largeur.

Maintenant, dans mon code widget, j'ai le code suivant:

echo $before_widget;

ce qui se traduit par:

<div class="widget my" id="my-widget-1"></div>

Ce que j'aimerais faire, c'est d'une manière ou d'une autre $before_widgetme connecter et ajouter ma propre classe (la largeur spécifiée dans la liste déroulante). Donc, je veux le balisage suivant:

<div class="widget my col480" id="my-widget-3"></div>

Et s'il n'y a pas de classe spécifiée, je veux ajouter class="col480".

Comment puis-je y parvenir?

Merci pour l'aide! Dasha

dashaluna
la source

Réponses:

14

Aha, de sorte que la $before_widgetvariable est une chaîne représentant div élément: <div class="widget my" id="my-widget-1">. J'ai donc vérifié la $before_widgetsous-chaîne "class" et y ai ajouté ma $widget_widthvaleur.

Le code provient de mon fichier de widget personnalisé:

function widget( $args, $instance ) {
  extract( $args );
  ... //other code

  $widget_width = !empty($instance['widget_width']) ? $instance['widget_width'] : "col300";
  /* Add the width from $widget_width to the class from the $before widget */
  // no 'class' attribute - add one with the value of width
  if( strpos($before_widget, 'class') === false ) {
    // include closing tag in replace string
    $before_widget = str_replace('>', 'class="'. $widget_width . '">', $before_widget);
  }
  // there is 'class' attribute - append width value to it
  else {
    $before_widget = str_replace('class="', 'class="'. $widget_width . ' ', $before_widget);
  }
  /* Before widget */
  echo $before_widget;

  ... //other code
}

Je voulais ajouter ma $widget_widthvariable à l'élément widget div dans mon propre code widget (alors que j'avais un accès facile à la $widget_widthvariable).

J'espère que cela a du sens et aidera quelqu'un.

Merci, Dasha

dashaluna
la source
beau travail - m'a aidé avec un problème de widget - merci :)
Q Studio
10

vous pouvez utiliser un dynamic_sidebar_paramscrochet de filtre pour trouver votre widget et y ajouter vos classes:

add_filter('dynamic_sidebar_params', 'add_classes_to__widget'); 
function add_classes_to__widget($params){
    if ($params[0]['widget_id'] == "my-widget-1"){ //make sure its your widget id here
        // its your widget so you add  your classes
        $classe_to_add = 'col480 whatever bla bla '; // make sure you leave a space at the end
        $classe_to_add = 'class=" '.$classe_to_add;
        $params[0]['before_widget'] = str_replace('class="',$classe_to_add,$params[0]['before_widget']);
    }
    return $params;
} 
Bainternet
la source
Merci pour la réponse. J'aurai beaucoup d'exemples de mon widget personnalisé chacun d'eux avec leur propre largeur spécifique. C'est pourquoi je voulais ajouter une classe supplémentaire dans le code du widget lui-même, plutôt que via un filtre. J'espère que cela a du sens?
dashaluna
les options d'instance sont enregistrées dans le tableau d'options afin que vous puissiez les obtenir à partir de là une fois que vous connaissez l'identifiant du widget en utilisantget_option('widget-name')
Bainternet
1
Merci beaucoup pour votre aide! Je suis désolé, je ne comprends pas vraiment votre solution :( Et je voulais que tout le code soit dans mon fichier de widget personnalisé, alors que je peux facilement accéder à la variable de largeur. J'ai fini par pirater la $before_widgetchaîne. Votre réponse m'a mis sur le bonne piste en découvrant que $before_widgetc'est une chaîne. Merci encore :)
dashaluna
Ce serait une option préférée car elle utilise des filtres wordpress plutôt que d'éditer les fichiers de thème
rhysclay
6

Une autre façon que j'ai trouvée pour ajouter une classe pour un widget personnalisé est d'utiliser la clé ' classname ' de votre fonction de construction comme dans:

class My_Widget_Class extends WP_Widget {
// Prior PHP5 use the children class name for the constructor…
// function My_Widget_Class()
       function __construct() {
            $widget_ops = array(
                'classname' => 'my-class-name',
                'description' => __("Widget for the sake of Mankind",'themedomain'),
            );
            $control_ops = array(
                'id_base' => 'my-widget-class-widget'
            );
   //some more code after...

   // Call parent constructor you may substitute the 1st argument by $control_ops['id_base'] and remove the 4th.
            parent::__construct(@func_get_arg(0),@func_get_arg(1),$widget_ops,$control_ops);
        }
}

Et assurez-vous d'utiliser par défaut ' before_widget ' dans votre thème ou si vous utilisez register_sidebar()dans function.php, faites-le comme ceci:

//This is just an example.
register_sidebar(array(
          'name'=> 'Sidebar',
            'id' => 'sidebar-default',
            'class' => '',//I never found where this is used...
            'description' => 'A sidebar for Mankind',
            'before_widget' => '<aside id="%1$s" class="widget %2$s">',//This is the important code!!
            'after_widget' => '</aside>',
            'before_title' => '<h3>',
            'after_title' => '</h3>',
        ));

Ensuite, sur toutes les instances de votre widget, vous aurez la classe 'widget my-class-name' comme ceci:

<aside class="widget my-class-name" id="my-widget-class-widget-N"><!-- where N is a number -->
  <h3>WIDGET TITLE</h3>
  <p>WIDGET CONTENT</p>
</aside>

Vous pouvez également appeler le constructeur parent en premier, puis ajouter le nom de classe que vous souhaitez:

class My_Widget_Class extends WP_Widget {
    // Better defining the parent argument list …
    function __construct($id_base, $name, $widget_options = array(), $control_options = array())
    {    parent::__construct($id_base, $name, $widget_options, $control_options);
         // Change the class name after
         $this->widget_options['classname'].= ' some-extra';
    }
}
anou
la source
1

ajoutez d'abord une classe d'espace réservé personnalisée dans le constructeur

<?php
public function __construct() {
   $widget_ops  = array(
      'classname'                   =>; 'widget_text eaa __eaa__', //__eaa__ is my placeholder css class
      'description'                 =>; __( 'AdSense ads, arbitrary text, HTML or JS.','eaa' ),
      'customize_selective_refresh' =>; true,
   );
   $control_ops = array( 'width' =>; 400, 'height' =>; 350 );
   parent::__construct( 'eaa', __( 'Easy AdSense Ads &amp; Scripts', 'eaa' ), $widget_ops, $control_ops );
}
?>

Ensuite, remplacez-le par la ou les classes de votre choix en fonction des options de widget comme celle-ci

<?php
if ( $instance['no_padding'] ) {
   $args['before_widget'] = str_replace( '__eaa__', 'eaa-clean', $args['before_widget'] );
}
?>

Vous pouvez trouver les détails avec exemple sur http://satishgandham.com/2017/03/adding-dynamic-classes-custom-wordpress-widgets/

Satish Gandham
la source
0

Vous pouvez essayer ce filtre:

/**
 * This function loops through all widgets in sidebar 
 * and adds a admin form value to the widget as a class name  
 *  
 * @param array $params Array of widgets in sidebar
 * @return array
*/

add_filter( 'dynamic_sidebar_params', 'nen_lib_add_class_to_widget' );
function nen_lib_add_class_to_widget( $params )
{
    foreach( $params as $key => $widget )
    {
        if( !isset($widget['widget_id']) ) continue;

        // my custom function to get widget data from admin form (object)
        $widget_data = nen_get_widget_data($widget['widget_id']) ;

        // check if field excists and has value
        if( isset($widget_data->wm_name) && $widget_data->wm_name )
        {
            // convert and put value in array
            $classes = array( sanitize_title( $widget_data->wm_name ) );

            // add filter, to be able to add more
            $classes = apply_filters( 'nen_lib_add_class_to_widget' , $classes , $widget['widget_id'] , $widget , $widget_data  );

            // get 'before_widget' element, set find and replace
            $string     = $params[$key]['before_widget'];
            $find       = '"widget ';
            $replace    = '"widget '.implode( ' ' , $classes ).' ';

            // new value
            $new_before = str_replace( $find , $replace , $string ) ;

            // set new value
            $params[$key]['before_widget'] = $new_before;
        }
    }
    return $params;
}
nenontwerp
la source