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

the_thumb

Ordenando o posicionamento das imagens

Ordenando o posicionamento das imagens

Desde quando comecei a trabalhar com WP a funcionalidade mais requisitada foi sempre inserir uma imagem nas chamadas dos posts. Para isso criei uma função que puxa, do banco de dados, a primeira imagem de um post. Apartir da versão 2.6 do WP é possível ordenar as imagens do post através de um drag’n drop nas opções de galeria, como mostra a imagem ao lado, sendo assim, basta arrastar para a primeira posição a imagem que quer usar. Essa imagem não precisa necessáriamente estar sendo utilizada no conteúdo do post, apenas ter sido anexada a ele.

Para utilizar essa função, abra o arquivo functions.php do seu tema, e depois cole o código abaixo.

function the_thumb($size = "medium", $add = "")
{
  global $wpdb, $post;

  $thumb = $wpdb->get_row("SELECT ID, post_title FROM {$wpdb->posts} WHERE post_parent = {$post->ID} AND post_mime_type LIKE 'image%' ORDER BY menu_order");

  if(!empty($thumb))
  {
    $image = image_downsize($thumb->ID, $size);

    print "<img src='{$image[0]}' alt='{$thumb->post_title}' {$add} />";
  }
}

Essa função funciona como uma template tag do WordPress, basta chamá-la no local do seu tema onde você quer que a imagem apareça, opcionalmente você pode escolher o tamanho da imagem ($size) e adicionar alguns parâmetros à tag da imagem ($add), como classes, largura, altura, etc.

Acho que é mais fácil mostrando uns exemplos.

1. Mostrar a imagem no tamanho médio (padrão 300 x 300) sem nenhum dado adicional:

<?php the_thumb('medium'); ?>

Resultaria em:

<img src='http://seusite.com/caminho/da/imagem-300x300.jpg' alt='titulo-da-imagem' />

2. Carregar uma miniatura da imagem (padrão 150 x 150) com a classe ‘alignleft’:

<?php the_thumb('thumbnail', 'class="alignleft"'); ?>

Retornaria:

<img src='http://seusite.com/caminho/da/imagem-150x150.jpg' alt='titulo-da-imagem' class='alignleft' />

3. Forçar uma imagem média a um tamanho diferente:

<?php the_thumb('medium', 'width="300" height="275"'); ?>

Apresentaria:

<img src='http://seusite.com/caminho/da/imagem-300x300.jpg' alt='titulo-da-imagem' width='300' height='275' />

Notem que forçando um tamanho para uma imagem apenas altera seu tamanho via html, o que pode distorcer a imagem se não for usado proporcionalmente.

Tela de configuração de mídia

Tela de configuração de mídia

Também é importante lembrar que é possível definir o tamanho das imagens nas configurações do WordPress, para isso vá em ‘Configurações > Mídia’ e altere as medidas a seu gosto.

Esses dias vi um artigo no wprecipes que mostrava como pegar a primeira imagem de um post e mostra-la, o problema da função deles é que ela exige que a imagem esteja no conteúdo do post o que muitas vezes não é interessante, primeiro pois força o autor a usar uma imagem no conteúdo e segundo por que a imagem que aparece na chamada tem sempre que ser a primeira que aparece no post.

Evitando posts repetidos

Quando começamos a trabalhar com Múltiplos Loops, um detalhe importante, muito bem lembrado pelo David, é quanto aos posts repetidos. É possível que os diferentes Loops tenham algum post em comum e esse post acabe sendo duplicado em algum momento.

Para evitar que isso aconteça, existe uma solução simples, a instrução ‘continue‘ do php. Essa instrução pula a iteração atual dentro de uma estrutura de loop, no nosso caso o ‘while‘. Mas antes precisamos saber quais iterações devem ser puladas, portanto criamos um array para armazenar o ‘id’ dos posts que já foram apresentados e em seguida filtramos esses posts. Com isso teremos:

<?php $usados = array(); ?>
<?php $noticias = new WP_Query("category_name=noticias&showposts=3"); ?>
<?php while($noticias->have_posts()) : $noticias->the_post(); ?>
 <?php array_push($useds, $post->ID); ?>
trecho da interface a ser repetido...
<?php endwhile; ?>
 
