Añadir clase a before_widget desde dentro de un widget personalizado

1 jun 2011, 15:00:10
Vistas: 19.7K
Votos: 10

Tengo un widget personalizado simple que solicita su ancho (que se usa más tarde en el front-end). El campo de ancho es un menú desplegable, por lo que el 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;

que resulta en:

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

Lo que me gustaría hacer es de alguna manera conectarme a $before_widget y añadir mi propia clase (el ancho especificado del menú desplegable). Por lo tanto, quiero obtener el siguiente marcado:

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

Y si no hay ninguna clase especificada, entonces quiero añadir class="col480".

¿Cómo puedo lograr esto?

¡Gracias por la ayuda! Dasha

0
Todas las respuestas a la pregunta 5
1
15

Ahá, entonces la variable $before_widget es una cadena que representa un elemento div: <div class="widget my" id="my-widget-1">. Así que verifiqué $before_widget buscando la subcadena "class" y agregué mi valor $widget_width a ella.

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

function widget( $args, $instance ) {
  extract( $args );
  ... //otro código

  $widget_width = !empty($instance['widget_width']) ? $instance['widget_width'] : "col300";
  /* Agrega el ancho de $widget_width a la clase de $before_widget */
  // si no existe atributo 'class' - agregar uno con el valor del ancho
  if( strpos($before_widget, 'class') === false ) {
    // incluir etiqueta de cierre en la cadena de reemplazo
    $before_widget = str_replace('>', 'class="'. $widget_width . '">', $before_widget);
  }
  // si existe atributo 'class' - agregar el valor de ancho a él
  else {
    $before_widget = str_replace('class="', 'class="'. $widget_width . ' ', $before_widget);
  }
  /* Mostrar before_widget */
  echo $before_widget;

  ... //otro código
}

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

Espero que tenga sentido y ayude a alguien.

Gracias, Dasha

2 jun 2011 18:30:00
Comentarios

buen trabajo - me ayudó con un problema de widgets - gracias :)

Q Studio Q Studio
21 oct 2012 22:52:14
5
11

Puedes usar el gancho de filtro dynamic_sidebar_params 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"){ //asegúrate de que sea el ID de tu widget aquí
        // es tu widget, así que agregas tus clases
        $classe_to_add = 'col480 whatever bla bla '; // asegúrate de dejar un espacio al final
        $classe_to_add = 'class=" '.$classe_to_add;
        $params[0]['before_widget'] = str_replace('class="',$classe_to_add,$params[0]['before_widget']);
    }
    return $params;
} 
1 jun 2011 16:03:38
Comentarios

gracias por la respuesta. Tendré muchas instancias de mi widget personalizado, cada una con su propio ancho específico. Por eso quería agregar una clase adicional dentro del código del widget mismo, en lugar de hacerlo mediante un filtro. ¿Tiene sentido?

dashaluna dashaluna
1 jun 2011 16:37:15

las opciones de instancia se guardan en la tabla de opciones, así que puedes obtenerlas desde ahí una vez que conozcas el ID del widget usando get_option('widget-name')

Bainternet Bainternet
1 jun 2011 19:14:42

¡muchas gracias por tu ayuda! Lamento no entender realmente tu solución :( Y quería que todo el código estuviera dentro de mi archivo de widget personalizado, donde puedo acceder fácilmente a la variable de ancho. Terminé modificando la cadena $before_widget. Tu respuesta me puso en el camino correcto al descubrir que $before_widget es una cadena. Gracias de nuevo :)

dashaluna dashaluna
2 jun 2011 18:32:29

Esta sería la opción preferida ya que utiliza filtros de WordPress en lugar de editar los archivos del tema

rhysclay rhysclay
15 mar 2017 06:51:53

Esto es excelente - gracias. Aunque personalmente prefiero usar $params[0]['id'] en lugar de $params[0]['widget_id'] ya que ese es el id con el que registrarás la barra lateral/widget.

Brett Brett
26 may 2020 02:25:26
0

