Qual o nível de segurança do seu sistema?

Constantemente me deparo com esse questionamento por algum cliente e, confesso, ainda hesito um pouco na hora de responder. A primeira coisa que me vem à cabeça é: ”O sistema possui um Sistema de Segurança Sayajin Nível 3“. Acredito que a maioria dos cliente se dariam por satisfeitos. Além disso de que adiantaria ficar cuspindo várias siglas e jargões como: XSS, Força Bruta, SQL Injection, etc.

Quanto mais demoro para responder, mais desconfiados ficam os clientes e isso gera ainda mais dúvidas.

Software Livre é outro termo que levanta muitas suspeitas. Muita gente acha que se o código está aberto fica mais fácil para pessoas mal intencionadas descobrirem falhas mas não entendem que o inverso também se aplica. E o fato de o código estar aberto para todos incrementarem amplia o número de revisores e, consequentemente, da qualidade do software.

Escala de Segurança

O problema é que não existe uma escala de segurança para sistemas web. Sei que seria complicado pois deveria levar em conta: servidor, sistema operacional e o fator humano entre outros; mas acredito que essa escala se faça necessária para facilitar o diálogo com clientes leigos e até conduzir o desenvolvimento de novos sistemas.

No que tange os sistemas web, talvez um primeiro passo seja pensar em divisões de nível baseado nas falhas que esse sistema trata, como sanitizar as consultas antes de processá-las no banco. Em seguida, avaliar boas práticas de programação empregadas, por exemplo: não usar variáveis globais.

Cada nível possuiria uma lista de critérios a serem atendidos que ficariam cada vez mais complexos à medida que fosse subindo de nível. Dessa forma teríamos um valor concreto da categoria em que o sistema se encontra.

O Custo da Segurança

Certa vez um cliente disse que queria um site 100% seguro. Pensei em dizer que ninguém se daria ao trabalho de hackear seu site mas acho que isso iria atingir em cheio o seu ego. Ao invés disso, me limitei a chutar um valor e prazo para implementação da solução de acordo com o que ele queria, que ultrapassavam sua estimativa de orçamento e cronograma. Isso foi o suficiente para fazê-lo mudar de idéia.

Um site deve ser tão seguro quanto precisa ser. Esse é outra forma de enxergar uma escala de segurança, entendendo que a implementação de cada nível requer um investimento maior, não só para o desenvolvimento mas para compra de certificados, alocação de recurso e por aí vai.

Nada é Completamente Seguro

Não existe segurança absoluta, mas dizer isso a seu cliente pode significar a perda de um contrato para uma empresa que diz ter um sistema impenetrável.

Mais uma vez uma escala de segurança mostra sua importância. Deixaria claro para usuários inexperientes o nível de segurança de um sistema e nos permitira fazer comparações com os seus concorrentes.

No mais, quer segurança? Coloque seu site em um pendrive criptografado, com senha, dentro de um cofre, debaixo da sua cama… bem longe da internet.

Plugin: MM Chat

A algum tempo atrás trabalhei num plugin para chat que acabou nem sendo colocado em funcionamento. Para não haver desperdício, resolvi disponibilizá-lo para download, caso exista algum interessado.

Instalação

  1. Faça o upload do plugin ‘mm-chat’ para o diretório ‘/wp-content/plugins/’ do WordPress;
  2. Ative o plugin;
  3. Arraste o widget ‘Chat’ para qualquer sidebar

Configuração

Um novo menu aparecerá em ‘Configurações > Chat’, onde será possível configurar o limite e caracteres de cada mensagem e intervalo das atualizações de: mensagens e usuários.

Utilização

Para iniciar uma conversa, faça o login no site, vá para a página onde o widget está, clique no nome da pessoa com quem você quer conversar. Cada usuário tem uma janela própria que pode ser movida para qualquer canto da tela (jQuery UI – Dialog).

Caso alguém te mande uma mensagem, a janela de dialogo abrirá automáticamente, além de manter um breve histórico das conversas anteriores.

Caso você não queira mais receber mensagens de um determinado usuário, basta clicar no cadeado ao lado do nome do mesmo.

Download