<?php $artigos = new WP_Query("category_name=artigosamp;showposts=3"); ?>
<?php while($artigos->have_posts()) : $artigos->the_post(); ?>
<?php if(in_array($post->ID, $usados)) continue; ?>
 <?php array_push($useds, $post->ID); ?>
trecho da interface a ser repetido...
<?php endwhile; ?>

Explicando os trechos destacados: antes de tudo, criamos um array de nome $usados. No primeiro loop, a cada iteração, adicionamos o id do post da vez no array. E finalmente, nos loops consecutivos, verificamos se o post da vez já foi usado antes de carregar o seu conteúdo.

No bom programês, seria algo como:

<?php $usados = lista(); ?>
<?php $noticias = consulte_posts("quantidade_de_posts=3 e categoria_de_nome=noticias"); ?>
<?php enquanto(houverem_posts_em_noticias()) : carregue_o_post_da_vez(); ?>
 <?php adicionar_na_lista_dos_usados($id_do_post); ?>
trecho da interface a ser repetido...
<?php verifique_se_ainda_há_posts; ?>
 
<?php $artigos = consulte_posts("quantidade_de_posts=3 e categoria_de_nome=artigos"); ?>
<?php enquanto(houverem_posts_em_artigos()) : carregue_o_post_da_vez(); ?>
<?php se(na_lista_dos_usados_houver($id_do_post)) pular_iteração; ?>
 <?php adicionar_na_lista_dos_usados($id_do_post); ?>
trecho da interface a ser repetido...
<?php verifique_se_ainda_há_posts; ?>

Caso seu template tenha mais de dois loops, basta repetir a estrutura do segundo loop.

Qualquer dúvida é só avisar.

Multiplos Loops

Para deixar seu blog com mais cara de site um dica é mudar o modelo de apresentação das notícias nas áreas principais. Ao invés da lista corrida dos últimos posts na home do blog, colunas organizam melhor as notícias além de permitir uma visão mais ampla do conteúdo, por exemplo, você pode dividir seu site em sessões e então listar na home as últimas notícias de cada sessão, deixando a disposição mais equilibrada. Dessa forma também é possível agrupar uma quantidade maior de posts evitando que os visitantes fiquem rolando o site ou procurando o conteúdo através da paginação.

O ‘WP_Query’ é a classe responsável pelos loops no WordPress, com ele podemos criar consultas no site que estarão amparadas por todas as funções presentes no Loop do WordPress facilitando todo o serviço de criação de novas colunas. A forma como ele funciona é semelhante ao ‘query_posts‘, inclusive os argumentos são os mesmos.

Aqui vai um exemplo:

<?php $noticias = new WP_Query("category_name=noticias&showposts=3"); ?>
<?php if($noticias->have_posts()) : ?>
<div class="noticias">
<?php while($noticias->have_posts()) : $noticias->the_post(); ?>
trecho da interface a ser repetido...
<?php endwhile; ?>
</div>
<?php endif; ?>
 
<?php $artigos = new WP_Query("category_name=artigosamp;showposts=3"); ?>
<?php if($artigos->have_posts()) : ?>
<div class="artigos">
<?php while($artigos->have_posts()) : $artigos->the_post(); ?>
trecho da interface a ser repetido...
<?php endwhile; ?>
</div>
<?php endif; ?>

Notem que utilizando o ‘WP_Query’, as funções ‘have_posts()’ e ‘the_post()’ devem ser precedidas pelo objeto instanciado. Como ‘$noticias’ e ‘$artigos’ do exemplo mostrado acima.

Nesse exemplo eu também adicionei a condicional if para mostrar como alterar a formatação dos posts das diferentes sessões. No programês:

<?php $noticias = consulte_posts("quantidade_de_posts=3 e categoria_de_nome=noticias"); ?>
<?php se(houverem_posts_em_noticias()) : ?>
<div class="noticias">
<?php enquanto(houverem_posts_em_noticias()) : carregue_o_post_da_vez(); ?>
trecho da interface a ser repetido…
<?php verifique_se_ainda_há_posts; ?>
</div>
<?php fim_das_noticias; ?>

O importante é que tenham em mente que as tags abertas entre o ‘if’ e o ‘while’ devem ser fechadas entre o ‘endwhile’ e o ‘endif’, ok.

Personalizando O Loop

