WordPress logo

Neste artigo você vai entender como funcionam os Custom Post Types no WordPress (tipos de post personalizados) e vai ter a possibilidade de fazer ainda mais com seu tema.

Apesar do artigo estar presente em nossa série de artigos sobre “Como criar um tema WordPress“, você pode criar Custom Post Types tanto no seu tema (utilizando o arquivo functions.php), ou em um plugin, no arquivo padrão do mesmo.

Por que usar Custom Post Types?

Por padrão, o WordPress vem com apenas dois tipos de locais para exibir conteúdo, posts e páginas. Custom Post Types têm a mesma finalidade de um post ou uma página, exibir ou salvar conteúdo.

Com eles você tem infinitas possibilidades, pois eles não afetam o funcionamento normal do seu WordPress. Com isso, você pode criar um local para exibir conteúdo enviado pelos usuários, criar um novo formato de página ou posts, sliders, áreas personalizadas no seu tema, como membros da equipe, ou sobre a sua empresa, e assim por diante. As possibilidades são realmente infinitas.

Recentemente, uma cliente me pediu para criar um formulário onde os usuários enviariam seu nome, telefone e e-mail. Fiz tudo com os Custom Post Types. Só tive que personalizar um pouco o modo com que os campos eram tratados, já que os campos de “Nome”, “Telefone” e “E-mail” não existem por padrão no WordPress. Nada que os meta dados do post não resolvessem (vou detalhar isso em outro artigo).

Neste artigo vou mostrar como registrar um Custom Post chamado “Filmes” (você pode escolher outro nome se quiser), registrar uma categoria para esse Custom Post, criar os template files necessários para exibir os artigos, e utilizar a consulta do WordPress (WP_Query) para exibir o conteúdo do seu Custom Post em áreas personalizadas do seu tema. É um guia definitivo, vou fazer o possível para que você não tenha que pesquisar nada na Internet para criar o que precisa.

Custom post types no WordPress

Custom post types no WordPress

Vamos lá!

Registrando o Custom Post e a Custom Taxonomy

Primeiramente vamos entender os nomes:

  • Custom Post refere-se ao seu post personalizado
  • Custom Taxonomy refere-se à categoria que iremos criar para o Custom Post

Ambos devem ser inicializados utilizando uma ação (action) que deve ser anexada na função init do WordPress.

Isso pode ser atingido com uma simples função PHP, veja:

<?php
// Custom post
function registra_tutsup_filmes() {
	// Vamos registrar tudo aqui dentro
}
// Adiciona a ação
add_action( 'init', 'registra_tutsup_filmes' );
?>

Vamos trabalhar dentro da função registra_tutsup_filmes.

Essa função deverá ser criada dentro do functions.php do seu tema, ou em um arquivo de plugin (estou trabalhando no functions.php).

Função para registrar um Custom Post Type

Dentro da nossa função registra_tutsup_filmes, vamos colocar o seguinte:

$labels = array(
	'name'               => 'Filmes',
	'singular_name'      => 'Filme',
	'menu_name'          => 'Filmes',
	'name_admin_bar'     => 'Filme',
	'add_new'            => 'Novo',
	'add_new_item'       => 'Novo',
	'new_item'           => 'Novo',
	'edit_item'          => 'Editar',
	'view_item'          => 'Visualizar',
	'all_items'          => 'Filmes',
	'search_items'       => 'Encontrar',
	'parent_item_colon'  => 'Pais:',
	'not_found'          => 'Nada encontrado.',
	'not_found_in_trash' => 'Nada encontrado.',
);

$args = array(
	'labels'             => $labels,
	'public'             => true,
	'publicly_queryable' => true,
	'show_ui'            => true,
	'show_in_menu'       => true,
	'query_var'          => true,
	'capability_type'    => 'post',
	'has_archive'        => true,
	'hierarchical'       => false,
	'menu_position'      => null,
	'rewrite' => array('slug' => 'tutsup_filmes'),
	'can_export' => true,
	'taxonomies' => array('post_tag'),
	'supports' => array(
		'title', 
		'editor', 
		'author', 
		'thumbnail',  
		'excerpt', 
		'trackbacks',
		'custom-fields',
		'comments',
		'revisions',
		/*'page-attributes',*/
		'post-formats'
	),
);

