Foi lançado recentemente o novo WordPress 3.0 que inclui uma série de grandes novidades e alterações à estrutura e forma como o WordPress trabalha, nomeadamente os novos Custom Post Types. A pedido do leitor Flávio Araújo, vamos hoje falar sobre os Custom Post Types, tendo como base o excelente artigo dos colegas do blog Think Vitamin.

Como referido pelo próprio criador dos Custom Post Types, por vezes o WordPress introduz novas funcionalidades que à partida parecem demasiado complexas mas que na realidade não o são. Os Custom Post Types são uma delas. Na verdade esta nova funcionalidade deverá ser vista como conteúdo customizável e nada mais do que isso.

O QUE SÃO CUSTOM POST TYPES?

O nome Custom Post Type é na verdade bastante confuso pois introduz o nome genérico “Post” que na verdade nada tem a ver com um post de um blog. Se pretende compreender melhor esta nova funcionalidade, substitua esse termo por “content”, ou seja, tipos de conteúdo customizado (custom content type). Dessa forma é mais fácil compreender o conceito.

Os custom post types não têm regras que os definem propriamente e relativamente aquilo que são. Eles podem na verdade representar qualquer tipo de conteúdo que você deseje. Por exemplo, o WordPress oferece originalmente diferentes tipos de custom post types:

  • Posts do blog
  • Páginas
  • Anexos
  • Revisões
  • Menus de navegação (WordPress 3.0)

Basicamente este tipo de conteúdo utiliza a mesma forma de criação, edição e armazenamento de um artigo de um blog, mas com muito mais controlo criativo sobre o mesmo.

IDEIAS CUSTOM POST TYPES?

Embora o WordPress 3.0 introduza uma série de custom post types originalmente, existem muitos desenvolvedores e webdesigners que pretendem levar o WordPress ao próximo nível. Vejamos alguns exemplos criativos que se podem construir a partir de diferentes Custom Post Types:

  • Listas de classificados
  • Calendários de eventos.
  • Base de dados de filmes.
  • Base de dados de livros.
  • Integração de um fórum sem problemas de compatibilidade.
  • Um sistema de tickets de serviço e helpdesk.
  • Portfólios.
  • Galeria de design e fotografia.
  • Etc.

As opções são na verdade infinitas e estão apenas dependentes da sua capacidade criativa, portanto, evite limitar-se aos exemplos dados e sempre que sentir necessidade de criar algo no seu blog, provavelmente irá conseguir faze-lo utilizando Custom post types.

COMO CRIAR UM CUSTOM POST TYPE?

Os custom post types são extremamente simples de utilizar do ponto de vista do painel de administração do WordPress. No entanto e tal como referimos em cima, os designers/desenvolvedores ainda necessitam de ter algum conhecimento de PHP, excepto se optarem por plugins como o Custom Post Template e o Custom Post Type UI.

Neste tutorial vamos editar o ficheiro functions.php que se encontra na sua diretoria principal do seu template. Vamos apenas acrescentar código, portanto, poderá fazer a edição do seu ficheiro no topo ou no fundo do mesmo. Com algumas edições, pretendemos criar um custom post type para o nosso portfolio, e um template que irá utilizar esta informação. No final acabaremos com um novo menu no nosso painel administrativo, algo deste tipo:

Uma nova página intitulada “My Portfolio”:

E um novo local onde colocar os conteúdos específicos desta nova secção:

PRIMEIRO PASSO

Eis a primeira porção de código que teremos de adicionar ao ficheiro functions.php:

add_action('init', 'portfolio_register');
 
function portfolio_register() {
 
	$labels = array(
		'name' => _x('My Portfolio', 'post type general name'),
		'singular_name' => _x('Portfolio Item', 'post type singular name'),
		'add_new' => _x('Add New', 'portfolio item'),
		'add_new_item' => __('Add New Portfolio Item'),
		'edit_item' => __('Edit Portfolio Item'),
		'new_item' => __('New Portfolio Item'),
		'view_item' => __('View Portfolio Item'),
		'search_items' => __('Search Portfolio'),
		'not_found' =>  __('Nothing found'),
		'not_found_in_trash' => __('Nothing found in Trash'),
		'parent_item_colon' => ''
	);
 
	$args = array(
		'labels' => $labels,
		'public' => true,
		'publicly_queryable' => true,
		'show_ui' => true,
		'query_var' => true,
		'menu_icon' => get_stylesheet_directory_uri() . '/article16.png',
		'rewrite' => true,
		'capability_type' => 'post',
		'hierarchical' => false,
		'menu_position' => null,
		'supports' => array('title','editor','thumbnail')
	  ); 
 
	register_post_type( 'portfolio' , $args );
}

