Criando Widgets para o WordPress 2.8

Como todos já devem saber, foi lançada a versão 2.8 do WordPress e entre as principais melhorias está novo sistema de widgets. A interface do usuário está muito mais simples de utilizar, todos os widgets e sidebares ficam listados, basta arrastar um widget para o sidebar desejado e pronto! O WordPress salva automaticamente o sidebar, além disso os widgets já são multiplicáveis então não é mais necessário ficar regulando a divisão deles ou utilizar plugins que façam a duplicação.

Mas a melhoria não foi só na interface com o usuário, a criação dos widgets também ficou muito mais simples, o WordPress disponibiliza uma classe com todo o código bruto para o funcionamento dos widgets sobrando para o desenvolvedor apenas algumas funções específicas.

A API dos Widgets do WordPress fornece um modelo para a criação dos widgets:

class My_Widget extends WP_Widget {
	function My_Widget() {
		// widget actual processes
	}

	function widget($args, $instance) {
		// outputs the content of the widget
	}

	function update($new_instance, $old_instance) {
		// processes widget options to be saved
	}

	function form($instance) {
		// outputs the options form on admin
	}
}
register_widget('My_Widget');

Explicando rapidamente, nesse modelo você cria uma classe ‘My_Widget’ filha de uma classe ‘WP_Widget’ que é a classe fornecida pelo WordPress contendo o código bruto, restando ao desenvolvedor a definição dos métodos:

My_Widget()

O construtor deve sempre ter o mesmo nome da classe ou se chamar __construct (depende da versão do PHP). No construtor são definidos o id, o nome, a descrição, e outras informações relativas ao widget.

widget($args, $instance)

Esse método define a forma como o widget é apresentado no tema. O parêmetro $args é um array contendo a formatação da estrutura do widget como: tags de abertura e fechamento do widget e do título do widget além do nome e id do widget.

O conteúdo dessa função não muda muito em relação ao modelo anterior dos widgets que era chamado pelo ‘register_sidebar_widget’, a única diferença é que o conteúdo da função, antes carregado do banco, agora vem todo no array $instance.

form($instance)

O médoto form representa a inteface administrativa do widget, onde é feita a configuração do mesmo, sua definição não é obrigatória.

Esse método é o espelho da função chamada pelo ‘register_widget_control’, mas aqui fica somente a estrutura do formulário. Assim como o método ‘widget’, aqui os dados não precisam mais serem carregados do banco, o array $instance traz todos os dados. O que notei de diferente na montagem do formulário foram apenas as nomeclaturas dos campos, agora tendo que ser feita da seguinte forma:

<input type="text" id="<?php print $this->get_field_id('nome-do-campo'); ?>" name="<?php print $this->get_field_name('nome-do-campo); ?>" value="<?php print $instance['nome-do-campo']; ?>" />

update($new_instance, $old_instance)

Também não é necessária a definição do método update. É esse método que realiza o processamento dos dados antes de salva-los no banco. O parâmetro $new_instance contém os dados novos (os que acabaram de ser informados) enquanto o $old_instance contém os dados antigos, para o caso de ser necessário fazer uma comparação.

Após o processamento dos dados, um array com os dados finais deverá ser retornado.

Não pretendo explicar novamente a lógica de criação de um widget, portanto vou simplesmente refazer o widget ‘Posts Mais Quentes’ nesse novo modelo e caso tenham dúvidas, consultem o post Opções de Widgets.

<?php
/*
Plugin Name: Widget: Posts mais quentes
Description: Lista posts mais comentados
Version: 0.3
Author: Marcelo Mesquita
Author URI: http://www.marcelomesquita.com/
*/

// Posts Mais Quentes
class Widget_Posts_Mais_Quentes extends WP_Widget
{
	function Widget_Posts_Mais_Quentes()
	{
		$this->WP_Widget('posts_mais_quentes', 'Posts Mais Quentes');
	}

	function widget($args, $instance)
	{
		global $wpdb;

		// Valor padrão, caso nada tenha sido informado
		if(empty($instance['quantidade'])) $instance['quantidade'] = "5";
		// Recuperando os posts
		$hot_posts = $wpdb->get_results("SELECT ID, post_title, comment_count FROM {$wpdb->posts} WHERE post_status = 'publish' ORDER BY comment_count DESC LIMIT {$instance['quantidade']}");

		if(empty($hot_posts))
			return false;

		// Usando o modelo de widgets do tema
		print $args['before_widget'];
		print $args['before_title'] . $instance['titulo'] . $args['after_title'];
		print "<ul>";
		// Listando os posts mais quentes
		foreach($hot_posts as $hot_post)
			print "<li><a href='" . get_permalink($hot_post->ID) . "'>{$hot_post->post_title} ({$hot_post->comment_count})</a></li>";
		print "</ul>";
		print $args['after_widget'];
	}