// Registra o custom post tutsup_filmes
register_post_type( 'tutsup_filmes', $args );

Apesar do trecho acima ter várias linhas de código, elas estão simplesmente configurando o que o seu Custom Post Type irá suportar ou exibir na tela para o usuário. Tudo é bastante intuitivo, contudo, não deixe de conferir o WordPress Codex – Function Reference/register post type.

Função para registrar uma Custom Taxonomy

Para registrar uma categoria personalizada para o Custom Post que acabamos de criar, adicione o seguinte dentro da nossa função registra_tutsup_filmes:

// Registra a categoria personalizada
register_taxonomy( 
	'tutsup_filmes_category', 
	array( 
		'tutsup_filmes' 
	), 
	array(
		'hierarchical' => true,
		'label' => 'Categoria',
		'show_ui' => true,
		'show_in_tag_cloud' => true,
		'query_var' => true,
		'rewrite' => array('slug' => 'tutsup_filmes_category'),
	)
);

Agora temos uma nova categoria para nosso post personalizado.

Não deixe de acessar o WordPress Codex – Function Reference/register taxonomy.

Adiciona o Custom Post na consulta principal

Pode ser que isso não seja necessário para seu caso, porém, se quiser adicionar seus posts customizados na página inicial (junto com os outros posts), basta adicionar o seguinte no seu functions.php:

// Adiciona o custom posts na query principal
function add_my_post_types_to_query( $query ) {
	if ( $query->is_main_query() && is_home() ) {
		$query->set( 'post_type', array( 'post', 'tutsup_filmes' ) );
		return $query;
	}
}
add_action( 'pre_get_posts', 'add_my_post_types_to_query' );

Se não precisar disso, simplesmente pule essa parte.

Nosso functions.php

Veja como ficou nosso arquivo functions.php (apenas a parte dos Custom Post Types):

// Custom post
function registra_tutsup_filmes() {
	$labels = array(
		'name'               => 'Filmes',
		'singular_name'      => 'Filme',
		'menu_name'          => 'Filmes',
		'name_admin_bar'     => 'Filme',
		'add_new'            => 'Novo',
		'add_new_item'       => 'Novo',
		'new_item'           => 'Novo',
		'edit_item'          => 'Editar',
		'view_item'          => 'Visualizar',
		'all_items'          => 'Filmes',
		'search_items'       => 'Encontrar',
		'parent_item_colon'  => 'Pais:',
		'not_found'          => 'Nada encontrado.',
		'not_found_in_trash' => 'Nada encontrado.',
	);

	$args = array(
		'labels'             => $labels,
		'public'             => true,
		'publicly_queryable' => true,
		'show_ui'            => true,
		'show_in_menu'       => true,
		'query_var'          => true,
		'capability_type'    => 'post',
		'has_archive'        => true,
		'hierarchical'       => false,
		'menu_position'      => null,
		'rewrite' => array('slug' => 'tutsup_filmes'),
		'can_export' => true,
		'taxonomies' => array('post_tag'),
		'supports' => array(
			'title', 
			'editor', 
			'author', 
			'thumbnail',  
			'excerpt', 
			'trackbacks',
			'custom-fields',
			'comments',
			'revisions',
			/*'page-attributes',*/
			'post-formats'
		),
	);
	
	// Registra o custom post
	register_post_type( 'tutsup_filmes', $args );
	
	// Registra a categoria personalizada
	register_taxonomy( 
		'tutsup_filmes_category', 
		array( 
			'tutsup_filmes' 
		), 
		array(
			'hierarchical' => true,
			'label' => __( 'Categoria' ),
			'show_ui' => true,
			'show_in_tag_cloud' => true,
			'query_var' => true,
			'rewrite' => array('slug' => 'tutsup_filmes_category'),
		)
	);
}
add_action( 'init', 'registra_tutsup_filmes' );