Otra forma que encontré para agregar una clase a un widget personalizado es usar la clave 'classname' en la función constructora como en:

class My_Widget_Class extends WP_Widget {
// En PHP anterior a 5 se usa el nombre de la clase hija para el constructor…
// function My_Widget_Class()
       function __construct() {
            $widget_ops = array(
                'classname' => 'my-class-name',
                'description' => __("Widget por el bien de la Humanidad",'themedomain'),
            );
            $control_ops = array(
                'id_base' => 'my-widget-class-widget'
            );
   // más código después...

   // Llama al constructor padre, puedes sustituir el 1er argumento por $control_ops['id_base'] y quitar el 4to.
            parent::__construct(@func_get_arg(0),@func_get_arg(1),$widget_ops,$control_ops);
        }
}

Y asegúrate de usar el 'before_widget' por defecto en tu tema o si usas register_sidebar() en function.php, hazlo así:

// Esto es solo un ejemplo.
register_sidebar(array(
          'name'=> 'Barra lateral',
            'id' => 'sidebar-default',
            'class' => '',// Nunca encontré dónde se usa esto...
            'description' => 'Una barra lateral para la Humanidad',
            'before_widget' => '<aside id="%1$s" class="widget %2$s">',// ¡Este es el código importante!
            'after_widget' => '</aside>',
            'before_title' => '<h3>',
            'after_title' => '</h3>',
        ));

Entonces, en cada instancia de tu widget, tendrás la clase 'widget my-class-name' así:

<aside class="widget my-class-name" id="my-widget-class-widget-N"><!-- donde N es un número -->
  <h3>TÍTULO DEL WIDGET</h3>
  <p>CONTENIDO DEL WIDGET</p>
</aside>

También puedes llamar primero al constructor padre y luego añadir cualquier nombre de clase que desees:

class My_Widget_Class extends WP_Widget {
    // Mejor definiendo la lista de argumentos del padre…
    function __construct($id_base, $name, $widget_options = array(), $control_options = array())
    {    parent::__construct($id_base, $name, $widget_options, $control_options);
         // Cambia el nombre de la clase después
         $this->widget_options['classname'].= ' alguna-extra';
    }
}
12 feb 2014 15:52:09
0

primero añade una clase de marcador de posición personalizada en el constructor

<?php
public function __construct() {
   $widget_ops  = array(
      'classname'                   =>; 'widget_text eaa __eaa__', //__eaa__ es mi clase css de marcador de posición
      'description'                 =>; __( 'Anuncios de AdSense, texto arbitrario, HTML o 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ázala con la(s) clase(s) de tu elección basado en las opciones del widget así

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

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

12 mar 2017 20:27:27
0

Puedes probar este filtro:

/**
 * Esta función recorre todos los widgets en la barra lateral 
 * y añade un valor del formulario de administración al widget como nombre de clase  
 *  
 * @param array $params Array de widgets en la barra lateral
 * @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;

        // mi función personalizada para obtener datos del widget desde el formulario de administración (objeto)
        $widget_data = nen_get_widget_data($widget['widget_id']) ;

        // comprobar si el campo existe y tiene valor
        if( isset($widget_data->wm_name) && $widget_data->wm_name )
        {
            // convertir y poner el valor en un array
            $classes = array( sanitize_title( $widget_data->wm_name ) );

            // añadir filtro, para poder agregar más
            $classes = apply_filters( 'nen_lib_add_class_to_widget' , $classes , $widget['widget_id'] , $widget , $widget_data  );

            // obtener elemento 'before_widget', establecer buscar y reemplazar
            $string     = $params[$key]['before_widget'];
            $find       = '"widget ';
            $replace    = '"widget '.implode( ' ' , $classes ).' ';

            // nuevo valor
            $new_before = str_replace( $find , $replace , $string ) ;

            // establecer nuevo valor
            $params[$key]['before_widget'] = $new_before;
        }
    }
    return $params;
}
3 oct 2018 20:56:55