Todos aqueles que já trabalharam com o WordPress no passado irão certamente reconhecer a estrutura. Iremos adicionar uma acção quando o painel de administração do WP inicializar para que este chame a função portfolio_register(). Nessa função iremos criar duas arrays, $labels e $args, e depois utilizar o register_post_type para juntar tudo. Para o fazer iremos atribuir o nome ‘portfolio’ e dizer-lhe para utilizar os argumentos da array $args.

A parte mais complexa está no detalhe, portanto vamos analisar alguns desses argumentos. A lista completa encontra-se em  http://codex.wordpress.org/Function_Reference/register_post_type. Primeiro analisemos a array $labels:

  • name este é o (provavelmente plural) nome para o nosso novo post type
  • singular_name a forma como você se refere a ele no singular (do tipo: ‘Adicionar novo ****’)

Provavelmente você poderá trabalhar o resto das $labels sozinho, uma vez que eles apenas se referem a diferentes circunstâncias nas quais o nome do nosso custom post type será usado.

E agora analisemos a array $args:

  • public serão apresentadas no admin UI
  • show_ui deveremos mostrar um painel de admin para este custom post type
  • menu_icon um ícone customizado para o painel de admin
  • capability_type o WordPress irá tratar este como um ‘post’ para leitura, edição, e capacidade de eliminação
  • hierarchical ele é hierárquico, como as páginas
  • rewrite reescrever os permalinks utilizando a slug ‘portfolio’
  • supports que items pretendemos mostrar no adicionar/editar post page

Este é o primeiro passo, e já será o suficiente para que possa ver o seu novo custom post type no seu painel de administração do WordPress. Guarde o ficheiro functions.php e veja-o!

SEGUNDO PASSO

A próxima coisa a fazer é o registo da taxonomia. Basicamente é criar categorias para este novo tipo de conteúdo.

Por exemplo, no nosso portfolio desejamos incluir os nomes das tecnologias e software utilizados para criar o trabalho. Iremos chamar essa taxonomia de ‘Skills’, e preenche-la com nomes tipo HTML, CSS e jQuery.

É apenas uma linha de código:

register_taxonomy("Skills", array("portfolio"), array("hierarchical" => true, "label" => "Skills", "singular_label" => "Skill", "rewrite" => true));

O primeiro item é o nome da taxonomia, ‘Skills’. O segundo é o nome do tipo de objecto a que a estamos a aplicar, que no nosso caso é o nosso custom post type ‘portfolio’ (que é uma array). Finalmente os nossos argumentos; poderá encontrar uma listagem completa em http://codex.wordpress.org/Function_Reference/register_taxonomy, e aqui iremos utilizar apenas três que tenham as características que desejamos, tal como explicado no primeiro passo.

Adicionando essa linha de código, já poderá ver algo deste tipo:

Posteriormente poderá adicionar ‘skills’ tal como faz com as categorias dos seus blogs. Será algo deste tipo:

TERCEIRO PASSO

O terceiro passo é adicionar campos de informação customizados no adicionar/editar post page.

Para o nosso portfolio poderemos adicionar coisas como o ano em que a peça foi publicada e detalhes de quem a desenhou, construir, e produziu o site/design.

Neste caso existe um pouco mais de código, mas se por ventura o ler, compreenderá facilmente o seu sentido:

add_action("admin_init", "admin_init");
 
function admin_init(){
  add_meta_box("year_completed-meta", "Year Completed", "year_completed", "portfolio", "side", "low");
  add_meta_box("credits_meta", "Design & Build Credits", "credits_meta", "portfolio", "normal", "low");
}
 
function year_completed(){
  global $post;
  $custom = get_post_custom($post->ID);
  $year_completed = $custom["year_completed"][0];
  ?>
  <label>Year:</label>
  <input name="year_completed" value="<?php echo $year_completed; ?>" />
  <?php
}
 
function credits_meta() {
  global $post;
  $custom = get_post_custom($post->ID);
  $designers = $custom["designers"][0];
  $developers = $custom["developers"][0];
  $producers = $custom["producers"][0];
  ?>
  <p><label>Designed By:</label><br />
  <textarea cols="50" rows="5" name="designers"><?php echo $designers; ?></textarea></p>
  <p><label>Built By:</label><br />
  <textarea cols="50" rows="5" name="developers"><?php echo $developers; ?></textarea></p>
  <p><label>Produced By:</label><br />
  <textarea cols="50" rows="5" name="producers"><?php echo $producers; ?></textarea></p>
  <?php
}