MM Chat

Template para subcategorias

As últimas versões do WordPress melhoraram muito a hierarquia de templates, possibilitando criar modelos usando slug de tags ou categorias (category-noticias.php), nome dos autores (author-marcelo.php), tipos de arquivos (image.php) e até criar templates para tipos de posts (single-evento.php archive-evento.php).

Uma coisa da qual sinto falta no WordPress é a possibilidade de criar um template para subcategorias. Dessa forma podemos dividir o site em áreas com cores específicas ou com sidebares diferenciados, por exemplo.

Para resolver esse problema, existe uma função do que recupera as subcategorias de uma dada categoria (get_term_children) e as retorna em um array. Com isso podemos usar a template tag is_category passando esse array como parâmetro.

Por fim basta condicionar o carregamento dos templates no arquivo category.php:

if( is_category( 1 ) or is_category( get_term_children( 1, 'category' ) ) )
  include( 'category-noticias.php' );
elseif( is_category( 2 ) or is_category( get_term_children( 2, 'category' ) ) )
  include( 'category-eventos.php' );
else
  include( 'category-default.php' ); 

Assim para a categoria 1 e suas respectivas filhas, será usado o template category-noticias.php, para a categoria 2 e suas respectivas filhas será usado o template category-eventos.php e para as demais categorias, será usado o template category-default.php.

Para manter o código limpo, é recomendável que o template category.php tenha apenas as condições e os includes dos arquivos corretos, se você pretende manter o código padrão do template da categoria nesse arquivo, lembre-se de deixá-lo dentro da condição else.

Download

category

Plugin: Widget Custom Loop

Existe uma rotina na montagem dos conteúdos dos tema para WordPress já que é sempre um loop que carrega o conteúdo dos posts e páginas. Quando trabalhamos com sites grandes com várias colunas de informação a variação nesse loop se dá quase sempre por categorias – uma coluna mostra os posts da categoria x enquanto outra coluna mostra os posts da categoria y. A maioria das alterações era na estrutura html desses loops, então porque não automatizar esse processo?

custom-loopTentando facilitar as coisas eu criei o plugin Widget Custom Loop, que se trata de um widget que permite a definição do loop e personalização de sua estrutura.

Instalação

  1. Faça o upload do plugin ‘widget-custom-loop’ para o diretório ‘wp-content/plugins/’ do WordPress;
  2. Ative o plugin.

Utilização

Na páginda de widgets deverá aparecer o widget ‘Custom Loop’. Arraste o widget para o sidebar desejado e configure de acordo com suas necessidades.

Por padrão, caso o campo ‘Loop’ seja deixado em branco o plugin monta um loop automático. Esse modelo de loop automático é definido através da opção ‘loop_model’, caso o tema queira definir um modelo de loop, basta salvar esse modelo na opção ‘loop_model’, por exemplo:

update_option( ‘loop_model’, ‘<h3>{title}</h3>{excerpt}’ );

Dessa forma, sempre que o ‘Custom Loop’ for adicionado em algum sidebar, ele seguirá esse modelo por padrão.

Download

Widget Custom Loop

WordPress é CMS

Esse post era pra ser uma resposta a um comentário que recebi no post ‘Migrando Conteúdo do Drupal para WordPress‘ que escrevi, mas acabou ficando muito grande e se tornou um post. Minha intensão intenção não é denegrir a imagem do Drupal, só quero derrubar alguns mitos que existem em relação ao WordPress quando comparado a outros CMS’s – nesse caso o Drupal.

Já trabalhei desenvolvendo temas e plugins para os dois CMS’s e minha experiência com o WordPress foi muito mais simples e satisfatória.

WordPress é para Blog

O argumento de WordPress ser para blogs já não cola mais, no Showcase do WordPress, vocês encontram vários exemplos de portais, vitrines e sites que não tem nenhum traço de blog (não que isso seja algo ruim) em seu visual. O fato é: você faz o que quer com o WordPress.

