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

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!

Minhas impressões sobre o BuddyPress

Estive trabalhando no projeto Cultura Digital e não tem sido uma tarefa fácil. Grande parte da dificuldade que estamos tendo é atribuída ao BuddyPress. Ele não parece ter sido desenvolvido para o WordPress, suas tabelas e códigos (tanto interface quanto programação) não seguem um padrão semelhante ao do WordPress (“Code is Poetry”).

Banco de Dados

Me espantei na primeira vez que resolvi analisar a estrutura de dados do BuddyPress; vinte e uma tabelas novas criadas! A instalação original do WP utiliza apenas dez tabelas, a do WPMU necessita de dezesete, por que diabos o BP precisaria de vinte e uma só pra ele, resultando em trinta e oito no total (BP + WPMU).

Após gerar o modelo de dados do BP pude ter uma visão mais ampla da bobagem que haviam feito:

Nomeclatura das tabelas

Nomes como ‘wp_bp_acivity_user_activity’, ‘wp_bp_acivity_user_activity_cached’, ‘bp_messages_messages’ ou ‘bp_messages_threads’ já eram em si um quebra-cabeça a ser decifrado.

Normalização das tabelas

Ao começar a trabalhar com as tabelas não pude deixar de notar a quantidade de campos ‘user_id’ espalhados por tabelas, de alguma forma, conectadas. O caso mais claro foi o das tabelas ‘bp_activity_user_activity’ e ‘bp_activity_user_activity_cached’ que já são ligados através do campo ‘item_id’ mas ambas possuem os campo ‘user_id’.

Outro caso que me fez perder alguns cabelos foi o da tabela ‘bp_messages_threads’ que apenas mantém a ligação das mensagens que são respostas a outras mensagens. Isso poderia ser feito simplesmente criando um auto-relacionamento na tabela ‘bp_messages_messages’.

Dados redundantes

Acredito que o pior de tudo foi descobrir que algumas tabelas criadas pelo BuddyPress nem precisavam existir, pois serviam para armazenar informações que podiam ser armazenadas nas tabelas do WordPress.

Destaco o conjunto de tabelas ‘bp_xprofile_fields’ e ‘bp_xprofile_data’ que server para adicionar novos campos ao perfil do usuário. Para passar uma idéia, uma única tabela do WordPress substitui essas duas do BuddyPress, o plugin Register Plus é um exemplo de como isso pode ser feito. O único motivo, que vejo para que o BuddyPress tenha feito essa separação, seria para obter ganhos em performance, mas o fato de existir um campo para cada dado me fez pensar que a performance estaria equilibrada já que na tabela ‘usermeta’ esses dados poderiam estar em forma de array e, assim, ocupariam um campo apenas.

Também não gostei da forma como o BuddyPress trata as atividades. Apesar das atividades do site serem o conjunto das atividades de cada usuário, os dados ficam duplicados em diferentes tabelas. Por exemplo: Ao alterar meu perfil uma nova atividade é cadastrada na tabela ‘bp_activity_user_activity’ e depois a mesma informação é cadastrada na tabela ‘bp_activity_sitewide’.

Codificação

A codificação também ficou a desejar.

Funções engessadas

Diferente do WordPress onde as ‘template tags’ (funções que auxiliam a montagem do tema) praticamente não interferem na forma como o html é montado, no BuddyPress algumas ‘template tags’ carregam muito lixo e apresentam um visual pré-definido. Isso dificulta a personalização do tema pois força a alteração dos arquivos do BuddyPress para atingir um resultado esperado.

Por exemplo: a função que carrega os dados do perfil (xprofile_get_profile) monta uma tabela zebrada (uma linha clara outra escura), apenas com os dados informados e adiciona link a cada item. Mas a zebra que o BP monta é baseada nos dados que estão no banco, então se eu tiver deixado algum campo vazio a tabela acaba pulando uma cor deixando duas linhas claras e uma escura ou algo parecido. Se eu quiser corrigir essa zebra ou retirar os links dos dados eu precisarei criar uma função do zero para não ter que ‘hackear’ o BP.

Mistura de tema com plugin

Os temas são muito dependentes de funções definidas nos plugins. Essa questão é mais ou menos a mesma citada no item acima, imagine tentar criar uma nova função apenas para recuperar os membros ou pense na dor de cabeça que é ficar alternando entre plugins e tema para entender como tal trecho de código é montado.

Conclusão