Primeiro que tudo chamamos a função adicionar do admin_init quando o painel administrativo do WordPress se inicializa, e dentro dessa função adicionamos duas meta boxes – locais para introduzir os nossos dados. O contexto para estas duas boxes é:

<?php add_meta_box( $id, $title, $callback, $page, $context, $priority ); ?>

A única diferença entre estas duas é o local onde as colocamos no ecrã. O ‘year completed’ é colocado na barra lateral utilizado o ‘side’ enquanto os ‘credits’ são colocados no interior da página utilizando o ‘normal’.

Dentro de ambas as funções existe algum código PHP do WordPress e HTML para nos ajudar a definir correctamente os velhinhos custom fields. Tenha a certeza de que inclui:

global $post;

…para que possamos depois correr uma query

$custom = get_post_custom($post->ID);

Depois das duas meta boxes serem adicionadas, você irá visualizar algo deste tipo:

A última coisa a fazer no terceiro passo é termos a certeza de que guardamos estes valores. Para o fazer utilizamos:

add_action('save_post', 'save_details');

e

function save_details(){
  global $post;
 
  update_post_meta($post->ID, "year_completed", $_POST["year_completed"]);
  update_post_meta($post->ID, "designers", $_POST["designers"]);
  update_post_meta($post->ID, "developers", $_POST["developers"]);
  update_post_meta($post->ID, "producers", $_POST["producers"]);
}

Não existe nada demasiado complexo aqui. Estamos novamente a adicionar uma acção, desta vez para efectuar o ‘save_post’. Ele dispara a função save_details() que utiliza o update_post_meta (http://codex.wordpress.org/Function_Reference/update_post_meta) para guardar a informação relevante.

QUARTO PASSO

Agora é altura de dar um toque à página My Portfolio para mostrar alguma desta informação. Vejamos:

add_action("manage_posts_custom_column",  "portfolio_custom_columns");
add_filter("manage_edit-portfolio_columns", "portfolio_edit_columns");
 
function portfolio_edit_columns($columns){
  $columns = array(
    "cb" => "<input type=\"checkbox\" />",
    "title" => "Portfolio Title",
    "description" => "Description",
    "year" => "Year Completed",
    "skills" => "Skills",
  );
 
  return $columns;
}
function portfolio_custom_columns($column){
  global $post;
 
  switch ($column) {
    case "description":
      the_excerpt();
      break;
    case "year":
      $custom = get_post_custom();
      echo $custom["year_completed"][0];
      break;
    case "skills":
      echo get_the_term_list($post->ID, 'Skills', '', ', ','');
      break;
  }
}

Aqui estamos a adicionar duas novas funções ao WordPress Admin. A primeira, portfolio_edit_columns($columns), define simplesmente as colunas. Os primeiros dois argumentos “cb” e “title” são parte do core pelo que não recomendamos que mexa neles. Os outros três surgem do nosso custom post type, “description”, “year” e “skills”.

Temos também mais uma função para dizer ao WordPress onde ir buscar esta informação – portfolio_custom_columns($column). Utilizando um simples switch podemos definir qual a informação a mostrar em cada uma das colunas do layout. Para a “description” utilizamos o the_excerpt(), para o “year” vamos buscar o custom field utilizando o get_post_custom(), e para as “skills” vamos buscar uma lista de termos/taxonomias/categorias, separadas por vírgulas, utilizando o get_the_term_list().

Com isso teremos as nossas colunas definidas:

QUINTO PASSO

Originalmente os custom post types são mostrados utilizando o fallback single.php, ou index.php. Uma das coisas fantásticas é que podemos ser nós a criar os nossos templates customizados utilizando nomes do tipo single-xxxxxx.php. Neste caso iremos utilizar o single-portfolio.php. Crie apenas o seu ficheiro de template na sua directoria e o custom post type irá utiliza-lo. A forma como depois mostra a informação, já é consigo!

PROBLEMAS A REESCREVER ENDEREÇOS

Existem alguns problemas reportados relativamente ao reescrever endereços URL; por vezes não funcionam. No entanto, se está com este problema existem uma série de formas de solucionar o problema.

Primeiro, vá no seu menu Opções > Permalinks, e faça gravar. Normalmente este truque resolve o problema, tendo em consideração que o seu WordPress consegue gravar facilmente a informação no ficheiro .htaccess.

Se isso não funcionar você pode acrescentar uma linha de código depois de registar o tipo de post:

register_post_type( 'portfolio' , $args );
flush_rewrite_rules();

Isto poderá resolver de vez o seu problema…

Leitura adicional:
http://thinkvitamin.com/dev/create-your-first-wordpress-custom-post-type/
http://justintadlock.com/archives/2010/04/29/custom-post-types-in-wordpress

Bons truques! Até Já!