É verdade que existem milhões de blogs no ar que utilizam o WordPress, mas isso não significa que o WordPress só sirva para blogs. A explicação mais adequada para sua popularização se deve a sua simplicidade, facilidade de uso, facilidade de personalização, facilidade de ampliação e integração com outros sistemas. O WordPress diminui a dependencia que os usuários finais têm com os técnicos de informática pois ele é intuitivo, muitos usuários sequer precisam de treinamento para começar a publicar conteúdo.

Também vejo milhares de temas de blogs desenvolvidos para WordPress mas em muitos casos esses temas sequer foram desenvolvidos por programadores, foram designers que se aventuraram no mundo dos códigos e tiveram êxito, o que também é algo positivo pois prova como é tranquilo desenvolver um tema para o WordPress.

WordPress não é ‘completo’

Outra comparação errônea é pensar que determinado CMS é mais completo que outro. O termo ‘completo’ é muito relativo, de que adianta um CMS oferecer trinta recursos se você utiliza apenas quatro ou cinco. Os vinte e cinco recursos restantes acabam por complicar o uso da ferramenta e piorar a sua performance. O WordPress oferece um sistema mais enxuto com possibilidades de expansão (plugins), assim você consegue manter apenas o que é necessário para você.

Quanto ao uso de plugins, a instalação básica do Drupal já ativa por padrão vários plugins para as tarefas mais básicas que um CMS poderia oferecer, como: upload de imagens, comentários e taxonomia. Esses recursos são integrados ao WordPress o que fornece mais segurança e facilita a manutenção da plataforma.

Quem ainda tiver dúvidas da qualidade do WordPress como CMS, talvez não saiba que o WordPress foi eleito o CMS do ano em 2009 pela Info.

Conclusão

Enfim, eu penso que não há nada que outros CMS’s façam que o WordPress não possa fazer mas, com certeza, não é qualquer um que pode fazer.

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!

Modelo de Banco do BuddyPress 1.0

Estou disponibilizando agora o modelo de banco do bp 1.0, assim como o modelo do WP e o modelo do WPMU, esse não é uma representação fiel do banco e sim uma visualização simplificada para consulta. Devido a quantidade de tabelas existentes no BuddyPress, mantive apenas a tabela ‘users’ do WPMU, pois é a nela que se concentram a maioria dos relacionamentos do BP. Além disso também fiquei por fazer alguns relacionamentos que estavam confusos e ambiguos.

No arquivo estão o xml para edição no DBDesigner e uma imagem no formato png, conforme a apresentada abaixo.

bp-10

Opções de Widgets

Após criar um widget o próximo passo é adicionar algumas opções a ele, tornando-o mais flexível para o usuário final. Utilizando como exemplo o plugin de posts mais quentes, digamos que você tenha definido a quantidade de cinco posts para serem apresentados mas um usuário queira mostrar apenas três. Para essas situações utilizamos a seguinte função:

register_widget_control('Nome do Widget', 'sua_funcao_de_configuracao', 'largura', 'altura')
Formulário de configuração do Widget

Formulário de configuração do Widget

Essa função permite configurar as opções de seu widget onde ‘Nome do Widget’ é o nome do widget que deseja configurar (o mesmo que informou em ‘register_sidebar_widget’), ‘sua_funcao_de_configuracao’ é a função que deve ser chamada para configurar o plugin e ‘largura’ e ‘altura’ são opcionais e se referem ao tamanho do formulário de configuração.

A sua função de configuração deve possuir um formulário com os campos de configuração e uma rotina para salvar esses dados no banco. O seu formulário não deve conter as tags ‘form’ nem ‘submit’, pois eles são acrescentados automáticamente pelo WordPress de forma a englobar todos os widgets.

Vamos ver uma forma fácil de implementar essa configuração:

function configurar_posts_mais_quentes()
{
  // Inicializa as variáveis necessárias
  $options = array();

  // Salvando as opções
  if($_POST['salvar_posts_mais_quentes'])
  {
    $opcoes['quantidade'] = (int) $_POST['quantidade_de_posts_mais_quentes'];

    // Valor padrão, caso nada tenha sido informado
    if(empty($opcoes['quantidade'])) $opcoes['quantidade'] = 5;

    update_option('posts_mais_quentes', $opcoes);
  }

  // Carregar as opções desse widget
  $opcoes = get_option('posts_mais_quentes');

  // Formulário
  ?>
    <input type="hidden" name="salvar_posts_mais_quentes" value="1" />

    <p>
      <label for="quantidade_de_posts_mais_quentes">Quantidade:</label>
      <input type="text" name="quantidade_de_posts_mais_quentes" maxlength="2" value="<?php print $opcoes['quantidade']; ?>" class="widefat" />
    </p>
  <?php
}

