Existem muitas maneiras para variar a exibição do conteúdo dentro do WordPress. Você pode optar pela criação de tipos de posts personalizados (Custom Post Types), Formatos de posts (Post Formats), além de ter a possibilidade de se utilizar da hierarquia de arquivos para esse mesmo fim. Quando o conteúdo trabalhado se trata de uma página do WordPress (tipo de post “page”), você também pode aplicar variações na apresentação através do recurso Modelo de página.

Um modelo de página, ou Page Template, é um tipo de variação que existe por padrão no WordPress. Você consegue gerenciar o modelo de uma página quando adiciona/edita uma página ou mesmo na listagem das páginas existentes usando o recurso de edição rápida.

Modelo de página - Edição rápida

Edição rápida de uma página, campo Modelo permite trocar facilmente entre os modelos existentes

Caso você esteja usando algum Tema pronto que não faça uso desse recurso ou mesmo tenha começado um Tema próprio sem nenhum modelo criado, esse campo não aparecerá em nenhuma das telas; seja na listagem no modo edição rápida ou mesmo na edição da página em si. Para que o campo seja exibido é preciso que o Tema ativo tenha ao menos um Modelo de Página dentro dele.

Como criar um Modelo de página no WordPress

O uso de modelos de páginas no WordPress pode ser muito interessante para evidenciar modelos de apresentação diferentes, como também separar conteúdos específicos; você pode por exemplo criar modelos para a página de serviços, fale conosco, quem somos, mapa do site, perguntas frequentes e tantos outros conteúdos que você queira diferenciar em seu projeto.

A criação de um template page é bem simples, basta que você crie um novo arquivo PHP na raiz do seu Tema, sendo que você pode atribuir qualquer nome a ele; porém logo no início do arquivo você precisa evidenciar em comentários a seguinte instrução:

// Template Name: Quem somos

Você também pode usar os comentários em várias linhas caso queira fazer uma breve documentação logo no cabeçalho.

/**
 * 
 * Template Name: Quem somos
 * Description: Possui uma apresentação da empresa
 * Qualquer outra informação adicional
 *
 **/

A única informação importante e necessária para que o arquivo seja reconhecido como um Modelo é a linha Template Name.

Apesar de você poder criar um template de página usando um arquivo .php de qualquer nome, recomendo que você adote alguma padronização para facilitar a manipulação desse tipo de conteúdo. O uso de algum prefixo funciona muito bem e permite que você identifique os modelos mais facilmente em meio aos demais arquivos do Tema. Apenas não utilize o prefixo page-[slug].php pois pode causar problemas com a hierarquia de arquivos do WordPress. Sugiro usar pg-[slug].php, tp-[slug].php ou qualquer outra variação do gênero.

Páginas e a hierarquia de modelos

Como mencionei acima, os modelos de página funcionam em harmonia com a hierarquia de modelos do WordPress e por isso o uso da nomenclatura page-slug.php não deve ser adotado para esse fim. Quando a URL de uma página é acessada os arquivos pesquisados em seu Tema são o page-[slug].php, page-[ID].php e page.php. Caso nenhum deles seja encontrado, assim como qualquer outras condições, o conteúdo do index.php é apresentado.

Quando você cria um novo modelo de página, ele antecede essas verificações; ou seja, quando a página é acessada e ela possui um modelo atribuído, o arquivo correspondente é mostrado. Seguindo o exemplo inicial dessa publicação, uma vez que você crie o arquivo pg-about.php para a página Quem Somos; ao acessar tal url, esse mesmo arquivo pg-about.php será a ponta final da hierarquia, ele será utilizado para mostrar as informações em tela ao seu visitante.

Criados os templates, a partir de agora darei início a criação de uma classe em forma de plugin que poderá te auxiliar bastante na utilização dos modelos em seu projeto. Caso prefira você também poderá incorporar essas rotinas em seu Tema, bastando fazer um simples require desse arquivo na pasta do Tema escolhido. O primeiro passo é a criação da classe Page_Template que receberá os métodos estáticos de manipulação dos templates.

<?php
class Page_Template {
} ?>

Capturar modelo de página atual

Em projetos que possuem vários de modelos de página, pode ser interessante identificar qual o modelo está sendo requisitado a fim de realizar rotinas específicas a ele. Logo a primeira funcionalidade desse nosso plugin será a captura do modelo de página da requisição atual.

class Page_Template {
    public static function get_current()
     {
         if ( !is_page() )
             return false;

        return str_replace(
             array( '/' . 'pg-', '.php', TEMPLATEPATH ),
             '',
             get_page_template()
         );
     }
}

Para chamar o método get_current em qualquer arquivo do seu Tema, basta usar:

Page_Template::get_current();

O método irá verificar se a requisição é uma página, e se for, vai recuperar o template para retorná-lo. Como a função get_page_template retorna o caminho completo do arquivo, para facilitar a compreensão e as verificações futuras removi o caminho bem como a extensão e prefixo do arquivo.

Percebeu no código acima como foi interessante adotar um padrão para a nomenclatura dos templates. Aqui preferi utilizar o prefixo pg-, formando o nome do arquivo pg-[slug].php. Com essa estrutura adotada quando for preciso verificar um modelo (pg-about.php) eu posso fazer algo como:

if ( Page_Template::get_current() == 'about' )
   // faça algo para o modelo Quem Somos

Isso foi possível pois foram removidos prefixo, extensão e caminho absoluto do arquivo.

