Adicione classe ao before_widget a partir de um widget personalizado

10

Eu tenho um widget personalizado simples que solicita sua largura (que é usada posteriormente no front-end). O campo de largura é uma lista suspensa de seleção, portanto, um usuário tem opções predefinidas.

Eu terei muitas instâncias do meu widget, cada uma terá sua própria configuração de largura.

Agora, no meu código do widget, tenho o seguinte código:

echo $before_widget;

o que resulta em:

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

O que eu gostaria de fazer é, de alguma forma, conectar $before_widgete adicionar minha própria classe (a largura especificada no menu suspenso de seleção). Então, eu quero a seguinte marcação:

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

E se não houver nenhuma classe especificada, eu quero adicionar class="col480".

Como faço para conseguir isso?

Obrigado pela ajuda! Dasha

dashaluna
fonte

Respostas:

14

Aha, então a $before_widgetvariável é uma string representando div elemento: <div class="widget my" id="my-widget-1">. Então, verifiquei a $before_widgetsub-string "class" e adicionei meu $widget_widthvalor a ela.

O código é do meu arquivo 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
}

Eu queria adicionar minha $widget_widthvariável ao elemento div do widget dentro do meu próprio código de widget (enquanto eu tinha um acesso fácil à $widget_widthvariável).

Espero que faça sentido e ajude alguém.

Obrigado, Dasha

dashaluna
fonte
nice work - me ajudou com uma edição widget - graças :)
Q Estúdio
10

você pode usar o dynamic_sidebar_paramsgancho de filtro para encontrar seu widget e adicionar suas classes a ele:

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
fonte
Obrigado pela resposta. Terei muitas instâncias do meu widget personalizado, cada uma delas com sua própria largura específica. É por isso que eu queria adicionar classe extra dentro do próprio código do widget, em vez de usar o filtro. Espero que isso faça sentido?
Dashaluna
também opções de instância são salvas na tabela a opção para que você pode obter-lo de lá quando você sabe o ID de widget usandoget_option('widget-name')
Bainternet
11
Muito obrigado por sua ajuda! Me desculpe, eu realmente não entendo sua solução :( E eu queria que todo o código estivesse dentro do meu arquivo de widget personalizado, enquanto posso acessar facilmente a variável width. Acabei cortando a $before_widgetstring. Sua resposta me levou ao Descobrindo a direita faixa que $before_widgeté uma string obrigado novamente :).
dashaluna
Esta seria uma opção preferida, uma vez que utiliza filtros de wordpress em vez de editar os arquivos de tema
rhysclay
6

Outra maneira que encontrei para adicionar uma classe a um widget personalizado é usar a tecla ' classname ' da sua função de construção, como em:

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

E certifique-se de usar o padrão ' before_widget ' no seu tema ou se você usar o register_sidebar()function.php, faça o seguinte:

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

Em todas as instâncias do seu widget, você terá a classe 'widget my-class-name' assim:

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

Você também pode chamar o construtor pai primeiro e depois anexar o nome da classe que desejar:

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

primeiro adicione uma classe de espaço reservado personalizada no construtor

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

Em seguida, substitua-o pelas classes de sua escolha com base nas opções de widget como esta

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

Você pode encontrar os detalhes com exemplo em http://satishgandham.com/2017/03/adding-dynamic-classes-custom-wordpress-widgets/

Satish Gandham
fonte
0

Você pode tentar 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
fonte