Tableless - Desenvolvimento inteligente com Padrões Web

29/03/2011
Wordpress

Custom Post Types no WordPress

Crie tipos de conteúdo diferentes, agregue taxonomias e adicione campos personalizados. Deixe o seu site cada vez mais personalizado, trabalhando a fundo com o WordPress como CMS.

Por


Custom Post Types é a função que manipula os tipos de conteúdo no WordPress, ou seja, pode-se criar conteúdos personalizados a partir da sua demanda. Isso é uma das provas mais concretas que temos hoje um CMS muito forte que não serve apenas para criar blog e/ou sites de pequeno porte.

Criando Custom Post Types

Como o assunto é muito amplo, criarei com vocês um exemplo de Notícias.

Em functions.php, adicione:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<?php
    add_action('init', 'type_post_noticias');
 
    function type_post_noticias() {
        $labels = array(
            'name' => _x('Notícias', 'post type general name'),
            'singular_name' => _x('Notícia', 'post type singular name'),
            'add_new' => _x('Adicionar Novo', 'Novo item'),
            'add_new_item' => __('Novo Item'),
            'edit_item' => __('Editar Item'),
            'new_item' => __('Novo Item'),
            'view_item' => __('Ver Item'),
            'search_items' => __('Procurar Itens'),
            'not_found' =>  __('Nenhum registro encontrado'),
            'not_found_in_trash' => __('Nenhum registro encontrado na lixeira'),
            'parent_item_colon' => '',
            'menu_name' => 'Notícias'
        );

        $args = array(
            'labels' => $labels,
            'public' => true,
            'public_queryable' => true,
            'show_ui' => true,         
            'query_var' => true,
            'rewrite' => true,
            'capability_type' => 'post',
            'has_archive' => true,
            'hierarchical' => false,
            'menu_position' => null,
'register_meta_box_cb' => 'noticias_meta_box',     
            'supports' => array('title','editor','thumbnail','comments', 'excerpt', 'custom-fields', 'revisions', 'trackbacks')
          );
 
register_post_type( 'noticias' , $args );
flush_rewrite_rules();
}
?>

Primeiro adicionamos a função add_action, que vai abrigar dois parâmetros, o gancho (aonde vai rodar a função) e a função callback (a função que vai ser chamada com as informações). É função type_post_noticias que vai armazenar as informações do post. A variável $labels, está indicando os valores para cada título.

