Aggiungere una classe a before_widget all'interno di un widget personalizzato
Ho un semplice widget personalizzato che richiede la sua larghezza (che viene utilizzata successivamente nel front-end). Il campo della larghezza è un menu a tendina, quindi l'utente ha opzioni predefinite.
Avrò molte istanze del mio widget, ognuna con la propria configurazione della larghezza.
Ora, nel codice del mio widget ho il seguente codice:
echo $before_widget;
che produce:
<div class="widget my" id="my-widget-1"></div>
Quello che vorrei fare è in qualche modo collegarmi a $before_widget
e aggiungere la mia classe personalizzata (la larghezza specificata dal menu a tendina). Quindi, voglio ottenere il seguente markup:
<div class="widget my col480" id="my-widget-3"></div>
E se non è specificata alcuna classe, voglio aggiungere class="col480"
.
Come posso ottenere questo risultato?
Grazie per l'aiuto! Dasha

Aha, quindi la variabile $before_widget
è una stringa che rappresenta un elemento div: <div class="widget my" id="my-widget-1">
. Ho controllato la $before_widget
per la sottostringa "class" e ho aggiunto il mio valore $widget_width
ad essa.
Il codice proviene dal mio file widget personalizzato:
function widget( $args, $instance ) {
extract( $args );
... //altro codice
$widget_width = !empty($instance['widget_width']) ? $instance['widget_width'] : "col300";
/* Aggiungi la larghezza da $widget_width alla classe da $before widget */
// nessun attributo 'class' - aggiungine uno con il valore della larghezza
if( strpos($before_widget, 'class') === false ) {
// includi il tag di chiusura nella stringa di sostituzione
$before_widget = str_replace('>', 'class="'. $widget_width . '">', $before_widget);
}
// c'è l'attributo 'class' - aggiungi il valore della larghezza ad esso
else {
$before_widget = str_replace('class="', 'class="'. $widget_width . ' ', $before_widget);
}
/* Prima del widget */
echo $before_widget;
... //altro codice
}
Volevo aggiungere la mia variabile $widget_width
all'elemento div del widget all'interno del mio codice widget (mentre avevo un accesso semplice alla variabile $widget_width
).
Spero che abbia senso e possa aiutare qualcuno.
Grazie, Dasha

puoi utilizzare l'hook filter dynamic_sidebar_params
per individuare il tuo widget e aggiungere le tue classi:
add_filter('dynamic_sidebar_params', 'add_classes_to__widget');
function add_classes_to__widget($params){
if ($params[0]['widget_id'] == "my-widget-1"){ //assicurati che sia l'ID del tuo widget qui
// è il tuo widget quindi aggiungi le tue classi
$classe_to_add = 'col480 whatever bla bla '; // assicurati di lasciare uno spazio alla fine
$classe_to_add = 'class=" '.$classe_to_add;
$params[0]['before_widget'] = str_replace('class="',$classe_to_add,$params[0]['before_widget']);
}
return $params;
}

grazie per la risposta. Avrò molte istanze del mio widget personalizzato, ciascuna con la propria larghezza specifica. Ecco perché volevo aggiungere una classe extra direttamente nel codice del widget, piuttosto che tramite un filtro. Spero abbia senso?

beh, le opzioni dell'istanza sono salvate nella tabella delle opzioni, quindi puoi ottenerle da lì una volta che conosci l'ID del widget usando get_option('widget-name')

grazie mille per il tuo aiuto! Mi dispiace ma non ho capito bene la tua soluzione :( E volevo che tutto il codice rimanesse all'interno del mio file del widget personalizzato, mentre posso accedere facilmente alla variabile della larghezza. Alla fine ho modificato la stringa $before_widget
. La tua risposta mi ha messo sulla buona strada per scoprire che $before_widget
è una stringa. Grazie ancora :)

Questa sarebbe un'opzione preferibile in quanto utilizza i filtri di WordPress anziché modificare i file del tema