O BuddyPress tem muito a evoluir antes de se tornar um sistema confiável, acredito que o principal é voltar os esforços para deixá-lo mais compatível com o seu hospedeiro, o WordPress. Assim poderá haver uma maior compatibilidade entre os plugins e temas, além de diminuir a curva de aprendizado para os desenvolvedores que já trabalham com o WordPress, o que, na minha opinião, poderá resultar em um impulso na comunidade BuddyPress.

Modelo de Banco do WordPress MU 2.7

Estou disponibilizando agora o modelo de banco de dados do WPMU 2.7, assim como o modelo do WordPress, esse não é uma representação fiel do banco e sim uma visualização simplificada para consulta. As tabelas dentro da área azul são as que se repetem para cada blog, onde o x é o id numério de cada blog.

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

wpmu-271

Tema: Painter

Da necessidade de personalização rápida de um tema e suas funcionalidades, surgiu a idéia do “Painter”. Um tema simples, com cores sólidas e poucas imagens, porém altamente customizável.

custom-colorsPersonalização

Destaco nele a possibilidade de personalização através da área administrativa, permitindo a escolha das cores de cada item do site além da imagem do cabeçalho. Conta com o farbtastic, um plugin em jquery para seleção de cores, presente na versão 2.7 do WordPress, dessa forma qualquer um pode alterar o tema, mesmo sem conhecimentos em html e css.

Devido a quantidade de campos editáveis, foi inserido um select com alguns esquemas de cores pré-definidos, mas isso não impede que as cores sejam alteradas uma por uma. E para aqueles que não dispensam um editor de imagens, os campos também podem ser preenchidos manualmente.

O tema já está pronto para utilização de widgets e para os plugins lead_manager, breadcrumb-xt e authimage.

Internacionalização

O idioma padrão do tema é inglês. Junto com o tema vão os arquivos de tradução (.po e .mo) para o português Brasileiro. Assim é possível traduzir o tema para outros idiomas também.

Agradecimentos

Muito obrigado ao Fabiano Rangel que deu uma geral no tema acabando com os tons de cinza e adicionando algumas imagens, além de criar os esquemas de cores pré-definidos que poupará o tempo de muitos. Agradeço também a paciência que o Fabiano teve para entender, testar e definir as cores para a criação do plugin, se não fosse por ele vocês teriam que se virar com nomes como: “Cor de fundo clara”, “Cor de frente escura”, “Cor de frente média”, etc…

Download

painter

Exemplos

painterpainter-redpainter-pastel

Modelo de Banco do WordPress 2.7

Modelo de Banco do WordPress-2.7

Modelo de Banco do WordPress-2.7

Estou disponibilizando aqui o modelo de banco do WordPress 2.7 que montei utilizando o DBDesigner4, uma excelente ferramenta, opensource, para modelagem de banco de dados. Para os programadores, é sempre bom ter um modelo do banco a mão para ajudar a montar as consultas e estudar as possibilidades de integração com os sistemas.

No anexo estão o arquivo xml editável do DBDesigner4 e a imagem do banco no formato png. Esse modelo não é uma representação fiél do banco, eu preferi montar uma forma simplificada que facilitasse a leitura e privilegiasse os relacionamentos principais evitando aquele monte de linhas cruzando as tabelas de um lado ao outro.

Tema: Stallefish

Um mês após o lançamento do site estou colocando no ar o tema que desenvolvi. Você deve estar pensando: “Putz! Um mês pra fazer isso?!”. É… eu demorei mesmo, e sim! O tema é só isso.

Tentei basear o layout no conteúdo, sem distrações artísticas (até porque não tenho muitas habilidades com design) mas tentando compensar utilizando recursos lógicos.

Agrupei todas as informações relativas ao conteúdo num tipo de sidebar do lado esquerdo dos posts, páginas e comentários com a intenção de facilitar sua identificação e relacionamentos.

Ajax

O que destaco nesse tema é a navegação em ajax, de forma a diminuir um pouco o processamento do servidor e a banda da rede. Em contrapartida dificulta um pouco o histórico já que o navegador não registra o carregamento dos conteúdos assíncronos. Existem algumas soluções em javascript que simulam o histórico, mas ainda estou estudando a melhor forma de usá-las.

Personalização

O sidebar também é um ponto que ressalto nesse tema, os visitantes podem minimizar as caixas dos conteúdos que menos o interessam e, futuramente, também poderão ordenar as caixas privilegiando as mais utilizadas. O tema memoriza as configurações do visitante, assim quando ele voltar ao site, o sidebar estará devidamente ordenado e visível.

Internacionalização

Ainda estou traduzindo o tema… eu sei, eu sei, é muita prepotencia, mas vai que entra um gringo aí, né.