// Adiciona o custom posts na query principal
function add_my_post_types_to_query( $query ) {
	if ( $query->is_main_query() && is_home() ) {
		$query->set( 'post_type', array( 'post', 'tutsup_filmes' ) );
		return $query;
	}
}
add_action( 'pre_get_posts', 'add_my_post_types_to_query' );

Apenas com isso você será capaz de cadastrar novos posts utilizando a opção “Filmes” da sua área administrativa (wp-admin).

 Template Files (arquivos de modelo) ou WP_Query?

Existem milhares de maneiras para você exibir o conteúdo dos seus Custom Post Types, dentre elas temos:

  • Utilizar WP_Query para buscar e exibir o conteúdo dos Custom Post Types em qualquer local do seu tema;
  • Utilizar os template files junto com o loop para exibir os Custom Post Types como artigos normais;

Nessa parte do artigo irei mostrar ambos os métodos indicados acima.

Template files (arquivos de modelo)

Para utilizar os template files, criamos 4 arquivos:

  • single-tutsup_filmes.php (para exibir o conteúdo single do Custom Post tutsup_filmes);
  • archive-tutsup_filmes.php (para exibir todos os artigos do Custom Post tutsup_filmes);
  • taxonomy-tutsup_filmes_category.php (para exibir todos os artigos da categoria tutsup_filmes_category);
  • loop-tutsup_filmes.php (apenas por questão de organização, separamos o loop do nosso Custom Post).

Vamos ver o conteúdo de todos os arquivos separadamente abaixo:

single-tutsup_filmes.php

O conteúdo é praticamente o mesmo do index.php, você pode modificar conforme preferir.

<!-- Adiciona o cabeçalho (header.php) -->
<?php get_header(); ?>

<main role="main" class="artigos conteudo padding-esquerda-direita">

	<div class="linha clearfix">
	
		<div class="colunas principal">
			<div class="conteudo-ajax conteudo-coluna margem-total">
			
				<?php get_template_part('loop', 'tutsup_filmes'); ?>
			
				<?php
					$paginas = paginacao();
					if ( ! empty( $paginas ) ): 
				?> 
					<div class="paginacao">
						<?php echo $paginas;?>
					</div>
				<?php endif; ?>
				
			</div>			
		</div>
		
		<aside class="colunas lateral">
			<div class="conteudo-coluna margem-total">
				 <?php get_sidebar(); ?> 
			</div>
		</aside>
		
	</div>
	
</main>

<!-- Adiciona o rodapé (footer.php) -->
<?php get_footer(); ?>

 archive-tutsup_filmes.php

Também tem o mesmo conteúdo do index.php, você pode editar conforme preferir.

<!-- Adiciona o cabeçalho (header.php) -->
<?php get_header(); ?>

<main role="main" class="artigos conteudo padding-esquerda-direita">

	<div class="linha clearfix">
	
		<div class="colunas principal">
			<div class="conteudo-ajax conteudo-coluna margem-total">
				<?php get_template_part('loop', 'tutsup_filmes'); ?>

				<?php
					$paginas = paginacao();
					if ( ! empty( $paginas ) ): 
				?> 
					<div class="paginacao">
						<?php echo $paginas;?>
					</div>
				<?php endif; ?>
				
			</div>			
		</div>
		
		<aside class="colunas lateral">
			<div class="conteudo-coluna margem-total">
				 <?php get_sidebar(); ?> 
			</div>
		</aside>
		
	</div>
	
</main>

<!-- Adiciona o rodapé (footer.php) -->
<?php get_footer(); ?>

 taxonomy-tutsup_filmes_category.php

