Arquivos do mês julho, 2009

Criando Meta Boxes

Na versão 2.7 o WordPress estreiou as meta boxes, que são aquelas caixinhas arrastáveis que estão presente no dashboard, na área de edição de posts e páginas além de outros locais na área administrativa do WordPress.

Muitas vezes, na criação de plugins que interajem com os posts ou páginas, é necessário adicionar um novo campo à area de edição. Afim de manter a formatação do WordPress, a criação de uma meta box é o caminho mais limpo e fácil. Também é possível adicionar as metaboxes as páginas dos seus plugins, mas é uma tarefa um pouco mais complicada, então vamos deixar para outro artigo.

add_meta_box($id, $title, $callback, $page, $context=’advanced’, $priority=’default’, $callback_args=null);

Essa função é a responssável por adicionar a meta box a uma determinada página. O $id é o identificador único para o HTML, é com esse identificador que o WordPress manipulará sua metabox. Já o $title é o título da metabox, $callback é a sua função que ficará responssável pelo carregamento do conteúdo dentro da metabox e $page é a página onde a sua metabox será carregada (’page’, ‘post’, ‘link’, etc). Os outros parâmetros são opcionais: $context define o local da página onde sua metabox será carregada por padrão (’normal’, ‘advanced’, ’side’) enquanto $priority diz o posicionamento padrão da metabox dentro do $context (’high’ ou ‘low’), e por fim $callback_args que permite a passagem de argumentos à metabox.

Por exemplo, para criar uma metabox que mostre uma frase de incentivo (não consegui pensar em algo mais simples e útil) na parte de cima do sidebar da tela de edição de posts, ficaria assim:

add_meta_box('incentivador', 'Incentivador', 'incentive_me', 'post', 'side', 'high');

Não se esqueça de criar a função ‘incentive_me’ em seu plugin.

Agora só falta adicionar um gancho para a chamada da metabox:

add_action('do_meta_boxes', 'incentivador_metabox');

Onde ‘incentivador_metabox’ é a função que conterá o seu add_meta_box.

O código final ficaria assim:

<?php
/*
Plugin Name: MetaBox: Incentivador
Description: Mostra uma frase
Version: 0.1
Author: Marcelo Mesquita
Author URI: http://www.marcelomesquita.com/
*/

add_action('do_meta_boxes', 'incentivador_metabox');

function incentivador_metabox()
{
    add_meta_box('incentivador', 'Incentivador', 'incentive_me', 'post', 'side', 'high');
}

function incentive_me()
{
    $frases = array(
        'Você consegue!',
        'Faça seu melhor!',
        'Tudo é possível!'
    );

    print $frases[rand(0, 3)];
}
?>

Para saber mais acesse a Referência da Função add_meta_box


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!