Explicando… começando na linha 18 ($opcoes = get_option(‘posts_mais_quentes’)) carrega as opções desse widget do banco. Notem que usei a tabela ‘options’ do banco do WordPress para salvar as opções do plugins, como foi explicado no post plugins e banco de dados.

Agora vamos para o início do formulário na linha 22, onde adiciono um campo oculto (<input type=”hidden” name=”salvar_posts_mais_quentes” value=”1″ />) apenas para ter controle quando o formulário for enviado. Também adicionei um campo de texto na linha 26 (<input type=”text” name=”quantidade_de_posts_mais_quentes” maxlength=”2″ value=”<?php print $opcoes['quantidade']; ?>” class=”widefat” />) para que o usuário possa informar a quantidade de posts que devem aparecer em seu widget.

Voltando para a linha 7, analizo se o formulário foi enviado, checando se o campo oculto foi informado, então valido o dado recebido do formulário ($opcoes['quantidade'] = (int) $_POST['quantidade_de_posts_mais_quentes']) e, finalmente, salvo as informações no banco (update_option(‘posts_mais_quentes’, $opcoes)). Notem também que as informações desse widget foram salvas como array, assim é possível armazenar todas as configurações em um único local, poupando quantidade de acesso ao banco e organizando os dados.

Tentei montar esse formulário da forma mais simples possível, além disso coloquei alguns comentários para facilitar o entendimento.

Mas não é só isso, depois de salvar as configurações desse widget ainda falta carregá-las na hora de montar o widget:

function posts_mais_quentes($args)
{
  global $wpdb;

  // Carregar as opções desse widget
  $opcoes = get_option('posts_mais_quentes');

  // Recuperando os posts
  $hot_posts = $wpdb->get_results("SELECT ID, post_title, comment_count FROM {$wpdb->posts} ORDER BY comment_count DESC LIMIT {$opcoes['quantidade']}");

  // Usando o modelo de widgets do tema
  print $args['before_widget'];
  print $args['before_title'] . "Mais Quentes" . $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'];
}

Essa função é a mesma do post anterior com duas pequenas alterações. Uma na linha 6, onde carrego as configurações salvas e na linha 9 onde uso a quantidade de posts informadas pelo usuário para limitar a consulta (LIMIT {$opcoes['quantidade']}).

É isso… crie novas possibilidades para seus widgets, os usuários finais possuem sempre gostos diversos, simplifique a vida deles. Abaixo coloco o código completo desse estudo com uma opção a mais para a escolha do título do widget.

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

// Posts Mais Quentes
function posts_mais_quentes($args)
{
  global $wpdb;

  // Carregar as opções desse widget
  $opcoes = get_option('posts_mais_quentes');

  // Valor padrão, caso nada tenha sido informado
  if(empty($opcoes['quantidade'])) $opcoes['quantidade'] = "5";

  // Recuperando os posts
  $hot_posts = $wpdb->get_results("SELECT ID, post_title, comment_count FROM {$wpdb->posts} ORDER BY comment_count DESC LIMIT {$opcoes['quantidade']}");

  // Usando o modelo de widgets do tema
  print $args['before_widget'];
  print $args['before_title'] . $opcoes['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'];
}