	function update($new_instance, $old_instance)
	{
		return $new_instance;
	}

	function form($instance)
	{
		?>
			<p>
				<label for="<?php print $this->get_field_id('titulo'); ?>">Título:</label>
				<input type="text" id="<?php print $this->get_field_id('titulo'); ?>" name="<?php print $this->get_field_name('titulo'); ?>" maxlength="26" value="<?php print $instance['titulo']; ?>" class="widefat" />
				<label for="<?php print $this->get_field_id('quantidade'); ?>">Quantidade:</label>
				<input type="text" id="<?php print $this->get_field_id('quantidade'); ?>" name="<?php print $this->get_field_name('quantidade'); ?>" maxlength="2" value="<?php print $instance['quantidade']; ?>" class="widefat" />
			</p>
		<?php
	}
}
// register widget
add_action('widgets_init', create_function('', 'return register_widget("Widget_Posts_Mais_Quentes");'));

Boa sorte!

11 thoughts on “Criando Widgets para o WordPress 2.8

  1. Marcelo, veja se pode me ajudar, acho que tem a ver com este post.

    estou tentando adicionar um componente jquery ui de abas aos meus widgets do wpmu. Então preciso que eles tenham as seguintes IDs:

    <a href=”#tabs-1″ rel=”nofollow”>Nunc tincidunt</a>
    <a href=”#tabs-2″ rel=”nofollow”>Proin dolor</a>
    <a href=”#tabs-3″ rel=”nofollow”>Aenean lacinia</a>

    Tab 1 content

    Tab 2 content

    Tab 3 content

    .

    Estou usando o tema thematic e não encontro maneira de criar essa estrutura. Pelo que entendo, cada widget estaria dentro de uma div tabs-X. Mas como faço isso?

    Obrigado!

    • Denis,
      o JavaScript que criei no culturadigital.br pega o título de cada widget e monta os links das abas.

      jQuery(function(){

      // Criar Abas

      jQuery(‘.box1-1 .widgettitle’).each(function(){

      var item = jQuery(this).html();

      var link = jQuery(this).parent().attr(‘id’);

      // Remover lixo do item

      item = item.replace(/<[^>]*>/g, “”);

      jQuery(‘.box1-1 ul:first’).append(‘<li><a href=”#’ + link + ‘”><span>’ + item + ‘</span></a></li>’);

      });
      });

      Se você estiver tendo dificuldades para inserir os ids no tema, altere os elementos no JavaScript que é mais simples, por exemplo, tente alterar a linha ‘jQuery(‘.box1-1 .widgettitle’).each(function(){‘ por ‘jQuery(‘.xoxo .widgettitle’).each(function(){‘ (a classe .xoxo eu peguei do tema que você está utilizando). Não se esqueça de alterar as classes .box1-1 por .xoxo nas outras chamadas no javascript.

      Abraço.

  2. Olá Marcelo,
    Ótimo seu tutorial. Tenho uma dúvida e gostaria de deixá-la aqui , caso você saiba a resposta eu agradeço: é possível configurar um widget quando o criamos para ele aparecer apenas na página inicial??
    Abçs
    Andre

    • André,
      você quer que quando alguém arraste seu widget para um sidebar, ele só apareça se estiver na home? Caso seja isso, basta adicionar dentro da função widget, logo após a ‘{‘ o seguinte código:
      if( !is_home() ) return false;

      Espero ter ajudado.

  3. Exatamente! Mas tentei e não funcionou. Será que fiz errado? Olhe o código:

    function WidgetVD($args) {
    if( !is_home() ) return false;
    echo $args['before_widget'];
    echo $args['before_title'] . “Meu Widget” . $args['after_title'];
    Class::vDiario(Class::$origemVD);
    echo $args['after_widget'];
    }

    É isso!?

    Grato pela ajuda!

  4. Pingback: Como alterar o aspecto da lista de categorias no Wordpress | Wordpress

  5. Olá Marcelo,
    Mas uma vez estou aqui com dúvidas que não tem relação com o post, mas se puder me ajudar te agradeço! Você saberia me dizer se existe alguma função ou filtro no wordpress que permita não exibir a sidebar em uma determinada página? Não poderia ser no tema, tem que ser como um filtro para usar em um plugin meu!

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>