Como os outros arquivos, também tem o mesmo conteúdo do index.php, modifique se precisar:

<!-- Adiciona o cabeçalho (header.php) -->
<?php get_header(); ?>

<main role="main" class="artigos conteudo padding-esquerda-direita">

	<div class="linha clearfix">
	
		<div class="colunas principal">
			<div class="conteudo-ajax conteudo-coluna margem-total">
				<?php get_template_part('loop', 'tutsup_filmes'); ?>

				<?php
					$paginas = paginacao();
					if ( ! empty( $paginas ) ): 
				?> 
					<div class="paginacao">
						<?php echo $paginas;?>
					</div>
				<?php endif; ?>
				
			</div>			
		</div>
		
		<aside class="colunas lateral">
			<div class="conteudo-coluna margem-total">
				 <?php get_sidebar(); ?> 
			</div>
		</aside>
		
	</div>
	
</main>

<!-- Adiciona o rodapé (footer.php) -->
<?php get_footer(); ?>

 loop-tutsup_filmes.php

<!-- O loop -->
<?php if ( have_posts() ) : while ( have_posts() ) : the_post();?>

	<!-- Container do artigo -->	
	<div class="artigo-container">
		
		<!-- Título do post -->
		<h1>
			<a href="<?php the_permalink(); ?>"><?php the_title(); ?></a>
		</h1>
		
		<!-- Categoria -->
		<?php
		$taxonomy = 'tutsup_filmes_category';
		$terms = get_terms( $taxonomy, '' );
		
		if ( $terms ) {
				foreach($terms as $term) {
					echo '<a href="' . esc_attr(get_term_link($term, $taxonomy)) . '">' . $term->name.'</a>';
				}
		}
		?>
		
		<!-- Autor -->
		<?php the_author(); ?>
		
		<!-- Data -->
		<?php the_date(); ?>
		
		<?php if ( is_single() || is_page() ): ?>
			<!-- Conteúdo do post -->
			<?php the_content(); ?>
			<?php the_tags(); ?>
		<?php else: ?>
			<!-- Resumo do post -->
			<?php the_excerpt(); ?>
		<?php endif; ?>
		
		<?php comments_template(); ?>
	</div>
	
<?php endwhile; ?>
<?php endif; // Loop ?>

Aqui temos apenas uma pequena edição na “Categoria”, pois estamos utilizando uma Custom Taxonomy (Categoria personalizada).

Utilizando a WP_Query para exibir o conteúdo

Se este for seu caso, você pode utilizar WP_Query para exibir o conteúdo do seu Custom Post Type, veja como é simples:

<?php
// Custom posts mais recentes
if ( is_single() ) {
	echo '<h4>Filmes mais recentes</h4>';
	
	// A consulta
	$the_query = new WP_Query( array(
		'post_type' => 'tutsup_filmes',
		'post__not_in' => array( get_the_ID() ),
		'posts_per_page' => 5
	) );

	// O loop
	if ( $the_query->have_posts() ) {
		echo '<ul>';
		while ( $the_query->have_posts() ) {
			$the_query->the_post();
			echo '<li><a href="' . get_the_permalink() . '">' . get_the_title() . '</a></li>';
		}
		echo '</ul>';
	} else {
		// Nada encontrado
	}
	/* Restaura a consulta original */
	wp_reset_postdata();
} // Custom posts mais recentes - is_single
?>

Neste caso, estou pegando os cinco posts mais recentes da minha sessão de Custom Post Type, que é tutsup_filmes.

Não deixe de conferir o WordPress Codex – Class Reference/WP Query.

Download

Caso queira baixar o nosso tema de testes com as edições acima, segue o link:

Concluindo

Talvez esse artigo seja um pouco mais avançado para quem não tem costume de trabalhar com WordPress, porém, se você baixar os arquivos do tema que estamos criando, será possível estudar tudo o que fizemos até agora.

Além disso, se você tiver alguma dúvida é só perguntar nos comentários abaixo.