Un altro modo che ho trovato per aggiungere una classe a un widget personalizzato è utilizzare la chiave 'classname' della tua funzione di costruzione come in:
class My_Widget_Class extends WP_Widget {
// Nelle versioni precedenti a PHP5 usa il nome della classe figlia per il costruttore…
// function My_Widget_Class()
function __construct() {
$widget_ops = array(
'classname' => 'my-class-name',
'description' => __("Widget per il bene dell'Umanità",'themedomain'),
);
$control_ops = array(
'id_base' => 'my-widget-class-widget'
);
// altro codice dopo...
// Chiama il costruttore genitore, puoi sostituire il primo argomento con $control_ops['id_base'] e rimuovere il quarto.
parent::__construct(@func_get_arg(0),@func_get_arg(1),$widget_ops,$control_ops);
}
}
E assicurati di utilizzare il 'before_widget' predefinito nel tuo tema o se usi register_sidebar()
in function.php, fallo così:
// Questo è solo un esempio.
register_sidebar(array(
'name'=> 'Sidebar',
'id' => 'sidebar-default',
'class' => '',// Non ho mai trovato dove viene usato...
'description' => 'Una sidebar per l\'Umanità',
'before_widget' => '<aside id="%1$s" class="widget %2$s">',// Questo è il codice importante!!
'after_widget' => '</aside>',
'before_title' => '<h3>',
'after_title' => '</h3>',
));
Quindi su ogni istanza del tuo widget, avrai la classe 'widget my-class-name' così:
<aside class="widget my-class-name" id="my-widget-class-widget-N"><!-- dove N è un numero -->
<h3>TITOLO DEL WIDGET</h3>
<p>CONTENUTO DEL WIDGET</p>
</aside>
Puoi anche chiamare prima il costruttore genitore e poi aggiungere qualsiasi nome di classe desideri:
class My_Widget_Class extends WP_Widget {
// Meglio definire la lista degli argomenti del genitore…
function __construct($id_base, $name, $widget_options = array(), $control_options = array())
{ parent::__construct($id_base, $name, $widget_options, $control_options);
// Cambia il nome della classe dopo
$this->widget_options['classname'].= ' some-extra';
}
}

prima aggiungi una classe segnaposto personalizzata nel costruttore
<?php
public function __construct() {
$widget_ops = array(
'classname' => 'widget_text eaa __eaa__', //__eaa__ è la mia classe css segnaposto
'description' => __( 'AdSense ads, testo arbitrario, HTML o JS.','eaa' ),
'customize_selective_refresh' => true,
);
$control_ops = array( 'width' => 400, 'height' => 350 );
parent::__construct( 'eaa', __( 'Easy AdSense Ads & Scripts', 'eaa' ), $widget_ops, $control_ops );
}
?>
Poi sostituiscila con la/e classe/i di tua scelta in base alle opzioni del widget in questo modo
<?php
if ( $instance['no_padding'] ) {
$args['before_widget'] = str_replace( '__eaa__', 'eaa-clean', $args['before_widget'] );
}
?>
Puoi trovare i dettagli con l'esempio su http://satishgandham.com/2017/03/adding-dynamic-classes-custom-wordpress-widgets/

Puoi provare questo filtro:
/**
* Questa funzione scorre tutti i widget in una sidebar
* e aggiunge un valore del form admin al widget come nome di classe
*
* @param array $params Array dei widget nella 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;
// mia funzione personalizzata per ottenere i dati del widget dal form admin (oggetto)
$widget_data = nen_get_widget_data($widget['widget_id']) ;
// verifica se il campo esiste e ha un valore
if( isset($widget_data->wm_name) && $widget_data->wm_name )
{
// converte e inserisce il valore in un array
$classes = array( sanitize_title( $widget_data->wm_name ) );
// aggiunge filtro, per poter aggiungere altro
$classes = apply_filters( 'nen_lib_add_class_to_widget' , $classes , $widget['widget_id'] , $widget , $widget_data );
// ottiene l'elemento 'before_widget', imposta trova e sostituisci
$string = $params[$key]['before_widget'];
$find = '"widget ';
$replace = '"widget '.implode( ' ' , $classes ).' ';
// nuovo valore
$new_before = str_replace( $find , $replace , $string ) ;
// imposta nuovo valore
$params[$key]['before_widget'] = $new_before;
}
}
return $params;
}