Modelo de página por ID

Todas as demais rotinas que serão apresentadas de agora em diante devem estar dentro da classe principal Page_Template, sendo todos os métodos definidos como estáticos pois a classe não precisará de instâncias e propriedades diversas para funcionar, pelo contrário, a proposta principal do uso da classe aqui é para organizar e encapsular as informações.

O próximo passo na manipulação dos templates é trabalhar com modelos a partir de qualquer local do Tema, não precisando estar em uma requisição de um modelo de página ou dentro do respectivo arquivo. Para que você possa trabalhar com os modelos desse modo você precisa saber que a atribuição de um modelo a uma página ocorre através de um meta dado (Metadata API); ou seja, quando você atribui um modelo a uma página você cria um novo registro em na $wpdb->postmeta cuja chave é _wp_page_template. Desse modo, podemos recuperar por exemplo o identificador de uma página que possui um determinado template vinculado.

public static function get_id( $template )
{
    $page_id = 0;
    if ( is_string( $template ) ) {
        global $wpdb;
        $page_id = (int) $wpdb->get_var(
            $wpdb->prepare(
                "SELECT post_id FROM {$wpdb->postmeta} " .
                "WHERE meta_key='_wp_page_template' AND meta_value=%s " .
                "ORDER BY meta_id DESC LIMIT 1",
                $template
            )
        );
    }
    return $page_id;
}

A chamada para esse método recebe como parâmetro o nome completo do arquivo, porém sem o caminho absoluto.

Page_Template::get_id( 'pg-about.php' );

Normalmente usa-se um modelo de página apenas para uma página. Porém caso você queira aperfeiçoar esse método para não causar problema com páginas que estão na lixeira ou ainda recuperar o modelo de página (caso você use o mesmo modelo mais de uma vez) mais recente, você pode optar por:

public static function get_id( $template )
{
    $page_id = 0;
    if ( is_string( $template ) ) {
        global $wpdb;
        $page_id = (int) $wpdb->get_var(
            $wpdb->prepare(
                "SELECT post_id FROM {$wpdb->postmeta} pm " .
                "INNER JOIN {$wpdb->posts} p " .
                "ON pm.post_id=p.ID " .
                "WHERE p.post_status='publish' " .
                "AND pm.meta_key='_wp_page_template' " .
                "AND pm.meta_value=%s " .
                "ORDER BY p.post_date DESC LIMIT 1",
                $template
            )
        );
    }
    return $page_id;
}

Se você deseja capturar o modelo de uma página qualquer, ou ainda; se acontecer o processo contrário, onde você tem o ID do post mas não tem o modelo que foi atribuído a ele, a solução fica mais simples e direta.

public static function get_by_id( $page_id )
{
    return get_post_meta( (int) $page_id, '_wp_page_template', true );
}

Link permanente de um template

Uma vez que você já possui o identificador de um determinado modelo, recuperar as demais informações dessa página torna-se uma tarefa bem mais simples. Veja abaixo por exemplo, como você obter o link permanente a partir do nome de um modelo.

public static function get_permalink( $template )
{
    $url = '#';
    $page_id = self::get_id( $template );
    if ( $page_id )
        $url = get_permalink( $page_id );
    return $url;
}

O parâmetro $template é o mesmo utilizado para captura do ID da página, isso serviu inclusive para otimizar o código do método, bastando referenciar o uso de get_id como você pode observar acima.

Page_Template::get_permalink( 'pg-about.php' );

Recuperar objeto $post de uma Page Template

Além do identificador e da URL do modelo, você também pode precisar de mais informações sobre a página de um certo template. Sem grandes mudanças e seguindo a lógica da captura da URL, você pode estruturar um método para captura das demais informações da página com:

public static function get_object( $template ) {
    $obj = '#';
    $page_id = self::get_id( $template );
    if ( $page_id )
        $obj = get_post( $page_id );
    return $obj;	
}

Assim como abordei na captura dos ID’s, se você quer atribuir um mesmo modelo a mais de uma página será preciso fazer algumas pequenas modificações em seu código.

public static function get_object( $template, $slug=null )
{
    $pages = get_posts(
        array(
            'post_type'     => 'page',
            'posts_per_page'=> -1,
            'meta_key'      => '_wp_page_template',
            'meta_value'    => $template
        )
    );

    $results = count( $pages );
    if ( is_array( $pages ) && $results ) {
        if ( ( $results > 1 ) && $slug )
            return get_page_by_path( $slug );
        else
            return array_shift( $pages );
    }
    return false;
}

Acrescentei um novo parâmetro ao método get_object que receberá o slug da página. Caso você atribui o modelo de página pg-about.php para as páginas Apresentação e Quem Somos, caso queira obter o objeto $post dessa última você utilizará:

Page_Template::get_object( 'pg-about.php', 'quem-somos' );

Essa variação de get_object retornará a página mais recente, pois assim está definido o padrão de funcionamento da função get_posts. Caso queira mudar esse comportamento, acrescente as definições que desejar para order e orderby no array parâmetro dessa mesma função.

A partir do ID, permalink e também do objeto $post de uma página com modelo atribuído, você também poderá se aprofundar e capturar a imagem destacada, campos personalizados, página mãe, páginas filhas e toda a variação de gerenciamento de posts que o WordPress oferece sem grandes dificuldades.

Clique aqui para fazer o download da classe Page_Template