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!


Deixe um Comentário










Comentários RSS

8 comentários

Andre

Favor desconsiderar o anterior! Sua dica funcionou perfeitamente! Apenas coloquei no Widget errado! rsrsr!
Abçs!


Andre

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!


Marcelo Mesquita

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.


Andre

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


Marcelo Mesquita

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.


Denis

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!


Rômulo

Excelente tutorial Marcelo
parabens!!!