Agregar clase a before_widget desde un widget personalizado

10

Tengo un widget personalizado simple que solicita su ancho (que se usa más adelante en el front-end). El campo de ancho es un menú desplegable de selección, por lo que un usuario tiene opciones predefinidas.

Tendré muchas instancias de mi widget, cada una tendrá su propia configuración de ancho.

Ahora, en mi código de widget tengo el siguiente código:

echo $before_widget;

lo que resulta en:

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

Lo que me gustaría hacer es de alguna manera conectar $before_widgety agregar mi propia clase (el ancho especificado en el menú desplegable de selección). Entonces, quiero el siguiente marcado:

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

Y si no hay una clase especificada, entonces quiero agregar class="col480".

¿Cómo logro esto?

¡Gracias por la ayuda! Dasha

dashaluna
fuente

Respuestas:

14

Aha, por lo que la $before_widgetvariable es una cadena que representa el elemento div: <div class="widget my" id="my-widget-1">. Así que verifiqué la subcadena $before_widgetde "clase" y le agregué mi $widget_widthvalor.

El código es de mi archivo de widget personalizado:

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
}

Quería agregar mi $widget_widthvariable al elemento div del widget dentro de mi propio código de widget (aunque tenía un acceso fácil a la $widget_widthvariable).

Espero que tenga sentido y ayude a alguien.

Gracias Dasha

dashaluna
fuente
buen trabajo - me ayudó con un problema de widget - gracias :)
Q Studio
10

puedes usar dynamic_sidebar_paramsfilter hook para encontrar tu widget y agregarle tus clases:

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
fuente
gracias por la respuesta. Tendré muchas instancias de mi widget personalizado, cada una de ellas con su propio ancho específico. Es por eso que quería agregar una clase adicional dentro del código del widget, en lugar de hacerlo a través del filtro. Espero que tenga sentido?
dashaluna 01 de
así opciones de instancia se guardan en la tabla de opciones para que pueda obtener a partir de ahí una vez que conozca el identificador de widget de usoget_option('widget-name')
Bainternet
1
¡muchas gracias por tu ayuda! Lo siento, realmente no entiendo su solución :( Y quería que todo el código estuviera dentro de mi archivo de widget personalizado, mientras puedo acceder fácilmente a la variable de ancho. Terminé hackeando la $before_widgetcadena. Su respuesta me puso en el descubriendo que $before_widgetes una cadena. Gracias de nuevo :)
dashaluna 02 de
Esta sería una opción preferida, ya que utiliza filtros de WordPress en lugar de editar los archivos de tema
rhysclay
6

Otra forma en que encontré agregar una clase para un widget personalizado es usar la tecla ' classname ' de su función de construcción como en:

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

Y asegúrese de usar el ' before_widget ' predeterminado en su tema o si lo usa register_sidebar()en function.php, hágalo así:

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

Luego, en cada instancia de su widget, tendrá la clase 'widget my-class-name' como esta:

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

También puede llamar primero al constructor principal y luego agregar cualquier nombre de clase que desee:

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
fuente
1

primero agregue una clase de marcador de posición personalizada en el constructor

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

Luego, reemplácelo con la clase o clases que elija según las opciones de widget como esta

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

Puede encontrar los detalles con un ejemplo en http://satishgandham.com/2017/03/adding-dynamic-classes-custom-wordpress-widgets/

Satish Gandham
fuente
0

Puedes probar este filtro:

/**
 * 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
fuente