// Configurações dos Posts Mais Quentes
function configurar_posts_mais_quentes()
{
  // Inicializa as variáveis necessárias
  $opcoes = array();

  // Salvando as opções
  if($_POST['salvar_posts_mais_quentes'])
  {
    $opcoes['titulo'] = $_POST['titulo_dos_posts_mais_quentes'];
    $opcoes['quantidade'] = (int) $_POST['quantidade_de_posts_mais_quentes'];

    // Valor padrão, caso nada tenha sido informado
    if(empty($opcoes['quantidade'])) $opcoes['quantidade'] = "5";

    update_option('posts_mais_quentes', $opcoes);
  }

  // Carregar as opções desse widget
  $opcoes = get_option('posts_mais_quentes');

  // Formulário
  ?>
    <input type="hidden" name="salvar_posts_mais_quentes" value="1" />

    <p>
      <label for="titulo_dos_posts_mais_quentes">Título:</label>
      <input type="text" name="titulo_dos_posts_mais_quentes" maxlength="26" value="<?php print $opcoes['titulo']; ?>" class="widefat" />
      <label for="quantidade_de_posts_mais_quentes">Quantidade:</label>
      <input type="text" name="quantidade_de_posts_mais_quentes" maxlength="2" value="<?php print $opcoes['quantidade']; ?>" class="widefat" />
    </p>
  <?php
}

// Ativar o widget
function posts_mais_quentes_widgets()
{
  // Adicionar o widget
  register_sidebar_widget('Posts Mais Quentes', 'posts_mais_quentes');

  // Adicionar o controle ao widget
  register_widget_control('Posts Mais Quentes', 'configurar_posts_mais_quentes');
}

// Carregar o widget
add_action('widgets_init', 'posts_mais_quentes_widgets');
?>

Boa sorte!

Criando Widgets

No WordPress o sistema de widgets permite que usuários comuns ativem funcionalidades no site sem precisar, necessáriamente, entender HTML, CSS, PHP, etc. Mas para isso, esses usuários precisam que desenvolvedores se dediquem um pouco mais para tornar seus produtos (plugins, temas, etc) aptos a trabalhar dessa forma.

Para adicionar um widget, basta criar uma uma função e informar para o WP que aquela função deve ser tratada como um widget. Isso é feito da seguinte forma:

register_sidebar_widget('Nome do Widget', 'sua_funcao', 'sua_classe');

É tão simples quanto parece, o ‘Nome do Widget’ é o identificador do widget, ‘sua_funcao’ é a função que deve ser chamada quando esse widget estiver ativo e ‘sua_classe’ é opcional e se refere ao nome da classe css que deve ser inserida nesse widget.

Para que o seu widget se adeque ao tema é importante lembrar sempre de usar o modelo de widget definido no próprio tema para conter o conteúdo de sua função. Esse modelo é sempre embutido em forma de argumento na sua função, você só precisa usá-lo. Um exemplo vale mais do que mil palavras, então vejamos como ficaria:

sua_funcao($args)
{
  print $args['before_widget'];
  print $args['before_title'] . "Nome do Widget" . $args['after_title'];
  print "conteúdo de seu widget";
  print $args['after_widget'];
}

Agora que você sabe que é fácil, não tem desculpa para não utiliza-lá em seus plugins. Assim, os usuário não precisarão fazer edições no template, para usufruir dos benefícios de seus plugins, além de tornar mais simples o seu controle.

Juntando o que você aprendeu até agora sobre criar um plugin mas o que você acabou de aprender sobre criação de widget e um pouco de criatividade, já é possível fazer algumas coisas interessantes. Que tal um plugin que mostre no sidebar os posts mais quentes:

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

// Posts Mais Quentes
function posts_mais_quentes($args)
{
  global $wpdb;

  // Recuperando os posts
  $hot_posts = $wpdb->get_results("SELECT ID, post_title, comment_count FROM {$wpdb->posts} ORDER BY comment_count DESC LIMIT 5");

  // Usando o modelo de widgets do tema
  print $args['before_widget'];
  print $args['before_title'] . "Mais Quentes" . $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'];
}

// Ativa o sidebar
function posts_mais_quentes_widgets() {
  register_sidebar_widget('Posts Mais Quentes', 'posts_mais_quentes');
}

// Carregar o widget
add_action('widgets_init', 'posts_mais_quentes_widgets');

?>

Agora é só ativar o plugin e adicionar o widget ao sidebar para ve-lo funcionando. Colher de chá!

Agradecimentos

Obrigado ao Rômulo por corrigir o código do plugin acima.