A variável $args é onde vamos colocar as informações do post. Explico com mais detalhes abaixo.

  • labels: Indica a variável que contém as informações do label
  • public: determina se o conteúdo pode ser visto no painel de administração, por padrão é falso.
  • publicly_queryable: determina se a consulta pode ser realizada usando o argumento post_type, por padrão ele herda o valor do public.
  • show_ui: determina se telas de adicionar e editar o post devem ser adicionadas esse tipo de post, por padrão ele herda o valor do public.
  • query_var: evita consultas ou valores de sequência, por padrão é falso.
  • rewrite: reescrita do link, por padrão é verdadeiro.
  • capability_type: define o tipo de conteúdo que o tipo de post personalizado vai seguir, por padrão é post.
  • has_archive: permite os arquivos do tipo do post, por padrão é falso.
  • hierarchial: determina que o tipo do post é hierárquico (igual o das páginas), por padrão o valor é falso
  • menu_position: determina a ordem do menu, por padrão é null (ele ficará em baixo do menu dos comentários), mas pode receber esses seguintes valores
    • 5 – Em baixo do menu Post;
    • 10 – Em baixo do menu mídia;
    • 20 – Em baixo do menu páginas;
    • 60 – Em baixo do primeiro separador;
    • 100 – Em baixo do segundo separador.
  • register_meta_box_cb: Retorna a função que chamará as caixas de meta para o formulário (irei explicar à frente).
    supports: determina os recursos aceitos para esse tipo de post, por padrão é vazio, por isso tem que definir, ele recebe esses valores:

    • author: o autor por uma área personalizada
    • title: inclui o título ao tipo do post
    • editor: inclui a área de conteúdo do post (VISUAL ou HTML) e uploader de mídia
    • excerpts: inclui o campo de resumo
    • thumbnail: determina se o tipo de post pode inlcuir miniatura de post (http://tableless.com.br/adicionando-post-thumbnail)
    • comments: inclui os comentários
    • trackbacks: inclui os trackbacks
    • custom-fields: inclui a baixa de Custom Fields e se os campos serão automaticamente salvos
    • revisions: inclui revisões (armazenadas ou exibidas)
    • page-attributes: inclui a caixa Page Attributes (são encontradas na inserção de páginas), contendo as opções de parent, template e menu order.

Para o registro do post, é necessário a função register_post_type, que abrigará dois parâmetros. No primeiro é definido o nome do post (de preferência coloque em letras minúsculas e sem espaço, uma slug) e o outro agregará as demais informações do post, neste caso, a variável $args.

Criando Taxonomias

A taxonomia é uma forma de criar um tipo de categoria para o tipo de conteúdo.

Adicione em functions.php:

1
2
3
4
5
6
7
8
9
10
11
12
<?php
register_taxonomy(
"categorias",
      "noticias",
      array(            
        "label" => "Categorias",
            "singular_label" => "Categoria",
            "rewrite" => true,
            "hierarchical" => true
)
);
?>

Com a função register_taxonomy, registramos uma nova taxonomia. O primeiro valor aonde será definido o nome da taxonomia (de preferência de letras minúsculas e sem espaço), o segundo valor é definido o nome do tipo de conteúdo registrado, onde essa taxonomia se agregará. No array, é definido informações já explicadas acima.

Criando campos personalizados

Vamos trabalhar com a variável register_meta_box na criação de campos personalizados. Para essa variável, foi definido o valor noticias_meta_box, que será a nossa função callback, a função que vai ser chamada para a criação da meta.

Em functions.php adicione:

1
2
3
4
5
<?php
function noticias_meta_box(){        
        add_meta_box('meta_box_test', __('Meta Box'), 'meta_box_meta_test', 'noticias', 'side', 'high');
}
?>

Retornamos a função definida para a criação de meta box, dentro dela definimos na função add_meta_box, os argumentos respectivamente, são:

  • $id: o nome para o meta box, destinado para uso interno
  • $title: o título da caixa
  • $callback: a função que irá ser chamada para imprimir o conteúdo da caixa
  • $page: o tipo de post que vão existir esse meta, para aparecer em mais de um, coloque dentro de um array, ex: array(‘noticias’, ‘post’)
  • $context: em qual parte da página de edição ela vai está (normal, advanced ou side [lateral])
  • $priority: em qual altura a caixa deve aparecer dentro da seção (high [alta], normal, low[baixa), a depender do valor, caixas com prioridade maior ficará encima

Depois que definimos a meta, vamos agora retornar a função que vai imprimir o conteúdo da caixa:

1
2
3
4
5
6
7
8
9
10
<?php
function meta_box_meta_test(){
      global $post;
      $metaBoxValor = get_post_meta($post->ID, 'valor_meta', true);
?>        
    <label for="inputValorMeta">Valor: </label>
    <input type="text" name="valor_meta" id="inputValorMeta" value="<?php echo $metaBoxValor; ?>" />
<?php
    }
?>

A função foi criada, dentro dela imprimi-se o que o Box vai conter. Para garantir que o campo retornado é necessário usar a função get_post_meta. Ela requer três argumentos: o ID do post, o nome do campo (se possível sem acentos e nem espaços) e um valor true/false determinando se a função deve retornar um valor individual ou não.

Por fim criaremos a função que vai salvar as alterações dos campos personalizados:

1
2
3
4
5
6
7
8
<?php
    add_action('save_post', 'save_noticias_post');
   
    function save_noticias_post(){
        global $post;        
            update_post_meta($post->ID, 'valor_meta', $_POST['valor_meta']);
    }
?>

Inicialmente adicionamos a ação no gancho save_post com o retorno da função save_noticias_post. A função update_post_meta vai receber três argumentos, os dois primeiros serão iguais aos explicados na função get_post_meta, a única diferença que o ultimo argumento vai receber o valor alterado, caso seja alterado manualmente colocamos uma simples string com o outro valor. Neste caso a alteração será feita após o envio do formulário.

Criando um LOOP personalizado

Vamos criar o LOOP personalizado de acordo com o tipo de post, caso ainda não tenha visto o que seja um LOOP, veja

Aonde queria que aparecesse a repetição, adicione:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
$newsArgs = array( 'post_type' => 'noticias', 'posts_per_page' => 4);                  
                       
      $newsLoop = new WP_Query( $newsArgs );                  
                       
      while ( $newsLoop->have_posts() ) : $newsLoop->the_post();              ?>
<div class="news">                                
        <h1><a href="<?php the_permalink(); ?>" title="<?php the_title(); ?>"><?php the_title(); ?></a></h1>
            <p><strong><?php the_time('F jS, Y') ?></strong> by <?php the_author_posts_link() ?></p>
            <p><?php the_content(); ?></p>
<p><?php echo get_the_term_list( $post->ID, 'categorias', 'Categorias: ', ' '); ?></p>
            <p>Retornando o campo personalizado: <?php echo get_post_meta($post->ID, 'valor_meta', true); ?></p>
</div>
<?php endwhile; ?>

O único termo desconhecido no Loop é a função get_the_term_list, que vai retornar a taxonomia para o post. O primeiro argumento é o valor do ID do post, o segundo valor é o nome definido da taxonomia, o terceiro valor é o que vai retonar antes de retornar as taxonomias e o último o separador.

Não há dificuldade, o segredo está na variável $newsArgs, que é aonde você vai definir as opções da repetição, ele pode receber mais argumentos, que você pode ver em: http://codex.wordpress.org/Function_Reference/WP_Query

Para visualizar um post, editamos as informações no arquivo single.php do nosso tema, quando temos um Custom Post Type, por padrão ele lê com essa página, caso queria ter uma pagina só para o tipo de post, você pode uma nova página chamada single-{slug}.php, ou seja, essa slug seria trocada pelo nome do Custom Post Type, no nosso caso, single-noticias.php.

Feeds para tipos de post personalizado

Se seu site existe muitos leitores via feed e você quer mostrar o conteúdo personalizado, como fazer? Lendo um livro, WordPress 3 Básico (livro que indico para iniciantes ou desenvolvedores natos), achei essa solução, muito simples.

Em functions.php, adicione:

1
2
3
4
5
6
7
8
9
10
<?php
add_filter('pre_get_posts', 'postsfeed');
   
    function postsfeed($query){
        if( is_feed() ){
            $query->set('post_type', array('post', 'noticias'));
        }
        return $query;
    }
?>

No código vamos adicionar o filtro para a consulta de conteúdo para o Feed, você pode adicionar inúmeros conteúdos personalizados.

Reduzindo o código

Existe mesmo a necessidade para registrar o Custom Post Type a quantidade de argumentos que foi mostrado? Não.

Neste artigo fez questão de mostrar a maioria das variáveis, mas você pode reduzir o código ainda mais em futuras alterações. Em vez de registrar o seu conteúdo com aquele código enorme, pode-se substituir por:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php
add_action('init', 'type_post_noticias');
 
    function type_post_noticias() {
        $labels = array(
            'name' => _x('Notícias', 'post type general name'),
            'singular_name' => _x(Notícia', 'post type singular name')
        );

        $args = array(
            '
labels' => $labels,
            '
public' => true,          
            '
register_meta_box_cb' => 'noticias_meta_box',
            '
supports' => array('title','editor','thumbnail','comments', 'excerpt', 'custom-fields', 'revisions', 'trackbacks')
          );
 
    register_post_type( '
noticias' , $args );
    flush_rewrite_rules();  
?>

Ambas as formas estão corretas.

Por Paulo Rodrigues

Paulo Rodrigues é residente de Salvador-BA, especialista em criação de sites e desenvolvimento web desde de 2008. Foi com o desenvolvimento front-end que se apaixonou por esse caminho sem volta, atualmente além de interfaces, Paulo desenvolve para WordPress.

http://www.twitter.com/paulorodriguesw

Veja os outros posts de

  • http://www.nerdhead.com.br/ Rafael Cirolini

    Uso muito esta funcionalidade! Foi uma das melhores implementações do 3.0!!!!

  • http://filipealmeida.com Filipe Almeida

    Ótimo post, Paulo Rodrigues!!
    Muito obrigado por compartilhar, o wordpress é mais poderosso do que eu imaginava, da pra fazer inumeras coisas ultilizando estes recursos citados por você.
    Tenho ainda muito o que aprender sobre wordpress.
    Obrigado novamente.
    Abraços

  • http://gurumidia.com.br Leandro Santos

    Excelente post e ótima funções, também desenvolvo em wordpress um excelente cms, a prova disso que desenvolvemos um portal de uma emissora em fortaleza-ce afilida da rede record, o seu portal de notícias, http://www.cnews.com.br

  • http://nauweb.comeuniversowp.com.br Marlon Amâncio

    Excelente post! Parabéns

    Realmente foi umas das melhores implementações do WP3. Só estou tendo problemas com as páginas arquivos de tags e pesquisa. Não estavam incluindo os custom posts nesses arquivos, então achei essa solução mas não consegui incluir os posts padrão, mesmo incluindo ‘post’ no array. (Outro objetivo era excluir as páginas da pesquisa e isso funcionou). Abraços.

    add_filter( ‘pre_get_posts’, ‘buscar_custom_posts’ );

    function buscar_custom_posts( $query ) {

    if ( ( is_tag() || is_search() || is_tax() ) && empty( $query->query_vars['suppress_filters'] ) )
    $query->set( ‘post_type’, array( ‘artigos’, ‘videos-e-slides’ ) );

    return $query;
    }

  • http://nauweb.com/universowp.com.br Marlon Amâncio

    Alguém testou esse código para incluir os posts personalizados nos feeds? Comigo não está funcionando :(

    Alterei o noticias para o nome do custom post que declarei, artigos. Testei através dos links abaixo mas não funcionou.

    http://example.com/?feed=rss
    http://example.com/?feed=rss2
    http://example.com/feed/
    http://example.com/feed/rss/
    http://example.com/feed/rss2/

    Quem puder ajudar ficarei muito agradecido.

  • Ângelo Lucas

    Valeu Cara, esse post me ajudou bastante!

  • http://lucianobraga.com/ Luciano Braga

    Muito bom o post. Valeu!

  • http://lucianobraga.com/ Luciano Braga

    Uma das melhores não. O melhor do 3.0.
    Gostei bastante dessa nova funcionalidade, ampliou ainda mais os usos que podemos fazer do WordPress. Recentemente usei esta funcionalidade para criar um sistema de loja virtual e compras coletivas em um único site WordPress. Outra função que acho muito boa também são as Meta Boxes.

  • http://www.eventoselazer.com.br Antonio

    Criei tres campos personalizados para meus posts que são:
    Site, E-mail e Telefone. que serão preenchidos para contato com o anunciante. O problema é que esses dados somem, ou seja, não são salvos. Sempre que reabro o post para uma atualização esses dados tem que ser inseridos novamente pois os campos ficam em branco.

  • Igor

    O artigo eh bom, enxuto, porem nao ensina a personarlizar a busca..

  • Paulo Rodrigues

    Oi Igor, tudo bacana meu velho? Mas presta atenção neste código para você filtrar seu post personalizado na busca:
    add_filter(‘pre_get_posts’,'querySearch’);function querySearch($query) {       if ($query->is_search) {$query->set(‘post_type’, array(‘post’, ‘nome-do-post’));}      return $query; } 

    Presta atenção naquele array, pois ali você vai definir quais posts da busca. Você pega pelo nome registrado, ok?

    Antônio, tudo bem com você? Olhe no artigo, pois tem mostrando como salva essas opções personalizadas, tá bem em baixo do código onde cria os campos personalizados, ok? Qualquer dúvida só postar.

    Peço desculpas pela demora, um abraço, muito sucesso pra vocês!

  • Ricardixbr

    Como eu insiro mais de um campo personalizado no mesmo custom post?

  • Salvadorcamino

    Faltou a paginação :(

  • Pingback: Usando Meta Box em seu tema WordPress | Tableless

  • Ricardo

    Vlww cara!!! 

    Abraço.

  • Augusto

    Nao esta muito claro para iniciantes..=/

  • Cefasdesigner

    como faço para criar uma taxonomia para uma pagina isolada????