Após entender como O Loop funciona, já podemos começar a brincar com o WordPress controlando o conteúdo a ser caregado ou filtrado. Mais uma vez o WordPress facilita a vida dos desenvolvedores disponibilizando a função query_posts().

Essa função permite criar parâmetros de consulta ou adicionar novos parâmetros aos passados via endereço do navegador, dessa forma você pode: excluir uma categoria da pesquisa; re-ordenar os posts; limitar a quantidade de resultados; entre outras coisas.

O funcionamento do query_posts é simples, apenas adicione a função ‘query_posts(‘args’)’ antes da função ‘have_posts()’ substituindo o args pelos argumentos desejados à sua consulta. Dessa forma o ‘have_posts()’ irá ignorar os parâmetros passados pelo endereço e fará uma consulta baseada nos dados informados. Por exemplo, se você quer listar três posts aleatórios da categoria ‘destaques’ o script seria assim:

<?php query_posts("&orderby=rand&showposts=3&category_name=destaques"); ?>
<?php while(have_posts()) : ?>
trecho da interface a ser repetido...
<?php endwhile; ?>

Note que cada atributo é separado pelo & assim como nos parâmetros passados via url. Dessa forma os desenvolvedores se sentem mais familiarizados com o código e não precisam ficar decorando a ordem dos atributos nem se preocupar em anular os que não serão usados.

Caso a sua intenção seja apenas filtrar os resultados de uma busca, adicione a variável ‘$query_string’ à sua função query_posts, dessa forma o WordPress mescla os seus argumentos com os argumentos da página. Essa variável é muito importante quando você pretende manter a navegabilidade, como é o caso dos resultados de uma pesquisa ou do conteúdo da página inicial do site. Para exemplificar, segue como seria o script para retirar uma categoria dos resultados de uma pesquisa:

<?php query_posts("{$query_string}&cat=-3"); ?>
<?php while(have_posts()) : ?>
trecho da interface a ser repetido...
<?php endwhile; ?>

Esse script deve ficar no arquivo search.php, então os posts encontrados na categoria 3 não aparecerão nos resultados das pesquisas e a paginação dos resultados continuará funcionando.

O Loop

Para quem desenvolve em WordPress o mais importante é entender como funciona o loop. O Loop é a estrutura responsável por carregar os posts no WordPress, ele funciona em todos os templates do tema, esse é o motivo de sua grande importância. O que alimenta a consulta do loop são os parâmetros passados no endereço do site, carregados cronológicamente por padrão.

Por exemplo: Ao acessar o endereço http://www.dominio.com/?cat=1, estaremos passando para o loop que a categoria é igual a 1, assim, o loop irá carregar os posts que estejam dentro dessa categoria apenas.

Todos os resultados obtidos com a consulta são armazenados em um array chamado $posts e a cada volta do loop a chave do array é incrementada. Dessa forma, precisamos somente de uma estrutura de repetição que monte o conteúdo de cada post dentro da nossa interface. Para facilitar ainda mais, o WordPress disponibiliza duas funções que fazem quase todo o trabalho para nós, são elas:

  • have_posts(), que verifica se ainda existem posts no array; e
  • the_post(), que carrega os dados do post da vez.

A estrutura mais utilizada nos temas do WordPress é:

<?php while(have_posts()) : the_post(); ?>
trecho da interface a ser repetido...
 <?php endwhile; ?>

Traduzindo para o programês, ficaria assim:

<?php enquanto(houverem_posts()) : carregue_o_post_da_vez(); ?>
trecho da interface a ser repetido...
<?php verifique_se_ainda_há_posts; ?>

Dentro do loop estarão disponíveis os atributos do post da vez, esses atributos podem ser acessados utilizando as funções the_title(), the_permalink(), the_content(), para citar algumas. Sabendo disso, para montar um template que mostre o título, o autor e a data de publicação de um post precisaríamos simplesmente adicionar as respectivas funções nos locais apropriados. Segue mais um exemplo:

<?php the_permalink(); ?>“><?php the_title(); ?></a></h2> <p class="data"><?php the_time(); ?></p> <p class="autor"><?php the_author(); ?></p> <?php endwhile; ?>

Nesse exemplo teríamos, para cada post, uma tag 'h2' com o título do post, linkando para a página do post; uma classe 'data' com a data do post; e uma classe 'autor' com o autor do post. A formatação do html vai depender da sua interface.