Este é um curso que vai do básico ao avançado sobre como criar tema WordPress. Você vai entender a estrutura de arquivos, e conhecer várias funções do WP.

Provavelmente você já deve ter visto milhares de sites WordPress com Perfil do autor abaixo do post, onde aparece uma pequena biografia, seus links para redes sociais, sua foto e o link de sua página.

Nesse artigo você vai aprender a fazer exatamente isso.

Adicionando os campos extras no perfil

Antes de qualquer coisa, vamos adicionar campos de perfil para as redes sociais do autor, mais especificamente, Twitter, Facebook e Google+.

Eu já expliquei como fazer isso no último tutorial sobre “Campos extras no perfil do usuário WordPress“, todavia, adicione o seguinte no seu functions.php.

/*-----------------------------------------------------------------------------*
  Novos campos de contato
*-----------------------------------------------------------------------------*/

if ( ! function_exists('tutsup_new_contact_fields') ) {

    function tutsup_new_contact_fields( $contact_fields ) {
        // Twitter
        $contact_fields['twitter'] = 'Twitter';
        
        // Facebbok
        $contact_fields['facebook'] = 'Facebook';
        
        // Google+
        $contact_fields['googleplus'] = 'Google+';

        return $contact_fields;
    } // tutsup_new_contact_fields
    
    add_filter('user_contactmethods', 'tutsup_new_contact_fields', 10, 1);
    
} // function_exists

Agora acesse seu painel administrativo (seu perfil) e preencha os campos com os valores que preferir.

Criando a função

Ao invés de termos que escrever todo o código diretamente nos arquivos de template toda vez que for necessário, vamos criar uma função dentro do arquivo functions.php e depois executaremos essa função.

Adicione o seguinte:

<?php
/*-----------------------------------------------------------------------------*
  Área do autor
*-----------------------------------------------------------------------------*/

if ( ! function_exists('tutsup_author_area') ) {

    function tutsup_author_area() {
        
        // Apenas apresentaremos a área do autor em posts na íntegra
        if ( is_single() ):
            $author_id = get_the_author_meta( 'ID' );
?>
            
            <!-- Área do autor -->
            <div class="tp-author-area clearfix">
            
                <!-- Conteúdo interno da área do autor -->
                <div class="tp-inner-author-area">
                    
                    <!-- Gravatar -->
                    <div class="tp-author-gravatar">
                    
                        <a class="tp-author-link" href="<?php echo esc_url( get_author_posts_url( $author_id ) ); ?>">
                            <?php echo get_avatar( get_the_author_meta( 'user_email' ), 150 ); ?>
                        </a>
                    
                    </div> <!-- tp-author-gravatar -->
                    
                    <!-- Texto sobre o autor -->
                    <p class="tp-about-autor-text">
                        <?php _e('Sobre o autor', 'tutsup'); ?>
                    </p>
                    
                    <!-- Nome e link do autor -->
                    <h3 class="tp-about-autor-heading">
                        <a href="<?php echo get_author_posts_url( $author_id );?>">
                            <?php echo get_the_author(); ?>
                        </a>
                    </h3>
                    
                    <!-- Descrição do autor -->
                    <div class="tp-author-info">
                    
                        <?php the_author_meta( 'description' ); ?>
                        
                        <!-- Links sociais -->
                        <p class="tp-social-links clearfix">	
                        
                        <?php if ( get_the_author_meta( 'facebook', $author_id ) ): ?>
                            <a class="tp-author-social-link" href="<?php 
                                echo get_the_author_meta( 'facebook', $author_id ); 
                            ?>">Facebook</a>  
                        <?php endif;?>
                        
                        <?php if ( get_the_author_meta( 'googleplus', $author_id ) ): ?>
                            <a class="tp-author-social-link" href="<?php 
                                echo get_the_author_meta( 'googleplus', $author_id ); 
                            ?>?rel=author" rel="author">Google+</a> 
                        <?php endif;?>
                        
                        <?php if ( get_the_author_meta( 'twitter', $author_id ) ): ?>
                            <a class="tp-author-social-link" href="<?php 
                                echo get_the_author_meta( 'twitter', $author_id  ); 
                            ?>">Twitter</a>
                        <?php endif;?>
                    
                        </p>
                        
                    </div> <!-- tp-author-info -->
                    
                </div> <!-- tp-inner-author-area -->
            </div> <!-- tp-author-area -->
        
        <?php endif; // is_single() ?>
<?php
    } // tutsup_author_area
} // function_exists
?>

Pronto, agora podemos chamar a função dentro dos nossos arquivos de modelo.

Executando a função

Abra um arquivo de template que contenha o loop do WordPress e adicione o seguinte:

<?php tutsup_author_area();?>

Só isso é suficiente para os dados serem apresentados na tela (sem nenhum estilo configurado).

Por exemplo, estou utilizando o tema TwentyFourteen (padrão do WordPress). Nele, basta adicionar o código acima ao final do arquivo “content.php“.

Adicionando o estilo CSS (style.css)

Agora adicione o seguinte no arquivo “style.css”:

.clearfix:after {
    content: '.';
    width: 100%;
    display: block;
    clear: both;
    height: 0;
    line-height: 0;
    visibility: hidden;
    overflow: hidden;
}
.tp-author-area{
    padding: 15px 0;
    margin: 0;
}
.tp-inner-author-area{
    /* Para ajustar ao twentyfourteen - edite conforme seu tema*/
    max-width: 478px;
    border-top: 1px solid #eee;
    padding: 15px 0;
    margin: 0 auto;
    padding: 10px;
}

.tp-author-area .tp-author-gravatar {
    float: left;
    margin: 0 15px 15px 0;
    width: 100px;
    height: 100px;
}
.tp-author-area .tp-author-gravatar img {
    border-radius: 50%;
    max-width: 100%;
    height: auto;
}
.tp-author-link{}
.tp-author-area .tp-about-autor-text, .tp-author-area .tp-about-autor-heading{
    margin: 0;
    padding: 0;
    text-transform: uppercase;
}
.tp-author-area .tp-about-autor-text {
    margin-bottom: 5px;
}
.tp-author-area .tp-about-autor-heading {
    margin: 10px 0 20px 0;
    clear: none;
    font-size: 30px;
}
.tp-author-info{
    clear: both;
}
.tp-author-area .tp-social-links{
    margin: 10px 0;
}
.tp-author-area .tp-author-social-link{
    color: #fff;
    padding: 2px 5px;
    background: #24890d;
}
.tp-author-area .tp-author-social-link:hover{
    color: #fff;
}

Isso é suficiente para gerar o seguinte:

Perfil do autor abaixo do post no WordPress

Perfil do autor abaixo do post no WordPress

Você pode estilizar com CSS conforme preferir.

Concluindo

Você pode utilizar a função tutsup_author_area() no local onde achar melhor dentro dos seus loops, você pode até mesmo executar essa função fora do loop com o ID do autor se preferir.

Em caso de dúvidas, basta comentar.

Múltiplos loops no WordPress podem ser muito úteis para desenvolvedores. Com eles é possível fazer praticamente tudo o que você desejar com o conteúdo do site que você estiver criando, como exibir últimos posts de uma categoria, criar um slider com os posts fixos (sticky), criar widgets dos posts mais comentados, enfim, qualquer coisa…

Neste artigo você vai aprender a criar múltiplos loops na mesma página mantendo o loop padrão do WordPress intacto.

Antes de iniciarmos, se você não tiver afinidade com a criação de temas para WordPress, recomendo a leitura do nosso artigo PHP, HTML e CSS em temas WordPress, nele falamos bastante sobre várias coisas relacionadas com desenvolvimento no CMS.

O loop padrão do WordPress

Qualquer tema WordPress tem pelo menos um loop padrão, já que o mesmo é responsável por controlar todo o conteúdo do site. Não é possível que eu indique qual arquivo contém o loop, porque isso vai depender do desenvolvedor daquele tema. Normalmente, os loops do WordPress ficam em arquivos separados e são incluídos nos arquivos de modelo utilizando a template tag get_template_part.

O loop padrão do WordPress começa com:

<?php if ( have_posts() ): ?> 
    <?php while ( have_posts() ) : the_post(); ?>

E termina com:

    <?php endwhile; ?>
<?php endif; ?>

A primeira linha de código verifica se existem posts a serem exibidos. Caso positivo, um laço while é iniciado para exibir todo o conteúdo. O número de artigos exibidos será o mesmo que está configurado nas configurações do seu WordPress pela área administrativa.

Dentro do loop você pode utilizar dezenas de template tags que servem para exibir o conteúdo desejado.

Veja um exemplo bem simples:

<?php if ( have_posts() ): ?> 
    <?php while ( have_posts() ) : the_post(); ?>
    
        <!-- As template tags virão abaixo -->
        <?php the_title();?><br>
        <?php the_content();?><br>
        
    <?php endwhile; ?>
<?php endif; ?>

No exemplo acima utilizei duas template tags: the_title e the_content. Sendo uma para exibir o título do conteúdo e a outra para exibir o conteúdo do artigo.

Este é um exemplo simples, mas quando você começa a misturar as template tags com as conditional tags, isso pode ficar bem confuso.

Observação: Existem template tags que só podem ser utilizadas dentro do loop, isso é descrito no WordPress Codex.

Criando mais de um loop

Existem várias maneiras para criar loops no WordPress, você pode até modificar a consulta principal do site utilizando query_posts ou pre_get_posts, mas este não será nosso caso.

Quando você altera a consulta padrão do WordPress, pode ser que você atrapalhe o bom funcionamento das coisas se não souber exatamente o que está fazendo. Por outro lado, você pode utilizar WP_Query para gerar uma nova consulta sem gerar conflito com a consulta principal.

A classe WP_Query suporta milhares de argumentos que vão determinar o que deverá ser exibido. Por exemplo, suponhamos que eu queira exibir apenas posts fixos em um loop separado:

<?php
$nova_consulta = new WP_Query( 
    array( 
        'post__in' => get_option('sticky_posts'),
    ) 
);
?>

<?php if ( $nova_consulta->have_posts() ): ?>
    <?php while ( $nova_consulta->have_posts() ): ?>
        <?php $nova_consulta->the_post(); ?>
        <?php the_title();?><br>
    <?php endwhile; ?>
<?php endif; ?>

<?php wp_reset_postdata(); ?>

Perceba que ao invés de chamar a função have_posts() e the_post() diretamente, agora eu as chamo diretamente do novo objeto que criei da classe WP_Query, com isso não afeto o conteúdo do loop principal.

Por exemplo, vamos pegar o loop principal que criei anteriormente, mais o código acima juntos:

<?php
$nova_consulta = new WP_Query( 
    array( 
        'post__in' => get_option('sticky_posts'),
    ) 
);
?>

<?php if ( $nova_consulta->have_posts() ): ?>
    <?php while ( $nova_consulta->have_posts() ): ?>
        <?php $nova_consulta->the_post(); ?>
        <?php the_title();?><br>
    <?php endwhile; ?>
<?php endif; ?>

<?php wp_reset_postdata(); ?>

<?php if ( have_posts() ): ?> 
    <?php while ( have_posts() ) : the_post(); ?>
    
        <!-- As template tags virão abaixo -->
        <?php the_title();?><br>
        <?php the_content();?><br>
        
    <?php endwhile; ?>
<?php endif; ?>

Agora eu tenho dois loops dentro da mesma página; o primeiro exibe apenas os posts fixos (sticky); o segundo exibe o conteúdo padrão do site.

Um problema que você pode encontrar com isso, é que os posts fixos serão exibidos nas duas consultas. Para resolver o problema, você pode gerar um array, na primeira consulta, que receberá os IDs dos posts já exibidos. Na segunda consulta você só vai precisar conferir se o ID do post que será exibido não está naquele array.

Fica assim o código:

<?php
// Array que vai receber os posts que não quero repetir
$nao_repetir = array();

$nova_consulta = new WP_Query( 
    array( 
        'post__in' => get_option('sticky_posts'),
    ) 
);
?>

<?php if ( $nova_consulta->have_posts() ): ?>
    <?php while ( $nova_consulta->have_posts() ): ?>
    
        <?php $nova_consulta->the_post(); ?>
        
        <!-- Preenche o array -->
        <?php $nao_repetir[] = $post->ID; ?>
        
        <?php the_title();?><br>
        
    <?php endwhile; ?>
<?php endif; ?>

<?php wp_reset_postdata(); ?>

<br><br>

<?php if ( have_posts() ): ?> 
    <?php while ( have_posts() ) : the_post(); ?>
        
        <!-- Verifica o ID do post -->
        <?php if ( in_array( $post->ID, $nao_repetir ) ) continue; ?>

        <!-- As template tags virão abaixo -->
        <?php the_title();?><br>
        
    <?php endwhile; ?>
<?php endif; ?>

As partes importantes aqui são as seguintes:

<?php
...
$nao_repetir = array();
...
// Primeiro loop
<?php $nao_repetir[] = $post->ID; ?>
...
// Segundo loop
<?php if ( in_array( $post->ID, $nao_repetir ) ) continue; ?>

Ou seja: no primeiro loop preenchemos o array que contém os IDs dos posts que não queremos repetir; no segundo loop verificamos se o ID do post que será exibido está no array. Se estiver, a palavra chave continue fará com que o laço while pule para a próxima volta (para o próximo post) sem exibir nada.

Vamos incluir mais um loop, porém agora vamos exibir o seguinte:

  • Primeiro loop: Apenas posts fixos;
  • Segundo loop: Posts da categoria de ID 20;
  • Terceiro loop: Padrão (excluindo posts já exibidos);

Veja como fica:

<?php
$segunda_consulta = new WP_Query( 
    array( 
        'cat'            => 20, // Apenas posts da categoria 20 
        'posts_per_page' => 5,    // Apenas 5 posts
    ) 
);
?>

<?php if ( $segunda_consulta->have_posts() ): ?>
    <?php while ( $segunda_consulta->have_posts() ): ?>
    
        <?php $segunda_consulta->the_post(); ?>
        
        <!-- Preenche o array -->
        <?php $nao_repetir[] = $post->ID; ?>
        
        <?php the_title();?><br>
        
    <?php endwhile; ?>
<?php endif; ?>

<?php wp_reset_postdata(); ?>

Agora tudo junto:

<?php
// Array que vai receber os posts que não quero repetir
$nao_repetir = array();

$nova_consulta = new WP_Query( 
    array( 
        'post__in' => get_option('sticky_posts'),
    ) 
);
?>

<?php if ( $nova_consulta->have_posts() ): ?>
    <?php while ( $nova_consulta->have_posts() ): ?>
    
        <?php $nova_consulta->the_post(); ?>
        
        <!-- Preenche o array -->
        <?php $nao_repetir[] = $post->ID; ?>
        
        <?php the_title();?><br>
        
    <?php endwhile; ?>
<?php endif; ?>

<?php wp_reset_postdata(); ?>

<br><br>

<?php
$segunda_consulta = new WP_Query( 
    array( 
        'cat'            => '20', // Apenas posts da categoria 20 
        'posts_per_page' => 5,    // Apenas 5 posts
    ) 
);
?>

<?php if ( $segunda_consulta->have_posts() ): ?>
    <?php while ( $segunda_consulta->have_posts() ): ?>
    
        <?php $segunda_consulta->the_post(); ?>
        
        <!-- Preenche o array -->
        <?php $nao_repetir[] = $post->ID; ?>
        
        <?php the_title();?><br>
        
    <?php endwhile; ?>
<?php endif; ?>

<?php wp_reset_postdata(); ?>

<br><br>

<?php if ( have_posts() ): ?> 
    <?php while ( have_posts() ) : the_post(); ?>
        
        <!-- Verifica o ID do post -->
        <?php if ( in_array( $post->ID, $nao_repetir ) ) continue; ?>

        <!-- As template tags virão abaixo -->
        <?php the_title();?><br>
        
    <?php endwhile; ?>
<?php endif; ?>

Sei que é bastante código e pode assustar, mas é bem simples.

Uma observação importante: Não se esqueça de utilizar wp_reset_postdata() para restaurar a variável global $post após cada loop secundário.

Concluindo

Trabalhar com vários loops no WordPress não é complicado, porém, exige que você tenha noção de programação. Eles irão aumentar o número de consultas na base de dados, e, se não criados com perfeição, podem atrapalhar o loop principal, que é de onde vem o seu ganha pão.

O WordPress codex está cheio de exemplos e dicas, não deixe de conferir.

Em caso de dúvidas, não hesite em comentar!

Se você seguiu nosso tutorial detalhando “Como criar um tema WordPress“, provavelmente já deve ter algo pronto e funcionando em seu computador. Mas e agora? Como mostrar seu tema para o mundo e talvez até começar a trabalhar com desenvolvimento de temas para o CMS?

O melhor local para criar um showcase dos temas que você desenvolve é, sem dúvidas, o diretório de tema do WordPress. Lá você vai encontrar milhares de temas gratuitos em vários formatos diferentes, existe um tema para cada tipo de gosto.

Porém, não é apenas criar seu tema, enviar o código e esperar a fama. Você deve seguir algumas regras antes de qualquer coisa.

Neste tutorial vou detalhar o que fazer para criar um tema no padrão de todos os outros temas do WordPress. Você poderá enviar tudo o que você criar para o diretório de temas do CMS, além de garantir que seu código seja criado no padrão e sem erros.

Revisão de tema WordPress

Siga os passos abaixo para revisar seu tema.

WP_DEBUG

A primeira coisa que você deve fazer para verificar se seu tema está no padrão e não contém erros, é modificar a constante WP_DEBUG no seu wp-config.php. Por padrão, essa constante tem o valor false, e ela previne que o WordPress mostre os erros do PHP.

Para ativar o modo debug, você precisa modificar seu valor para true.

define('WP_DEBUG', true);

Agora você vai ver qualquer erro que seu código apresentar.

Unidade de testes

Em seguida, será necessário adicionar conteúdo ao seu tema, como artigos, categorias, usuários, comentários e coisas do tipo. Felizmente, você não precisa fazer isso manualmente, basta baixar a unidade de testes de tema e importar para seu WordPress.

Se não sabe como fazer isso, aqui vai:

  1. Baixe a unidade de testes;
  2. Acesse sua área administrativa (wp-admin);
  3. Acesse “Ferramentas” – “Importar”;
  4. Escolha “WordPress”;
  5. Selecione a unidade de testes e faça o Upload;
  6. Opcional: Tente marcar a caixa para baixar as imagens (nem sempre da certo, mas tente)

Com isso você terá uma unidade de testes robusta, com todas as tags HTML, artigos com imagens, comentários e tudo mais.

Theme-Check

Se você acha que seu código está em perfeitas condições, provavelmente este plugin vai lhe mostrar o contrário.

Theme-Check é um plugin que faz um review no seu tema procurando por qualquer coisa que não esteja no padrão. Ele vai mostrar onde existem erros, qual arquivo o erro foi apresentado, e a possível solução.

Não é possível enviar temas para o diretório do WordPress se ele tiver qualquer aviso de “Required” ou “Warning”.

Theme-Check

Theme-Check

Padrão de codificação do WordPress

Apesar de termos falado sobre tudo isso aqui no Tutsup, é obrigatório que você siga os padrões de codificação do WordPress em todas as partes do seu código.

Caso tenha perdido, segue o link para o artigo:

Mais detalhes sobre tema WordPress

Além de tudo o que foi descrito anteriormente, não deixe de ler o Theme Review do Codex. Além disso, se você tiver perdido qualquer informação sobre temas WordPress, veja todos os artigos que criamos até agora:

Se você seguir todas as dicas acima, com certeza se dará bem no desenvolvimento de temas para WordPress.

Concluindo

O Tutsup oferece serviços e informativos sobre a maioria dos assuntos relacionados com programação em PHP, JavaScript, HTML, CSS. Também oferecemos milhares de tutoriais para WordPress, além de alguns temas e plugins gratuitos.

Mas também oferecemos um serviço exclusivo para a criação de temas WordPress personalizados. Caso tenha interesse, entre em contato.

Traduzir um plugin ou tema WordPress que você cria é essencial para que você possa globalizar todo o conteúdo que você desenvolve, principalmente se você deseja utilizar a hospedagem oficial do WordPress para lançar seu conteúdo.

Por exemplo, é normal que criemos todo o conteúdo que desenvolvemos em inglês (que é um idioma global) e depois traduzir tudo para  português (que é nosso idioma nativo). Isso vai atrair mais desenvolvedores para participar e aprimorar seus projetos, e principalmente, lhe dará maior visibilidade, já que qualquer um que domine o inglês ou o português poderá utilizar qualquer tema ou plugin que você crie.

No WordPress é bastante simples fazer a tradução de qualquer conteúdo que você crie, você só precisa das ferramentas certas e conhecimento para utilizá-las.

Neste tutorial vou detalhar como faço para traduzir qualquer tema ou plugin que crio para o WordPress.

Talvez eu faça algo um pouco diferente de tudo o que é apresentado em tutoriais do próprio Codex, mas é funcional e prático, e nunca tive problemas com a minha tradução.

Download necessário

Para traduzir um plugin ou tema WordPress, vamos precisar de um programa gratuito chamado Poedit:

É necessário que você baixe e instale o mesmo em seu computador para continuar a ler este tutorial.

Pasta de arquivos

Dentro da pasta do seu plugin ou tema, crie uma pasta chamada “languages“.

Pasta languages

Pasta languages

Utilize o bloco de notas ou seu editor de textos favorito (como o Notepad++) para criar um arquivo com o código do idioma que você deseja traduzir. Este arquivo deverá ter a extensão .po.

Por exemplo, para traduzir um tema para português do Brasil, o arquivo deverá se chamar pt_BR.po; para inglês dos Estados Unidos, en_US.po; português de portugal, pt_PT.po; e assim por diante.

No meu caso, vou criar um arquivo chamado pt_BR.po.

Dentro desse arquivo, adicione o seguinte cabeçalho:

# Copyright (C) 2014 the WordPress team
# This file is distributed under the GNU General Public License v2 or later.
# Editado por todoespacoonline.com/w
msgid ""
msgstr ""
"Project-Id-Version: Tutsup 1.0n"
"Report-Msgid-Bugs-To: http://www.todoespacoonline.com/w/contato/n"
"POT-Creation-Date: 2014-09-21 17:19:47+00:00n"
"MIME-Version: 1.0n"
"Content-Type: text/plain; charset=UTF-8n"
"Content-Transfer-Encoding: 8bitn"
"PO-Revision-Date: 2014-09-21 17:33-0300n"
"Last-Translator: Luiz Otavio Miranda <[email protected]/w>n"
"Language-Team: Luiz Otávio Miranda <[email protected]/w>n"
"Language: pt_BRn"
"X-Generator: Poedit 1.6.7n"

No trecho acima você vai precisar editar o seguinte:

  • “Project-Id-Version: SEU TEMA/PLUGIN E A VERSÃOn”
  • “Report-Msgid-Bugs-To: URL PARA REPORTAR BUGSn”
  • “POT-Creation-Date: DATA DA CRIAÇÃOn”
  • “Last-Translator: SEU NOME <email>n”
  • “Language-Team: EQUIPE <email>n”
  • “Language: CÓDIGO DO IDIOMAn”

Agora pule uma linha e adicione o seguinte:

#: arquivo.php:linha
msgid "Frase em inglês"
msgstr "Tradução em português"

Por exemplo:

#: index.php:10
msgid "My first translation"
msgstr "Minha primeira tradução"

Faça isso para cada frase que você tiver que traduzir em seu tema. Veja outro exemplo mais completo:

# Copyright (C) 2014 the WordPress team
# This file is distributed under the GNU General Public License v2 or later.
# Editado por todoespacoonline.com/w
msgid ""
msgstr ""
"Project-Id-Version: Tutsupn"
"Report-Msgid-Bugs-To: http://www.todoespacoonline.com/w/contato/n"
"POT-Creation-Date: 2014-09-21 17:19:47+00:00n"
"MIME-Version: 1.0n"
"Content-Type: text/plain; charset=UTF-8n"
"Content-Transfer-Encoding: 8bitn"
"PO-Revision-Date: 2014-09-21 17:33-0300n"
"Last-Translator: Luiz Otavio Miranda <[email protected]/w>n"
"Language-Team: Luiz Otávio Miranda <[email protected]/w>n"
"Language: pt_BRn"
"X-Generator: Poedit 1.6.7n"

#: index.php:10
msgid "My first translation"
msgstr "Minha primeira tradução"

#: loop-index.php:27
msgid "This phrase will be in english if the WordPress language is english"
msgstr "Essa frase vai aparecer em Inglês se o WordPress estiver em inglês"

 Carregando os arquivos de tradução

Agora você precisa indicar a pasta onde os arquivos de tradução estão presentes no seu tema ou plugin. Se for um tema, isso deve ser feito no início do arquivo functions.php; se for plugin, isso deve ser feito no início do arquivo principal do mesmo.

Para indicar o local e o nome do seu domínio de tradução, faça o seguinte:

// Carrega o idioma - tutsup
load_theme_textdomain('tutsup', get_template_directory() . '/languages' );

Pronto, mas ainda precisamos gerar os arquivos de tradução com o Poedit.

Gerando os arquivos de tradução

Para gerar os arquivos de tradução, abra o programa Poedit, clique em abrir e escolha o arquivo pt_BR.po.

Poedit

Poedit

Para finalizar, clique em “Salvar”.

Isso deverá modificar o arquivo pt_BR.po e criar outro arquivo chamado pt_BR.mo.

Arquivos de tradução

Arquivos de tradução

Pronto, agora é só utilizar.

Utilizando as traduções no seu tema ou plugin

Para utilizar qualquer tradução dentro do seu tema, você pode utilizar _e (exibe o valor) ou __ (salva o valor em uma variável), além de outras.

Por exemplo:

<?php _e('This phrase will be in english if the WordPress language is english', 'tutsup'); ?>

Isso deverá gerar o seguinte texto no meu tema:

Essa frase vai aparecer em Inglês se o WordPress estiver em inglês

Essa frase vai aparecer em Inglês se o WordPress estiver em inglês

Se o WordPress estiver configurado para “Português do Brasil”; se estiver em inglês, o texto apresentado será:

This phrase will be in english if the WordPress language is english

This phrase will be in english if the WordPress language is english

Configurando o idioma do WordPress

Para modificar o idioma padrão do seu WordPress, vá até a área administrativa (wp-admin), acesse “Configurações” – “Geral“, e modifique conforme preferir.

Idioma do WordPress

Idioma do WordPress

Simples assim!

Dúvidas?

É algo bem simples e direto, mas se ainda tiver dúvidas, não hesite em comentar.

Provavelmente você já deve ter visto que alguns temas trazem widgets personalizados para o WordPress, como artigos mais visualizados ou mais comentados, estatística de autores, membros da equipe e assim por diante.

Neste artigo você vai aprender a criar seu próprio Widget para seu tema WordPress utilizando classes PHP, que é o modo como os Widgets padrão do WordPress são criados.

Aulas anteriores

Este artigo faz parte de uma série de artigos sobre “Criar tema WordPress”, portanto, a leitura das aulas anteriores irá ajudar no seu entendimento do que você vai ler aqui.

  1. Estrutura de arquivos de um tema WordPress
  2. Arquivo functions.php de um tema WordPress
  3. PHP, HTML e CSS em temas WordPress
  4. Paginação em temas WordPress
  5. Formulário de pesquisa para temas WordPress
  6. Criando o template de comentários WordPress
  7. Menu em temas WordPress
  8. Page templates no WordPress (Modelos de página)
  9. Custom Post Types no WordPress
  10. Criando Meta Box em tema WordPress
  11. Página de opções em temas WordPress

Você poderá fazer o download de tudo o que foi descrito em todas as aulas (incluindo a que você lê agora) no final do artigo.

 Analisando um Widget Padrão do WordPress

Antes de criar um Widget Qualquer, uma boa prática é analisar o conteúdo de um Widget padrão do WordPress. Todos eles estão registrados no arquivo wp-includes/default-widgets.php.

Vamos analisar a classe WP_Widget_Recent_Posts, que é responsável por criar o Widget de posts mais recentes do WordPress.

/**
 * Recent_Posts widget class
 *
 * @since 2.8.0
 */
class WP_Widget_Recent_Posts extends WP_Widget {

	public function __construct() {
		$widget_ops = array('classname' => 'widget_recent_entries', 'description' => __( "Your site&#8217;s most recent Posts.") );
		parent::__construct('recent-posts', __('Recent Posts'), $widget_ops);
		$this->alt_option_name = 'widget_recent_entries';

		add_action( 'save_post', array($this, 'flush_widget_cache') );
		add_action( 'deleted_post', array($this, 'flush_widget_cache') );
		add_action( 'switch_theme', array($this, 'flush_widget_cache') );
	}

	public function widget($args, $instance) {
		$cache = array();
		if ( ! $this->is_preview() ) {
			$cache = wp_cache_get( 'widget_recent_posts', 'widget' );
		}

		if ( ! is_array( $cache ) ) {
			$cache = array();
		}

		if ( ! isset( $args['widget_id'] ) ) {
			$args['widget_id'] = $this->id;
		}

		if ( isset( $cache[ $args['widget_id'] ] ) ) {
			echo $cache[ $args['widget_id'] ];
			return;
		}

		ob_start();

		$title = ( ! empty( $instance['title'] ) ) ? $instance['title'] : __( 'Recent Posts' );

		/** This filter is documented in wp-includes/default-widgets.php */
		$title = apply_filters( 'widget_title', $title, $instance, $this->id_base );

		$number = ( ! empty( $instance['number'] ) ) ? absint( $instance['number'] ) : 5;
		if ( ! $number )
			$number = 5;
		$show_date = isset( $instance['show_date'] ) ? $instance['show_date'] : false;

		/**
		 * Filter the arguments for the Recent Posts widget.
		 *
		 * @since 3.4.0
		 *
		 * @see WP_Query::get_posts()
		 *
		 * @param array $args An array of arguments used to retrieve the recent posts.
		 */
		$r = new WP_Query( apply_filters( 'widget_posts_args', array(
			'posts_per_page'      => $number,
			'no_found_rows'       => true,
			'post_status'         => 'publish',
			'ignore_sticky_posts' => true
		) ) );

		if ($r->have_posts()) :
?>
		<?php echo $args['before_widget']; ?>
		<?php if ( $title ) {
			echo $args['before_title'] . $title . $args['after_title'];
		} ?>
		<ul>
		<?php while ( $r->have_posts() ) : $r->the_post(); ?>
			<li>
				<a href="<?php the_permalink(); ?>"><?php get_the_title() ? the_title() : the_ID(); ?></a>
			<?php if ( $show_date ) : ?>
				<span class="post-date"><?php echo get_the_date(); ?></span>
			<?php endif; ?>
			</li>
		<?php endwhile; ?>
		</ul>
		<?php echo $args['after_widget']; ?>
<?php
		// Reset the global $the_post as this query will have stomped on it
		wp_reset_postdata();

		endif;

		if ( ! $this->is_preview() ) {
			$cache[ $args['widget_id'] ] = ob_get_flush();
			wp_cache_set( 'widget_recent_posts', $cache, 'widget' );
		} else {
			ob_end_flush();
		}
	}

	public function update( $new_instance, $old_instance ) {
		$instance = $old_instance;
		$instance['title'] = strip_tags($new_instance['title']);
		$instance['number'] = (int) $new_instance['number'];
		$instance['show_date'] = isset( $new_instance['show_date'] ) ? (bool) $new_instance['show_date'] : false;
		$this->flush_widget_cache();

		$alloptions = wp_cache_get( 'alloptions', 'options' );
		if ( isset($alloptions['widget_recent_entries']) )
			delete_option('widget_recent_entries');

		return $instance;
	}

	public function flush_widget_cache() {
		wp_cache_delete('widget_recent_posts', 'widget');
	}

	public function form( $instance ) {
		$title     = isset( $instance['title'] ) ? esc_attr( $instance['title'] ) : '';
		$number    = isset( $instance['number'] ) ? absint( $instance['number'] ) : 5;
		$show_date = isset( $instance['show_date'] ) ? (bool) $instance['show_date'] : false;
?>
		<p><label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php _e( 'Title:' ); ?></label>
		<input class="widefat" id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" type="text" value="<?php echo $title; ?>" /></p>

		<p><label for="<?php echo $this->get_field_id( 'number' ); ?>"><?php _e( 'Number of posts to show:' ); ?></label>
		<input id="<?php echo $this->get_field_id( 'number' ); ?>" name="<?php echo $this->get_field_name( 'number' ); ?>" type="text" value="<?php echo $number; ?>" size="3" /></p>

		<p><input class="checkbox" type="checkbox" <?php checked( $show_date ); ?> id="<?php echo $this->get_field_id( 'show_date' ); ?>" name="<?php echo $this->get_field_name( 'show_date' ); ?>" />
		<label for="<?php echo $this->get_field_id( 'show_date' ); ?>"><?php _e( 'Display post date?' ); ?></label></p>
<?php
	}
}

É bastante código, mas ela faz praticamente tudo relacionado ao Widget de artigos mais recentes. Se fosse um Widget personalizado (seu), você só precisaria registrá-lo no functions.php e incluir esta classe.

Vamos criar um widget de artigos mais comentados baseados no código dessa classe.

 Criando um Widget de posts mais comentados

Primeiramente crie uma pasta chamada classes dentro da pasta do seu tema, dentro dela crie um arquivo chamado de class-widget-posts-mais-recentes.php.

Arquivo da nossa classe

Arquivo da nossa classe

Dentro desse arquivo, copie todo o código da classe que exibi anteriormente.

Conteúdo do arquivo da nossa classe

Conteúdo do arquivo da nossa classe

Agora vamos editar algumas partes.

Primeiramente o nome da classe WP_Widget_Recent_Posts para Tutsup_Widget_Posts_Mais_Comentados.

Agora, no construtor, vamos alterar várias opções, veja:

public function __construct() {
	$widget_ops = array(
		'classname' => 'tutsup_posts_mais_comentados', 
		'description' => __( "Posts mais comentados do seu blog.") 
	);
	
	parent::__construct(
		'tutsup-posts-mais-comentados', 
		__('Posts mais comentados'), 
		$widget_ops
	);
	
	$this->alt_option_name = 'tutsup_posts_mais_comentados';

	add_action( 'save_post', array($this, 'flush_widget_cache') );
	add_action( 'deleted_post', array($this, 'flush_widget_cache') );
	add_action( 'switch_theme', array($this, 'flush_widget_cache') );
}

Agora abra o arquivo functions.php e adicione o seguinte na ação widgets_init:

// Widget personalizado
load_template( get_template_directory() . '/classes/class-widget-posts-mais-recentes.php' );
register_widget('Tutsup_Widget_Posts_Mais_Comentados');

Veja como ficou a função completa da nossa ação:

// Registra as sidebars
function tutsup_sidebars()	{
	register_sidebar( array(
		'name'          => 'Sidebar',
		'id'            => 'sidebar-1',
		'description'   => 'Widgets da sidebar.',
		'before_widget' => '<div id="%1$s" class="widget %2$s">',
		'after_widget'  => '</div>',
		'before_title'  => '<h4 class="sidebar-widget-title">',
		'after_title'   => '</h4>',
	) );
	register_sidebar( array(
		'name'          => 'Rodapé',
		'id'            => 'footer-1',
		'description'   => 'Widgets do rodapé.',
		'before_widget' => '<div id="%1$s" class="widget %2$s">',
		'after_widget'  => '</div>',
		'before_title'  => '<h4 class="footer-widget-title">',
		'after_title'   => '</h4>',
	) );
	
	// Widget personalizado
	load_template( get_template_directory() . '/classes/class-widget-posts-mais-recentes.php' );
	register_widget('Tutsup_Widget_Posts_Mais_Comentados');
}
add_action( 'widgets_init', 'tutsup_sidebars' );

 Observação: Lembre-se que muitas funções acima já foram descritas em nosso artigo sobre o arquivo functions.php.

Neste momento, se você acessar a área administrativa, na opção “Temas” – “Widgets”, verá nosso novo Widget:

Nosso Widget

Nosso Widget

Insira o mesmo na sua barra lateral e salve para você ter a possibilidade de visualizar as alterações diretamente no seu tema.

Agora vamos modificar tudo que é relacionado a widget_recent_posts para tutsup_posts_mais_comentados você vai ter que fazer uma busca no seu editor de textos para programação.

E vamos modificar a consulta (WP_Query) para:

$r = new WP_Query( apply_filters( 'tutsup_posts_mais_comentados', array(
	'posts_per_page'      => $number,
	'no_found_rows'       => true,
	'post_status'         => 'publish',
	'ignore_sticky_posts' => false,
	'orderby'             => 'comment_count',
) ) );

Pronto, agora já temos nossos artigos ordenados por posts mais comentados.

Agora, se quiser modificar o loop, adicionar classes, tags HTML, imagens e coisas do tipo, sinta-se à vontade. O loop fica nessa parte:

		if ($r->have_posts()) :
?>
		<?php echo $args['before_widget']; ?>
		<?php if ( $title ) {
			echo $args['before_title'] . $title . $args['after_title'];
		} ?>
		<ul>
		<?php while ( $r->have_posts() ) : $r->the_post(); ?>
			<li>
				<a href="<?php the_permalink(); ?>"><?php get_the_title() ? the_title() : the_ID(); ?></a>
			<?php if ( $show_date ) : ?>
				<span class="post-date"><?php echo get_the_date(); ?></span>
			<?php endif; ?>
			</li>
		<?php endwhile; ?>
		</ul>

Por exemplo:

if ($r->have_posts()) :
?>
<?php echo $before_widget; ?>
<?php if ( $title ) echo $before_title . $title . $after_title; ?>
<ul class="tutsup-most-commented">
<?php while ( $r->have_posts() ) : $r->the_post(); ?>
	<li class="clearfix">
		<a href="<?php the_permalink(); ?>">
			<div class="tp-most-commented-number"><?php comments_number( 0, 1, '%' ); ?></div> 
			<?php get_the_post_thumbnail() ? the_post_thumbnail('tutsup-thumbnails') : null; ?>
			<?php get_the_title() ? the_title() : the_ID(); ?>
		</a>
	<?php if ( $show_date ) : ?>
		<span class="post-date"><?php echo get_the_date(); ?></span>
	<?php endif; ?>
	</li>
<?php endwhile; ?>
</ul>

Pronto, agora é só você ajeitar as coisas pelo CSS, veja:

.tutsup-most-commented li {
	position: relative;
	margin: 10px 0;
}

.tp-most-commented-number {
	position: absolute;
	top: 0;
	right: 0;
	padding: 2px 5px;
	background: #000;
	color: #fff;
}

.tutsup-most-commented .attachment-tutsup-thumbnails {
	width: 100%;
	height: auto;
}

Lembre-se isso é apenas um exemplo, você deve estilizar seu Widget de acordo com sua necessidade.

Veja uma imagem de exemplo:

Exemplo do Widget

Widget de posts mais comentados com imagens e contagem de comentários

Classe do Widget de posts mais comentados completa

Veja o código completo da nossa classe:

<?php
/**
 * Posts mais comentados
 */
class Tutsup_Widget_Posts_Mais_Comentados extends WP_Widget {

	public function __construct() {
		$widget_ops = array(
			'classname' => 'tutsup_posts_mais_comentados', 
			'description' => __( "Posts mais comentados do seu blog.") 
		);
		
		parent::__construct(
			'tutsup-posts-mais-comentados', 
			__('Posts mais comentados'), 
			$widget_ops
		);
		
		$this->alt_option_name = 'tutsup_posts_mais_comentados';

		add_action( 'save_post', array($this, 'flush_widget_cache') );
		add_action( 'deleted_post', array($this, 'flush_widget_cache') );
		add_action( 'switch_theme', array($this, 'flush_widget_cache') );
	}

	public function widget($args, $instance) {
		$cache = array();
		if ( ! $this->is_preview() ) {
			$cache = wp_cache_get( 'tutsup_posts_mais_comentados', 'widget' );
		}

		if ( ! is_array( $cache ) ) {
			$cache = array();
		}

		if ( ! isset( $args['widget_id'] ) ) {
			$args['widget_id'] = $this->id;
		}

		if ( isset( $cache[ $args['widget_id'] ] ) ) {
			echo $cache[ $args['widget_id'] ];
			return;
		}

		ob_start();

		$title = ( ! empty( $instance['title'] ) ) ? $instance['title'] : __( 'Recent Posts' );

		/** This filter is documented in wp-includes/default-widgets.php */
		$title = apply_filters( 'widget_title', $title, $instance, $this->id_base );

		$number = ( ! empty( $instance['number'] ) ) ? absint( $instance['number'] ) : 5;
		if ( ! $number )
			$number = 5;
		$show_date = isset( $instance['show_date'] ) ? $instance['show_date'] : false;

		/**
		 * Filter the arguments for the Recent Posts widget.
		 *
		 * @since 3.4.0
		 *
		 * @see WP_Query::get_posts()
		 *
		 * @param array $args An array of arguments used to retrieve the recent posts.
		 */
		$r = new WP_Query( apply_filters( 'tutsup_posts_mais_comentados', array(
			'posts_per_page'      => $number,
			'no_found_rows'       => true,
			'post_status'         => 'publish',
			'ignore_sticky_posts' => false,
			'orderby'             => 'comment_count',
		) ) );

		if ($r->have_posts()) :
?>
		<?php echo $before_widget; ?>
		<?php if ( $title ) echo $before_title . $title . $after_title; ?>
		<ul class="tutsup-most-commented">
		<?php while ( $r->have_posts() ) : $r->the_post(); ?>
			<li class="clearfix">
				<a href="<?php the_permalink(); ?>">
					<div class="tp-most-commented-number"><?php comments_number( 0, 1, '%' ); ?></div> 
					<?php get_the_post_thumbnail() ? the_post_thumbnail('tutsup-thumbnails') : null; ?>
					<?php get_the_title() ? the_title() : the_ID(); ?>
				</a>
			<?php if ( $show_date ) : ?>
				<span class="post-date"><?php echo get_the_date(); ?></span>
			<?php endif; ?>
			</li>
		<?php endwhile; ?>
		</ul>
		<?php echo $args['after_widget']; ?>
<?php
		// Reset the global $the_post as this query will have stomped on it
		wp_reset_postdata();

		endif;

		if ( ! $this->is_preview() ) {
			$cache[ $args['widget_id'] ] = ob_get_flush();
			wp_cache_set( 'tutsup_posts_mais_comentados', $cache, 'widget' );
		} else {
			ob_end_flush();
		}
	}

	public function update( $new_instance, $old_instance ) {
		$instance = $old_instance;
		$instance['title'] = strip_tags($new_instance['title']);
		$instance['number'] = (int) $new_instance['number'];
		$instance['show_date'] = isset( $new_instance['show_date'] ) ? (bool) $new_instance['show_date'] : false;
		$this->flush_widget_cache();

		$alloptions = wp_cache_get( 'alloptions', 'options' );
		if ( isset($alloptions['widget_recent_entries']) )
			delete_option('widget_recent_entries');

		return $instance;
	}

	public function flush_widget_cache() {
		wp_cache_delete('widget_recent_posts', 'widget');
	}

	public function form( $instance ) {
		$title     = isset( $instance['title'] ) ? esc_attr( $instance['title'] ) : '';
		$number    = isset( $instance['number'] ) ? absint( $instance['number'] ) : 5;
		$show_date = isset( $instance['show_date'] ) ? (bool) $instance['show_date'] : false;
?>
		<p><label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php _e( 'Title:' ); ?></label>
		<input class="widefat" id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" type="text" value="<?php echo $title; ?>" /></p>

		<p><label for="<?php echo $this->get_field_id( 'number' ); ?>"><?php _e( 'Number of posts to show:' ); ?></label>
		<input id="<?php echo $this->get_field_id( 'number' ); ?>" name="<?php echo $this->get_field_name( 'number' ); ?>" type="text" value="<?php echo $number; ?>" size="3" /></p>

		<p><input class="checkbox" type="checkbox" <?php checked( $show_date ); ?> id="<?php echo $this->get_field_id( 'show_date' ); ?>" name="<?php echo $this->get_field_name( 'show_date' ); ?>" />
		<label for="<?php echo $this->get_field_id( 'show_date' ); ?>"><?php _e( 'Display post date?' ); ?></label></p>
<?php
	}
}

Agora vamos ver um Widget e manipular o texto enviado pelo usuário.

Criando meu Widget para enviar dados de redes sociais

Na parte de cadastro de Widgets onde o usuário deverá enviar conteúdo, existem 3 etapas (métodos):

  1. form() – Cria o formulário que o usuário deve preencher;
  2. widget() – Gera o HTML que é visto no tema;
  3. update() – Salva ou atualiza os dados;

Vamos à criação:

Primeiramente crie um arquivo na pasta classes chamado de “class-widget-tutsup-social.php“.

Neste arquivo, crie uma classe que estenda WP_Widget:

class Tutsup_social extends WP_Widget {

}

Vamos adicionar todos os métodos agora:

// Construtor da classe
function __construct() {
	$widget_ops = array(
		'classname' => 
		'tutsup-social', 
		'description' => __( "Link para redes sociais.") 
	);
	
	// Construtor da classe mãe
	parent::__construct(
		'tutsup-social', 
		'Tutsup Social', 
		$widget_ops
	);
	
	$this->alt_option_name = 'tutsup-social';
	
	// Carrega os métodos
	add_action( 'save_post', array($this, 'flush_widget_cache') );
	add_action( 'deleted_post', array($this, 'flush_widget_cache') );
	add_action( 'switch_theme', array($this, 'flush_widget_cache') );
}

O construtor da classe carrega tudo o que precisamos, como nome do Widget e descrição, sua classe e assim por diante. Edite conforme precisar.

Agora o método widget:

// Cria o HTML do widget
function widget($args, $instance) {

	// Edite apenas no local indicado
	$cache = array();
	if ( ! $this->is_preview() ) {
		// Troque tutsup-social para o seu widget
		$cache = wp_cache_get( 'tutsup-social', 'widget' );
	}

	if ( ! is_array( $cache ) ) {
		$cache = array();
	}

	if ( ! isset( $args['widget_id'] ) ) {
		$args['widget_id'] = $this->id;
	}

	if ( isset( $cache[ $args['widget_id'] ] ) ) {
		echo $cache[ $args['widget_id'] ];
		return;
	}

	ob_start();
	extract($args);

	// Aqui temos as variáveis de todos os campos que existem no formulário
	// Edite conforme precisar
	$title = ( ! empty( $instance['title'] ) ) ? $instance['title'] : 'Tutsup Social';
	$twitter = ( ! empty( $instance['twitter'] ) ) ? $instance['twitter'] : null;
	$facebook = ( ! empty( $instance['facebook'] ) ) ? $instance['facebook'] : null;
	$youtube = ( ! empty( $instance['youtube'] ) ) ? $instance['youtube'] : null;

	/** Este filtro está documentado em wp-includes/default-widgets.php */
	$title = apply_filters( 'widget_title', $title, $instance, $this->id_base );
?>
	<?php echo $before_widget; // Não edite ?>

	<?php if ( $title ) echo $before_title . $title . $after_title; // Não edite ?>
	
	<?php
	/* 
	----------------------------------------------------------------------------
	DAQUI EM DIANTE COMEÇA A EXIBIÇÃO HTML
	----------------------------------------------------------------------------
	*/
	?>
	
	<?php echo '<div class="tutsup-social clearfix">'; ?>
	
	<?php if ( $twitter ): ?>
		<div class="classe-do-elemento clearfix">
			<a target="_blank"  href="<?php echo $twitter?>">Nosso Twitter</a><br>
		</div>
	<?php endif ?>
	
	<?php if ( $facebook ): ?>
		<div class="classe-do-elemento clearfix">
			<a target="_blank"  href="<?php echo $facebook?>">Nosso Facebook</a><br>
		</div>
	<?php endif ?>
	
	<?php if ( $youtube ): ?>
		<div class="classe-do-elemento clearfix">
			<a target="_blank"  href="<?php echo $youtube?>">Canal do Youtube</a><br>
		</div>
	<?php endif ?>
	
	<?php echo '</div>';?>
	
	<?php
	/* 
	----------------------------------------------------------------------------
	TERMINA A EXIBIÇÃO HTML
	----------------------------------------------------------------------------
	*/
	?>

	
	<?php echo $after_widget; ?>
<?php
	if ( ! $this->is_preview() ) {
		$cache[ $args['widget_id'] ] = ob_get_flush();
		// Edite tutsup-social para seu Widget
		wp_cache_set( 'tutsup-social', $cache, 'widget' );
	} else {
		ob_end_flush();
	}
}

Essa á a parte que é exibida no tema, deixei tudo comentado para que você compreenda como funciona.

Basicamente você só precisa configurar as variáveis e depois exibir os valores no seu HTML. É bem simples.

Agora vamos ver dois métodos, a update() e flush_widget_cache():

// Atualiza o Widget
function update( $new_instance, $old_instance ) {
	$instance = $old_instance;
	
	// Modifique os nomes para os nomes dos campos do seu formulário
	$instance['title'] = strip_tags($new_instance['title']);
	$instance['twitter'] = strip_tags($new_instance['twitter']);
	$instance['facebook'] = strip_tags($new_instance['facebook']);
	$instance['youtube'] = strip_tags($new_instance['youtube']);

	$this->flush_widget_cache();

	$alloptions = wp_cache_get( 'alloptions', 'options' );
	if ( isset($alloptions['widget_recent_entries']) )
		delete_option('tutsup-about');

	return $instance;
}

// Apaga o cache do widget
function flush_widget_cache() {
	wp_cache_delete('tutsup-about', 'widget');
}

Novamente, aqui você só precisa adicionar as variáveis do seu formulário. Também modifique wp_cache_delete para o nome do seu widget.

Vamos ver o método que cria o formulário – form():

// Cria o formulário para o usuário adicionar o widget
function form( $instance ) {
	// Aqui temos todos os campos do formulário em variáveis
	$title     = isset( $instance['title'] ) ? esc_attr( $instance['title'] ) : '';
	$twitter = isset( $instance['twitter'] ) ? esc_attr( $instance['twitter'] ) : '';
	$facebook = isset( $instance['facebook'] ) ? esc_attr( $instance['facebook'] ) : '';
	$youtube = isset( $instance['youtube'] ) ? esc_attr( $instance['youtube'] ) : '';
?>
	<!-- Os inputs a serem apresentados para o usuário na área adm -->
	<p><label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php _e( 'Title:' ); ?></label>
	<input class="widefat" id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" type="text" value="<?php echo $title; ?>" /></p>
	
	<p><label for="<?php echo $this->get_field_id( 'twitter' ); ?>"><?php _e( 'Twitter:' ); ?></label>
	<input class="widefat" id="<?php echo $this->get_field_id( 'twitter' ); ?>" name="<?php echo $this->get_field_name( 'twitter' ); ?>" type="text" value="<?php echo $twitter; ?>" /></p>
	
	<p><label for="<?php echo $this->get_field_id( 'facebook' ); ?>"><?php _e( 'Facebook:' ); ?></label>
	<input class="widefat" id="<?php echo $this->get_field_id( 'facebook' ); ?>" name="<?php echo $this->get_field_name( 'facebook' ); ?>" type="text" value="<?php echo $facebook; ?>" /></p>
	
	<p><label for="<?php echo $this->get_field_id( 'youtube' ); ?>"><?php _e( 'Youtube:' ); ?></label>
	<input class="widefat" id="<?php echo $this->get_field_id( 'youtube' ); ?>" name="<?php echo $this->get_field_name( 'youtube' ); ?>" type="text" value="<?php echo $youtube; ?>" /></p>
<?php
}

Mais uma vez, você só precisa editar o nome das variáveis e os campos de input.

Veja como ficou:

Nosso Widget

Nosso Widget

Veja a classe completa.

<?php
/**
 * Tutsup Social
 */
class Tutsup_social extends WP_Widget {
	
	// Construtor da classe
	function __construct() {
		$widget_ops = array(
			'classname' => 
			'tutsup-social', 
			'description' => __( "Link para redes sociais.") 
		);
		
		// Construtor da classe mãe
		parent::__construct(
			'tutsup-social', 
			'Tutsup Social', 
			$widget_ops
		);
		
		$this->alt_option_name = 'tutsup-social';
		
		// Carrega os métodos
		add_action( 'save_post', array($this, 'flush_widget_cache') );
		add_action( 'deleted_post', array($this, 'flush_widget_cache') );
		add_action( 'switch_theme', array($this, 'flush_widget_cache') );
	}

	// Cria o HTML do widget
	function widget($args, $instance) {

		// Edite apenas no local indicado
		$cache = array();
		if ( ! $this->is_preview() ) {
			// Troque tutsup-social para o seu widget
			$cache = wp_cache_get( 'tutsup-social', 'widget' );
		}

		if ( ! is_array( $cache ) ) {
			$cache = array();
		}

		if ( ! isset( $args['widget_id'] ) ) {
			$args['widget_id'] = $this->id;
		}

		if ( isset( $cache[ $args['widget_id'] ] ) ) {
			echo $cache[ $args['widget_id'] ];
			return;
		}

		ob_start();
		extract($args);

		// Aqui temos as variáveis de todos os campos que existem no formulário
		// Edite conforme precisar
		$title = ( ! empty( $instance['title'] ) ) ? $instance['title'] : 'Tutsup Social';
		$twitter = ( ! empty( $instance['twitter'] ) ) ? $instance['twitter'] : null;
		$facebook = ( ! empty( $instance['facebook'] ) ) ? $instance['facebook'] : null;
		$youtube = ( ! empty( $instance['youtube'] ) ) ? $instance['youtube'] : null;

		/** Este filtro está documentado em wp-includes/default-widgets.php */
		$title = apply_filters( 'widget_title', $title, $instance, $this->id_base );
	?>
		<?php echo $before_widget; // Não edite ?>

		<?php if ( $title ) echo $before_title . $title . $after_title; // Não edite ?>
		
		<?php
		/* 
		----------------------------------------------------------------------------
		DAQUI EM DIANTE COMEÇA A EXIBIÇÃO HTML
		----------------------------------------------------------------------------
		*/
		?>
		
		<?php echo '<div class="tutsup-social clearfix">'; ?>
		
		<?php if ( $twitter ): ?>
			<div class="classe-do-elemento clearfix">
				<a target="_blank"  href="<?php echo $twitter?>">Nosso Twitter</a><br>
			</div>
		<?php endif ?>
		
		<?php if ( $facebook ): ?>
			<div class="classe-do-elemento clearfix">
				<a target="_blank"  href="<?php echo $facebook?>">Nosso Facebook</a><br>
			</div>
		<?php endif ?>
		
		<?php if ( $youtube ): ?>
			<div class="classe-do-elemento clearfix">
				<a target="_blank"  href="<?php echo $youtube?>">Canal do Youtube</a><br>
			</div>
		<?php endif ?>
		
		<?php echo '</div>';?>
		
		<?php
		/* 
		----------------------------------------------------------------------------
		TERMINA A EXIBIÇÃO HTML
		----------------------------------------------------------------------------
		*/
		?>

		
		<?php echo $after_widget; ?>
	<?php
		if ( ! $this->is_preview() ) {
			$cache[ $args['widget_id'] ] = ob_get_flush();
			// Edite tutsup-social para seu Widget
			wp_cache_set( 'tutsup-social', $cache, 'widget' );
		} else {
			ob_end_flush();
		}
	}

	// Atualiza o Widget
	function update( $new_instance, $old_instance ) {
		$instance = $old_instance;
		
		// Modifique os nomes para os nomes dos campos do seu formulário
		$instance['title'] = strip_tags($new_instance['title']);
		$instance['twitter'] = strip_tags($new_instance['twitter']);
		$instance['facebook'] = strip_tags($new_instance['facebook']);
		$instance['youtube'] = strip_tags($new_instance['youtube']);

		$this->flush_widget_cache();

		$alloptions = wp_cache_get( 'alloptions', 'options' );
		if ( isset($alloptions['widget_recent_entries']) )
			delete_option('tutsup-about');

		return $instance;
	}

	// Apaga o cache do widget
	function flush_widget_cache() {
		// Modifique para o nome do seu widget
		wp_cache_delete('tutsup-social', 'widget');
	}

	// Cria o formulário para o usuário adicionar o widget
	function form( $instance ) {
		// Aqui temos todos os campos do formulário em variáveis
		$title     = isset( $instance['title'] ) ? esc_attr( $instance['title'] ) : '';
		$twitter = isset( $instance['twitter'] ) ? esc_attr( $instance['twitter'] ) : '';
		$facebook = isset( $instance['facebook'] ) ? esc_attr( $instance['facebook'] ) : '';
		$youtube = isset( $instance['youtube'] ) ? esc_attr( $instance['youtube'] ) : '';
	?>
		<!-- Os inputs a serem apresentados para o usuário na área adm -->
		<p><label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php _e( 'Title:' ); ?></label>
		<input class="widefat" id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" type="text" value="<?php echo $title; ?>" /></p>
		
		<p><label for="<?php echo $this->get_field_id( 'twitter' ); ?>"><?php _e( 'Twitter:' ); ?></label>
		<input class="widefat" id="<?php echo $this->get_field_id( 'twitter' ); ?>" name="<?php echo $this->get_field_name( 'twitter' ); ?>" type="text" value="<?php echo $twitter; ?>" /></p>
		
		<p><label for="<?php echo $this->get_field_id( 'facebook' ); ?>"><?php _e( 'Facebook:' ); ?></label>
		<input class="widefat" id="<?php echo $this->get_field_id( 'facebook' ); ?>" name="<?php echo $this->get_field_name( 'facebook' ); ?>" type="text" value="<?php echo $facebook; ?>" /></p>
		
		<p><label for="<?php echo $this->get_field_id( 'youtube' ); ?>"><?php _e( 'Youtube:' ); ?></label>
		<input class="widefat" id="<?php echo $this->get_field_id( 'youtube' ); ?>" name="<?php echo $this->get_field_name( 'youtube' ); ?>" type="text" value="<?php echo $youtube; ?>" /></p>
	<?php
	}
	
}

Agora você precisa editar seu arquivo functions.php para adicionar a classe e registrar o widget, veja:

load_template( get_template_directory() . '/classes/class-widget-tutsup-social.php' );
register_widget('Tutsup_social');

Veja como ficou nossa ação executado no widgets_init:

// Registra as sidebars
function tutsup_sidebars()	{
	register_sidebar( array(
		'name'          => 'Sidebar',
		'id'            => 'sidebar-1',
		'description'   => 'Widgets da sidebar.',
		'before_widget' => '<div id="%1$s" class="widget %2$s">',
		'after_widget'  => '</div>',
		'before_title'  => '<h4 class="sidebar-widget-title">',
		'after_title'   => '</h4>',
	) );
	register_sidebar( array(
		'name'          => 'Rodapé',
		'id'            => 'footer-1',
		'description'   => 'Widgets do rodapé.',
		'before_widget' => '<div id="%1$s" class="widget %2$s">',
		'after_widget'  => '</div>',
		'before_title'  => '<h4 class="footer-widget-title">',
		'after_title'   => '</h4>',
	) );
	
	// Widget personalizado
	load_template( get_template_directory() . '/classes/class-widget-posts-mais-recentes.php' );
	register_widget('Tutsup_Widget_Posts_Mais_Comentados');
	
	load_template( get_template_directory() . '/classes/class-widget-tutsup-social.php' );
	register_widget('Tutsup_social');
}
add_action( 'widgets_init', 'tutsup_sidebars' );

Agora temos dois widgets em nosso tema.

 Download

Caso queira baixar o nosso tema teste que estamos criando nessa série de tutoriais, acesse o link abaixo:

Tudo o que foi descrito nessa aula e nas aulas anteriores já está incluído no arquivo acima.

Concluindo

A melhor maneira para aprender a criar algo no WordPress, é visualizando coisas que já vêm com o CMS, como foi o nosso caso, onde criamos nossos Widgets baseados nas classes de Widgets padrão do WordPress. Isso também serve para plugins, temas e qualquer outra parte que deseja aprender.

Caso tenha dúvidas, pergunte nos comentários.

Todos os temas premium (pagos) do WordPress têm uma página de opções onde você pode alterar milhares de coisas no layout, desde cores de fundo até upload de imagens para logo e favicon.

Normalmente eles criam suas páginas utilizando suas próprias funções, scripts e HTML, porém, o WordPress nos proporciona milhares de opções para adicionar páginas de menu e funções de callback para configurar tudo da maneira que preferirmos.

Neste tutorial vamos configurar uma página de opções bem simples para você entender como isso funciona em temas WordPress. Após sua leitura, você será capaz de criar sua própria página de opções da maneira que preferir.

Observação: Apesar de estarmos criando a página de opções em um tema, isso funciona em plugins da mesma maneira.

Aulas anteriores

Este artigo faz parte de uma série de artigos sobre “Criar tema WordPress”, portanto, a leitura das aulas anteriores irá ajudar no seu entendimento do que você vai ler aqui.

  1. Estrutura de arquivos de um tema WordPress
  2. Arquivo functions.php de um tema WordPress
  3. PHP, HTML e CSS em temas WordPress
  4. Paginação em temas WordPress
  5. Formulário de pesquisa para temas WordPress
  6. Criando o template de comentários WordPress
  7. Menu em temas WordPress
  8. Page templates no WordPress (Modelos de página)
  9. Custom Post Types no WordPress
  10. Criando Meta Box em tema WordPress

Você poderá fazer o download de tudo o que foi descrito em todas as aulas (incluindo a que você lê agora) no final do artigo.

Alterando nosso functions.php

A primeira coisa que vamos fazer é alterar o nosso arquivo functions.php para adicionar o que vamos precisar.

Primeiramente, vamos garantir que quando um usuário ativar nosso tema, a página seja redirecionada para a página de opções que vamos criar.

// Assim que nosso tema for ativado, redireciona para a página de opções
if ( is_admin() && isset( $_GET['activated'] ) ) {
	header( 'Location: ' . admin_url() . 'themes.php?page=tutsup_opcoes_tema');
}

Agora vamos obter as opções da base de dados, não se preocupe se elas ainda não existem, isso não vai gerar erros:

// Opções do tema
$tutups_opcoes_tema = get_option( 'tutsup_opcoes_tema' );

Vamos criar uma função que verifica se uma chave existe em um array (isso é PHP puro) para verificar nossas opções:

// Função para verificar e retornar nossas opções
function tutsup_chk ( $array, $key ) {
	if ( isset( $array[$key] ) ) {
		return $array[$key];
	} else {
		return false;
	}
}

Agora vamos carregar um arquivo que ainda não existe, mas vamos criar posteriormente:

// Classe para carregar as opções
load_template( get_template_directory() . '/classes/class-tutsup-opcoes-tema.php' );

Se você entende de PHP, vai perceber que estamos incluindo um arquivo de classe que está dentro da pasta classes chamado class-tutsup-opcoes-tema.php.

Vamos criar este arquivo.

Criando a classe de opções

Antes que você continue, se você não entende de classes, tire um tempo para ler nossos tutoriais sobre PHP Orientado a objetos.

O primeiro passo será criar a pasta e o arquivo que precisamos, então crie uma pasta chamada “classes” e um arquivo PHP chamado class-tutsup-opcoes-tema.php.

Dentro desse arquivo, a primeira coisa que vamos fazer é verificar se a classe que vamos criar existe:

if ( ! class_exists('TutsupOpcoesTema') ) {

    // Nosso código virá aqui

}

Isso vai evitar erros caso alguém tenha tido a ideia de criar uma classe com o mesmo nome da nossa.

Agora vamos criar a classe:

class TutsupOpcoesTema
{
    // Nossos métodos e propriedades virão aqui
}

// Carrega a classe
$tutsup_opcoes_tema = new TutsupOpcoesTema();

Não adicionei nenhum método nem propriedade em nossa classe porque vou fazer isso por partes, ao final vou mostrar o arquivo completo.

Propriedade de opções

Nossa propriedade de opções irá receber as propriedades já configuradas em nosso tema, então vamos configurá-la sem nenhum valor por enquanto:

// As opções
protected $options;

 Método construtor

Em nosso construtor, vamos adicionar o seguinte:

/**
 * Construtor
 *
 * Carrega todas as funções.
 */
public function __construct () {

	// Variável de opções que está no functions.php
	global $tutups_opcoes_tema;
	
	// Configura as opções dentro da classe
	$this->options = $tutups_opcoes_tema;
		
	/* Essa classe só executa ações para a área administrativa */
	if ( is_admin() ) {
		
		// Carrega os scripts e styles necessários
		add_action( 
			'admin_enqueue_scripts', 
			array( $this, 'carrega_scripts' ) 
		);

		// Adiciona o menu de opções
		add_action('admin_menu', array( $this, 'adiciona_menu' ) );
		
		// Registra nossas opções
		add_action( 'admin_init', array( $this, 'registra_opcoes' ) );
	} // is_admin
	
} // __construct

Veja que nosso construtor configura nossas opções na propriedade que criamos anteriormente e adiciona um monte de ações, das quais ainda não criamos os métodos.

Vamos criar os métodos necessários abaixo.

Carrega scripts e styles na área administrativa

O WordPress tem milhares de coisas legais que vão nos ajudar a criar nossas opções, tais como “Media Uploader” (para upload de imagens) e “Color Picker” (Para escolher cores). Vamos adicionar os scripts e styles para todos eles.

/**
 * Carrega scripts e styles
 */
public function carrega_scripts() {

	// Caixa de upload de imagem
	wp_enqueue_script('media-upload');
	
	// Thickbox
	wp_enqueue_script('thickbox');
	wp_enqueue_style('thickbox');
	
	// Color picker (para cores)
	wp_enqueue_style( 'wp-color-picker' );
	
	// Nosso script
	wp_enqueue_script( 
		'admin_settings', 
		get_template_directory_uri() . '/js/admin-settings.js', 
		array('wp-color-picker'), 
		'1.0.0', 
		true 
	);
	
} // carrega_scripts

Em nossa última chamada, chamamos “Nosso script”, isso porque será necessário criar um script jQuery para utilizar tudo o que o WordPress oferece de bom.

Vamos aproveitar e criar este script.

Criando o script para nossa área administrativa

Crie uma pasta chamada “js” (se ela ainda não existir) e, dentro da mesma, um arquivo chamado admin-settings.js. Nele adicione o seguinte:

jQuery(function( $ ){
	$('.fundo').wpColorPicker();
});

Só isso, mais nada!

Criando o menu na área administrativa

Agora vamos criar a função que vai criar nosso menu:

/**
 * Função para adicionar o menu na área administrativa
 */
public function adiciona_menu() {

	// Creates a page for editing the theme options
	add_theme_page(
		'Opções do tema',            // Título da página
		'Opções do tema',            // Título do menu
		'edit_themes',               // Permissões
		'tutsup_opcoes_tema',        //	Slug do menu
		array( $this, 'admin_html' ) // Função de callback
	);
	
} // adiciona_menu

Agora você já deve estar vendo o menu dentro da opção de temas da sua área administrativa:

Opções do tema

Opções do tema

Veja que na função add_theme_page, existe uma opção de função de callback. Esse callback é o que vai exibir o HTML dentro da nossa página de opções.

Vamos criar esse método.

Callback para gerar o HTML

Veja como ficou nossa função de callback:

/**
 * Carrega a página HTML que será apresentada na área administrativa
 */
public function admin_html() {		
?>

<div class="wrap">

<form method="post" action="options.php">
	<?php
		settings_fields( 'tutsup_opcoes_tema' );
		do_settings_sections( 'tutsup_opcoes_tema' );
	?>

	<h3>Opções do tema</h3>
		
	Texto do rodapé:<br>
	<input class="regular-text" type="text" value="<?php 
	echo esc_attr( tutsup_chk( $this->options, 'rodape' ) );
	?>" name="tutsup_opcoes_tema[rodape]"><br><br>
		
	Cor de fundo:<br>
	<input class="fundo" type="text" value="<?php 
	echo esc_attr( tutsup_chk( $this->options, 'fundo' ) );
	?>" name="tutsup_opcoes_tema[fundo]"><br><br>

	<p>
		<?php submit_button(); ?>
	</p>
	
</form>
</div>

<?php

} // admin_html

Então temos dois inputs, um com uma opção de Texto do rodapé e outra com Cor de fundo. Porém, essa página ainda não faz nada, já que ainda não registramos nossa opção. Vamos fazer isso.

Registrando nossa opção

Para registrar nossa opção, vamos utilizar a função register_setting do WordPress, veja:

/**
 * Função para registrar nossas opções
 */
public function registra_opcoes() {

	register_setting( 
		'tutsup_opcoes_tema', 
		'tutsup_opcoes_tema', 
		array( $this, 'valida_campos' ) // Função de callback
	);
	
} // registra_opcoes

Veja, novamente, que temos mais um callback para criar, este irá validar nossos campos do formulário (caso necessário).

Vamos criar este último método.

Validando os campos

Vou validar apenas um campo para que você entenda como fazer, o restante é tudo igual:

// Callback para validar os campos enviados (se necessário)
public function valida_campos( $input ) {
	
	// Vamos validar apenas o fundo, só para você entender
	if( isset( $input['fundo'] ) ) {
		$input['fundo'] = sanitize_text_field( $input['fundo'] );
	}
	
	return $input;
	
} // valida_campos

Classe completa

Se você se perdeu em algum ponto do tutorial, veja como ficou nossa classe completa:

<?php
/**
 * Classe TutsupOpcoesTema - Carrega as opções do tema
 *
 * Este é um template básico para suas criações mais avançadas.
 */
 
// Verifica se a classe já existe
if ( ! class_exists('TutsupOpcoesTema') ) {

	// Cria a classe
	class TutsupOpcoesTema
	{
		// As opções
		protected $options;

		/**
		 * Construtor
		 *
		 * Carrega todas as funções.
		 */
		public function __construct () {
		
			// Variável de opções que está no functions.php
			global $tutups_opcoes_tema;
			
			// Configura as opções dentro da classe
			$this->options = $tutups_opcoes_tema;
				
			/* Essa classe só executa ações para a área administrativa */
			if ( is_admin() ) {
				
				// Carrega os scripts e styles necessários
				add_action( 
					'admin_enqueue_scripts', 
					array( $this, 'carrega_scripts' ) 
				);

				// Adiciona o menu de opções
				add_action('admin_menu', array( $this, 'adiciona_menu' ) );
				
				// Registra nossas opções
				add_action( 'admin_init', array( $this, 'registra_opcoes' ) );
			} // is_admin
			
		} // __construct
		
		/**
		 * Função para adicionar o menu na área administrativa
		 */
		public function adiciona_menu() {
		
			// Creates a page for editing the theme options
			add_theme_page(
				'Opções do tema',            // Título da página
				'Opções do tema',            // Título do menu
				'edit_themes',               // Permissões
				'tutsup_opcoes_tema',        //	Slug do menu
				array( $this, 'admin_html' ) // Função de callback
			);
			
		} // adiciona_menu
		
		/**
		 * Função para registrar nossas opções
		 */
		public function registra_opcoes() {
		
			register_setting( 
				'tutsup_opcoes_tema', 
				'tutsup_opcoes_tema', 
				array( $this, 'valida_campos' ) // Função de callback
			);
			
		} // registra_opcoes
		
		// Callback para validar os campos enviados (se necessário)
		public function valida_campos( $input ) {
			
			// Vamos validar apenas o fundo, só para você entender
			if( isset( $input['fundo'] ) ) {
				$input['fundo'] = sanitize_text_field( $input['fundo'] );
			}
			
			return $input;
			
		} // valida_campos
		
		/**
		 * Carrega a página HTML que será apresentada na área administrativa
		 */
		public function admin_html() {		
?>

<div class="wrap">

	<form method="post" action="options.php">
		<?php
			settings_fields( 'tutsup_opcoes_tema' );
			do_settings_sections( 'tutsup_opcoes_tema' );
		?>
		
		<h3>Opções do tema</h3>
			
		Texto do rodapé:<br>
		<input class="regular-text" type="text" value="<?php 
		echo esc_attr( tutsup_chk( $this->options, 'rodape' ) );
		?>" name="tutsup_opcoes_tema[rodape]"><br><br>
			
		Cor de fundo:<br>
		<input class="fundo" type="text" value="<?php 
		echo esc_attr( tutsup_chk( $this->options, 'fundo' ) );
		?>" name="tutsup_opcoes_tema[fundo]"><br><br>
		
		<p>
			<?php submit_button(); ?>
		</p>
	</form>
</div>

<?php

		} // admin_html
		
		/**
		 * Carrega scripts e styles
		 */
		public function carrega_scripts() {
		
			// Caixa de upload de imagem
			wp_enqueue_script('media-upload');
			
			// Thickbox
			wp_enqueue_script('thickbox');
			wp_enqueue_style('thickbox');
			
			// Color picker (para cores)
			wp_enqueue_style( 'wp-color-picker' );
			
			// Nosso script
			wp_enqueue_script( 
				'admin_settings', 
				get_template_directory_uri() . '/js/admin-settings.js', 
				array('wp-color-picker'), 
				'1.0.0', 
				true 
			);
			
		} // carrega_scripts
	
	} // Class TutsupOpcoesTema

	// Carrega a classe
	$tutsup_opcoes_tema = new TutsupOpcoesTema();
}

Se você quiser remover o HTML do meio da classe, basta criar um arquivo separado e fazer a inclusão com a função require do PHP.

Veja como ficou:

Página de opções em temas WordPress

Página de opções em temas WordPress

Obtendo as opções dentro do tema

Para acessar as opções e realizar as ações dentro do seu tema WordPress, basta fazer com que a variável $tutups_opcoes_tema seja global dentro do seu template file.

Por exemplo, vou exibir o texto no rodapé (footer.php), abra este arquivo e adicione o trecho de código abaixo na primeira linha:

<?php global $tutups_opcoes_tema; ?>

Agora escolha um local e adicione o seguinte:

<?php 
if ( tutsup_chk( $tutups_opcoes_tema, 'rodape' ) ) {
	echo tutsup_chk( $tutups_opcoes_tema, 'rodape');
} else {
	echo 'Copyright &copy; Tutsup 2014';
}
?>

Veja como ficou meu arquivo footer.php completo:

<?php global $tutups_opcoes_tema; ?>

<footer class="conteudo rodape padding-total">
	<div class="linha clearfix">
		<div class="colunas largura-total">
			<div class="conteudo-coluna margem-total">
				<?php 
				if ( tutsup_chk( $tutups_opcoes_tema, 'rodape' ) ) {
					echo tutsup_chk( $tutups_opcoes_tema, 'rodape');
				} else {
					echo 'Copyright &copy; Tutsup 2014';
				}
				?>
			</div>
		</div>
	</div>
</footer>

<!-- 
O restante do rodapé que virá dentro do body. 
Criado automaticamente pelo WordPress. 
-->
<?php wp_footer(); ?>

</div><!-- .pagina -->

<!-- Fecha o body -->
</body>

<!-- Fecha o HTML -->
</html>

 Modificando a cor de fundo do tema

Agora, abra seu arquivo header.php, faça nossa variável se tornar global, e adicione o trecho de código abaixo de wp_head().

<?php 
if ( tutsup_chk( $tutups_opcoes_tema, 'fundo' ) ) {
	echo '<style>';
	echo 'body{ background-color: ' . tutsup_chk( $tutups_opcoes_tema, 'fundo' ) . ';';
	echo '</style>';
}
?>

No trecho de código acima, estamos simplesmente verificando se a opção “fundo” existe e se tem algum valor; se sim, modificamos a cor de fundo do body utilizando seu valor.

Você poderia fazer isso utilizando um filtro em wp_head(), mas eu não quis complicar mais (já está bem avançado).

Veja como ficou meu header.php completo:

<?php global $tutups_opcoes_tema; ?>

<!DOCTYPE html>
<html class="no-js" <?php language_attributes(); ?>>

<head>
	<!-- O charset padrão -->
	<meta charset="<?php bloginfo('charset'); ?>">
	
	<!-- Necessário para layout responsivo -->
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	
	<!-- O título do blog -->
	<title><?php wp_title(''); ?></title>

	<!-- 
	O restante do cabeçalho que virá dentro da head. 
	Criado automaticamente pelo WordPress. 
	-->
	<?php wp_head(); ?>
	
	<?php 
	if ( tutsup_chk( $tutups_opcoes_tema, 'fundo' ) ) {
		echo '<style>';
		echo 'body{ background-color: ' . tutsup_chk( $tutups_opcoes_tema, 'fundo' ) . ';';
		echo '</style>';
	}
	?>
</head>

<!-- Início do body -->
<body <?php body_class(); ?>>

<div id="pagina" class="pagina"> <!-- .pagina -->

<header class="conteudo cabecalho padding-total">
	<div class="linha clearfix">
		<div class="colunas principal">
			<div class="conteudo-coluna margem-total">
				<h1> 
					<a href="<?php bloginfo('url'); ?>">
						<?php bloginfo('name'); ?> 
					</a>
				</h1>
			</div>
		</div>
		
		<div class="colunas lateral">
			<div class="conteudo-coluna margem-total">
				<div class="search-form">
					<?php get_search_form(); ?>
				</div>
			</div>
		</div>
	</div>
</header>

<?php
$header_menu_args = array(
	'theme_location'  => 'header',
	'menu'            => '',
	'container'       => 'nav',
	'container_class' => 'main-menu clearfix',
	'container_id'    => '',
	'menu_class'      => '',
	'menu_id'         => '',
	'echo'            => true,
	'fallback_cb'     => 'wp_page_menu',
	'before'          => '',
	'after'           => '',
	'link_before'     => '',
	'link_after'      => '',
	'items_wrap'      => '<ul id="%1$s" class="%2$s">%3$s</ul>',
	'depth'           => 0,
	'walker'          => ''
);

wp_nav_menu( $header_menu_args );
?>

Pronto, agora você tem uma página de opções simples e funcional.

Download

Caso queira baixar os arquivo criados nessa aula e aulas anteriores para testes, utilize o link abaixo:

Você vai precisar descompactar o arquivo dentro de wp-content/themes e ativar o tema para visualizar tudo.

Concluindo

Criar uma página de opções no WordPress não é tão simples quanto fazer outras coisa, é necessário que você entenda como funcionam as coisas antes de se aventurar. Tentei deixar tudo muito básico e direto nesse tutorial, porém, caso tenha dúvidas, basta perguntar nos comentários.

No WordPress existem milhares de maneiras de expandir a funcionalidade padrão do CMS, tais como Custom Fields (Campos personalizados) ou a utilização de Post Meta.

Os Custom Fields são mais maleáveis e aparecem na área de criar artigos. Seu problema está justamente na facilidade de adicionar conteúdo, pois caso o usuário não entenda o que fazer com eles, seus campos se tornam inúteis.

Custom Fields (Campos Personalizados)

Custom Fields (Campos Personalizados)

Por outro lado, Post Meta (metadados do artigo) não vêm embutidos no WordPress por padrão, algum desenvolvedor deverá criar seu conteúdo. Sendo assim, temos maior controle sobre o que o usuário pode (ou não) adicionar.

Juntamente com os campos de Post Meta, devemos criar também uma caixa chamada de Meta Box, que irá aparecer abaixo dos campos do post contendo os campos para que o usuário possa preencher. Normalmente é um formulário simples com quantos campos você precisar para atingir um objetivo maior no seu tema.

Meta Box em tema WordPress

Meta Box em tema WordPress

Além disso, o usuário pode optar por não ver a Meta Box do seu tema caso não queira. Para isso, basta clicar em “Opções de tela” e desmarcar a caixa de checkbox referente.

Opções de tela do WordPress

Opções de tela do WordPress

Com Meta Box e Post Meta você pode fazer praticamente tudo o que vier em sua mente e que esteja relacionado a um artigo em questão. Por exemplo:

  • Adicionar CSS específico para aquele artigo;
  • Criar um modelo de página idêntico ao modelo de páginas do WordPress;
  • Exibir texto adicional;
  • Configurar conteúdo para membros logados;
  • Seguir o que seu coração ou imaginação mandarem e adicionar o que quiser…

Neste artigo você vai aprender a criar uma Meta Box em tema WordPress utilizando o arquivo functions.php (isso também pode ser feito por um plugin específico).

Mas primeiro…

Antes de continuar a ler este artigo, saiba que ele faz parte de uma série de artigos chamada “Como criar um tema WordPress“, portanto, é interessante que você leia primeiro os artigos anteriores para entender melhor sobre o que estamos falando:

  1. Estrutura de arquivos de um tema WordPress
  2. Arquivo functions.php de um tema WordPress
  3. PHP, HTML e CSS em temas WordPress
  4. Paginação em temas WordPress
  5. Formulário de pesquisa para temas WordPress
  6. Criando o template de comentários WordPress
  7. Menu em temas WordPress
  8. Page templates no WordPress (Modelos de página)
  9. Custom Post Types no WordPress

Estamos criando um tema simples para exibir tudo o que estamos demonstrando nessa série de artigos. Na maioria deles você terá uma opção para baixar o tema (chamado de Tutsup Básico) para entender melhor o que estamos descrevendo.

A proposta

Como nossa Meta Box terá que fazer algo útil (não faz sentido adicionar algo que não faça nada), vou criar uma função no tema que cria conteúdo apenas para membros, ou seja, apenas para usuários logados.

Também vou deixar a possibilidade do usuário adicionar uma mensagem adicional no artigo, apenas para exemplificar como adicionar vários campos.

A proposta é adicionar um campo onde o usuário possa marcar apenas uma opção para que o conteúdo se torne “privado” (apenas para usuários logados).

Meta Box em tema WordPress

Meta Box em tema WordPress

Registrando a Meta Box

Para registrar uma Meta Box, precisamos utilizar a função add_meta_box do WordPress.

Veja:

// Cria a meta_box
function tutsup_metabox() {
	
	// Tipos de post para a metabox
	$screens = array( 'post', 'page', 'tutsup_filmes' );

	foreach ( $screens as $screen ) {

		add_meta_box(
			'tutsup_meta_box',          // ID da Meta Box 
			'Configure seu conteúdo',   // Título
			'tutsup_metabox_callback',  // Função de callback
			$screen,                    // Local onde ela vai aparecer
			'normal',                   // Contexto
			'high'                      // Prioridade
		);
		
	} // foreach
	
} // Cria a meta_box
add_action( 'add_meta_boxes', 'tutsup_metabox', 1 );

Nela você precisa enviar os campos descritos nos comentários do código acima, além de uma função de callback, que será onde criaremos o HTML da nossa Meta Box.

Função de callback da Meta Box

Nossa função de callback da Meta Box terá o seguinte:

// Essa é a função que vai exibir os dados para o usuário
function tutsup_metabox_callback( $post ) {

	// Adiciona um campo nonce para verificação posterior
	wp_nonce_field( 'tutsup_custom_metabox', 'tutsup_custom_metabox_nonce' );

	// Configura os campos
	$_tp_post_privado = get_post_meta( $post->ID, '_tp_post_privado', true );
	$_tp_post_privado ? $privado_checked = 'checked' : $privado_checked = null;
	
	$_tp_mensagem = get_post_meta( $post->ID, '_tp_mensagem', true );

	echo '<input ' . $privado_checked . ' type="checkbox" name="_tp_post_privado" value="Sim" /> Conteúdo para membros (Usuários logados)<br><br>';
	
	echo 'Exibir mensagem:<br>';
	echo '<textarea name="_tp_mensagem" class="widefat">' . esc_html( $_tp_mensagem ) . '</textarea>';
}

Pronto, nesse momento você já deverá visualizar sua Meta Box nos posts, páginas e nosso Custom Post (tutsup_filmes).

Validando os campos e salvando os dados

Agora é necessário validar os campos para ver se tudo foi enviado conforme planejamos e salvar os dados na base de dados.

Podemos fazer isso com a seguinte função:

function tutsup_save_custom_metabox_data( $post_id ) {

	// Verifica o campo nonce
	if ( ! isset( $_POST['tutsup_custom_metabox_nonce'] ) ) {
		return;
	}

	// Verifica se o campo nonce é válido
	if ( ! wp_verify_nonce( $_POST['tutsup_custom_metabox_nonce'], 'tutsup_custom_metabox' ) ) {
		return;
	}

	// Se o formulário ainda não foi enviado (estiver fazendo autosave) 
	// não faremos nada
	if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
		return;
	}

	// Verifica as permissões do usuário (mínimo: editar post).
	if ( isset( $_POST['post_type'] ) && 'contato' == $_POST['post_type'] ) {

		if ( ! current_user_can( 'edit_post', $post_id ) ) {
			return;
		}
	}

	/* Perfeito, agora vamos aos campos. */
	$_tp_post_privado = isset( $_POST['_tp_post_privado'] ) ? $_POST['_tp_post_privado'] : null;
	$_tp_post_privado = sanitize_text_field( $_tp_post_privado );
	
	$_tp_mensagem = isset( $_POST['_tp_mensagem'] ) ? $_POST['_tp_mensagem'] : null;

	// Atualiza os dados no BD
	update_post_meta( $post_id, '_tp_post_privado', $_tp_post_privado );
	update_post_meta( $post_id, '_tp_mensagem', $_tp_mensagem );
}
add_action( 'save_post', 'tutsup_save_custom_metabox_data' );

Pronto, agora temos nossos dados salvos na base de dados.

Alterando o tema

Como estamos criando uma parte da função que cria conteúdo apenas para membros, precisaremos alterar um pouco nosso tema.

Optei por fazer a alteração apenas no meu loop principal (loop-index.php), veja:

<?php
if ( is_single() ) {
	
	// Post meta
	$metadados = get_post_meta( $post->ID );
	
	// Configura o conteúdo para membros
	if ( isset( $metadados['_tp_post_privado'] ) && isset( $metadados['_tp_post_privado'][0] ) ) {
	
		// Verifica se _tp_post_privado é igual a sim
		if ( $metadados['_tp_post_privado'][0] == 'Sim' ) {
		
			// Verifica se o usuário está logado
			if ( ! is_user_logged_in() ) {
			
				$login = '<a href="' . wp_login_url() . '">login</a>';
				$registre_se = '<a href="' . wp_registration_url() . '">registre-se</a>';
				
				echo "Conteúdo exclusivo para usuários. Faça $login ou $registre_se para acessar.";
				
				// Argumentos do formulário de login
				$login_args = array(
						'echo'           => true,
						'redirect'       => site_url( $_SERVER['REQUEST_URI'] ), 
						'form_id'        => 'loginform',
						'label_username' => __( 'Username' ),
						'label_password' => __( 'Password' ),
						'label_remember' => __( 'Remember Me' ),
						'label_log_in'   => __( 'Log In' ),
						'id_username'    => 'user_login',
						'id_password'    => 'user_pass',
						'id_remember'    => 'rememberme',
						'id_submit'      => 'wp-submit',
						'remember'       => true,
						'value_username' => NULL,
						'value_remember' => false
				);
				
				// Mostra o formulário de login
				wp_login_form( $login_args );
				
				// Retorna para não exibir nada do post
				return;
				
			} // Verifica se o usuário está logado
			
		} // Verifica se _tp_post_privado é igual a sim
		
	} // Configura o conteúdo para membros
	
	// Configura a mensagem (se existir)
	if ( isset( $metadados['_tp_mensagem'] ) && isset( $metadados['_tp_mensagem'][0] ) ) {
	
		// Verifica se _tp_mensagem tem algum valor
		if ( ! empty( $metadados['_tp_mensagem'][0] ) ) {
		
			echo '<p>' . $metadados['_tp_mensagem'][0] . '</p>';
			
		} // Verifica se _tp_mensagem tem algum valor
		
	} // Configura a mensagem (se existir)
	
} // is_single()
?>

No exemplo acima, estou apenas verificando se os dados de Post Meta estão configurados, se eles têm o valor que preciso e criando a ação.

Por exemplo, se o campo para conteúdo privado estiver marcado e tiver o valor “Sim”, não exibimos o conteúdo se o usuário não estiver logado. Ao invés disso, exibimos apenas uma mensagem e os campos de usuário e senha.

Também verificamos se a mensagem está configurada; se sim, exibimos seu conteúdo.

Download

Caso queira baixar o código completo de nosso tema experimental até o momento, segue o link para download:

Descompacte a pasta dentro de wp-content/themes.

Concluindo

Meta Boxes e Post Meta são excelentes maneiras de salvar conteúdo no WordPress para alterar a estrutura padrão do CMS, utilize com sabedoria.

Não deixe de seguir os outros tutoriais sobre “Criar temas WordPress“.

Em caso de dúvidas, pergunte nos comentários.

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.

Você pode atingir um tema especificamente detalhado e diferenciado para cada parte do WordPress usando apenas os template files, mas as coisas não param por aí. É possível criar page templates (modelos de página) conforme você preferir, para deixar algumas páginas com layout totalmente diferente das outras. E o melhor de tudo é que você poderá escolher o modelo assim que for criar ou editar qualquer página.

Page templates no WordPress

Page templates no WordPress

Nesse artigo, você vai aprender a criar page templates para temas WordPress.

Aulas anteriores

Antes de continuar a ler esse artigo, saiba que ele faz parte de uma série de tutoriais sobre “Criar um tema WordPress“, portanto, sugiro que leia as aulas anteriores para não parecer que seu conteúdo está incompleto.

Agora vamos aos modelos de página…

Criando o template file

Para que você tenha um modelo de página, é necessário criar um arquivo de modelo chamado page-nomedomodelo.php. Por exemplo, vou criar um modelo de página sem barra lateral, chamado de “Largura máxima”. Nesse caso, meu arquivo modelo vai se chamar page-largura-maxima.php.

Primeiramente, vou adicionar um cabeçalho no meu arquivo com o nome do meu modelo:

<?php
/*
Template Name: Largura máxima
*/
?>

Agora vou copiar o conteúdo do meu index.php, remover a barra lateral e adicionar uma classe para identificar a largura do conteúdo da página. Veja:

<?php
/*
Template Name: Largura máxima
*/
?>
<!-- Adiciona o cabeçalho (header.php) -->
<?php get_header(); ?>

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

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

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

E pronto!

Agora é só você acessar wp-admin e tentar criar ou editar uma página. Os modelos de página já devem aparecer para que você possa escolher.

CSS do page template

Claro que se você quer algo diferente, provavelmente terá que fazer algumas adições no CSS padrão do seu tema.

No meu caso, foi apenas isso:

/* Modelo de página */
.pagina-largura-maxima {
	width: 100%;
}

 Download

Caso queira baixar nosso tema criado até o momento, segue o link:

Descompacte a pasta dentro de wp-content/themes/.

Concluindo

Não deixe de seguir as novas aulas sobre “Criar temas WordPress“.

Em caso de dúvidas, pergunte nos comentários.

Continuando com nossa série de tutoriais sobre “Criar temas WordPress“, hoje você vai ver como registrar e exibir um menu em seu tema. Nosso menu poderá ter quantos níveis o usuário quiser (apesar de não recomendado) ele irá exibir todos os submenus categorizados na forma em que foram registrados na área administrativa (wp-admin) do WordPress.

Mas primeiro…

Antes que você continue a seguir este tutorial, é altamente recomendado que você veja as aulas anteriores para que esse artigo não pareça incompleto.

Seguem as aulas anteriores:

Agora sim, vamos adiante…

functions.php

Só para lembrar, nosso menu já está registrado em nosso functions.php, veja:

// Configurações do tema
function tutsup_setup() {		
	// Ativa o feed
	add_theme_support( 'automatic-feed-links' );
	
	// Ativa imagens destacadas
	add_theme_support( 'post-thumbnails' );
	
	// Ativa posts-formats
	add_theme_support( 'post-formats', array( 'audio', 'aside', 'chat', 'gallery', 'image', 'link', 'quote', 'status', 'video' ) );
	
	// Adiciona tamanhos de imagens customizados
	add_image_size( 'tutsup-small', 430, 286, true );
	add_image_size( 'tutsup-large', 1140, 1140, false );
	add_image_size( 'tutsup-thumbnails', 200, 133, true );

	// Registra um menu
	register_nav_menus( array(
		'header' => 'Header',
	) );
}
add_action( 'after_setup_theme', 'tutsup_setup' );

Veja as linhas marcadas acima. Nosso menu se chamará “header“, você pode modificar esse nome se quiser.

O HTML do menu

Acredite se quiser, mas você não vai precisar digitar nada em HTML. Simplesmente abra nosso arquivo header.php e adicione o seguinte ao final:

<?php
$header_menu_args = array(
	'theme_location'  => 'header',
	'menu'            => '',
	'container'       => 'nav',
	'container_class' => 'main-menu clearfix',
	'container_id'    => '',
	'menu_class'      => '',
	'menu_id'         => '',
	'echo'            => true,
	'fallback_cb'     => 'wp_page_menu',
	'before'          => '',
	'after'           => '',
	'link_before'     => '',
	'link_after'      => '',
	'items_wrap'      => '<ul id="%1$s" class="%2$s">%3$s</ul>',
	'depth'           => 0,
	'walker'          => ''
);

wp_nav_menu( $header_menu_args );
?>

Pronto, agora seu menu já deve estar aparecendo sem nenhum estilo. O único serviço que teremos é em nosso CSS, então vamos para o arquivo css/main-style.css.

Observação: É necessário que você configure o menu na área administrativa do WordPress e selecione “header” como local.

CSS do nosso menu

Todo menu WordPress pode ter submenus de vários níveis diferentes, o que indica que o usuário pode optar por adicionar submenu dentro de submenu.

Para não privarmos o usuário de ter a possibilidade de criar o menu da maneira que preferir, vamos exibir todos os submenus categorizados nos mesmos níveis em que foram incluídos na wp-admin.

Para isso, teremos que utilizar alguns truques de CSS, veja:

/**
 * Menu principal
 */
 
/* Container do menu */
.main-menu {
	background: #1e88e5;
}
.main-menu a {
	color: #fff;
	text-transform: uppercase;
	font-weight: 700;
	font-size: 12px;
	letter-spacing: 0.02em;
}
.main-menu a:hover {
	background: #4f9ee3;
}

/* Container dos links do menu - Espaço de 30px para acompanhar o layout */
.main-menu > ul {
	margin: 0 30px;
}

/* Mantém os sub-menus nas posições corretas */
.main-menu li {
	position: relative;
}

.main-menu > ul > li {
	float: left;
}
.main-menu > ul > li > a {
	display: block;
	padding: 10px;
}
.main-menu > ul > .menu-item-has-children > a {
	padding: 10px 30px 10px 10px;
}

/* Adiciona uma seta para baixo nos itens que tem sub-menu */
.main-menu > ul > .menu-item-has-children > a:after{
	display: block;
	content: ' ';
	border: 5px solid transparent; 
	border-top-color: #fff;
	right: 10px;
	top: 50%;
	margin-top: -2px;
	height: 5px;
	width: 5px;
	position: absolute;
	z-index: 9998;
}

/* Mantém os sub-menus mais abaixo nas posições corretas */
.menu-item-has-children  {
	position: relative;
}

.menu-item-has-children .sub-menu {
	position: absolute;
	background: #ddd;
	min-width: 200px;
	display: none;
	z-index: 9999;
}
.menu-item-has-children .sub-menu  li {
	border-bottom: 2px solid #ccc;
}
.menu-item-has-children .sub-menu  a {
	display: block;
	padding: 10px;
	color: #555;
}

/* Sub-menus dentro de sub-menus sempre aparecem ao lado direito */
.sub-menu .sub-menu {
	position: absolute;
	min-width: 200px;
	left: 100%;
	top: -0;
}

/* Não precisamos de javascript para mostra os sub-menus */
.menu-item-has-children:hover >.sub-menu {
	display: block;
}
.menu-item-has-children:hover >.sub-menu a:hover {
	background: #eee;
}

A partir daqui, seu menu deverá estar mais ou menos assim:

Menu do WordPress

Menu do WordPress

Perceba que utilizamos vários recursos, muitos dos quais já descrevemos aqui no Tutsup. Saiba mais em:

Nos artigos acima descrevemos várias coisas que ajudaram a você entender o menu criado para nosso tema.

Download

Caso queira baixar o tema que criamos no ponto que paramos nesse tutorial, segue o link:

Concluindo

Lembre-se que estou passando o método, não estou entrando em detalhes sobre CSS, nem estrutura HTML. Quero que você fique à vontade para criar seu tema no estilo que preferir.

Em caso de dúvidas, basta comentar.

Muitas pessoas optam por remover o sistema de comentários padrão do WordPress e adicionar algo como disqus, comentários do Facebook ou Google+, ou qualquer outro serviço mais profissional. Isso acontece por milhares de fatores, mas o que acho que mais leva as pessoas à troca são os spammers. Além disso, os outros serviços poupam recursos do servidor, como serviço de e-mail e MySQL.

Quando trocamos o sistema padrão de comentários do WordPress, o novo sistema irá tomar conta do nosso arquivo “comments.php” e não precisaremos nos preocupar com ele, porém, se esse não for o seu caso e você ainda insiste em utilizar o sistema de comentários padrão do WordPress, será necessário criar o template de comentários e estilizar o mesmo com CSS.

Vamos ver como fazer logo abaixo.

Aulas anteriores

Antes de continuar, não se esqueça de seguir as aulas anteriores. Algumas partes desse artigo podem parecer incompletas se você não ler as aulas anteriores.

Criando o arquivo comments.php

Primeiramente é necessário criar o arquivo comments.php, porém, ao invés de ficarmos criando várias funções, pesquisar o Codex inteiro ou ficar perguntando em fóruns. Vamos pegar o arquivo comments.php do tema Twenty fourteen, em seguida o CSS.

Feito isso, vamos modificar conforme precisarmos.

Veja como ficou meu arquivo comments.php:

<?php
/**
 * Aqui vamos garantir que os comentários só vão aparecer em posts, páginas ou
 * anexos. Além disso, também bloqueamos os comentários para páginas com senha,
 * eles só vão aparecer se o usuário digitar a senha.
 */
if ( post_password_required() || ! is_singular() ) {
	return;
}
?>

<?php
/**
 * A área de comentários do tema "TwentyFourteen"
 * com algumas edições necessárias.
 */
?>
<div id="comments" class="comments-area">

	<?php if ( have_comments() ) : ?>

	<h4 class="comments-title">
		Comentários
	</h4>

	<?php if ( get_comment_pages_count() > 1 && get_option( 'page_comments' ) ) : ?>
	<nav id="comment-nav-above" class="navigation comment-navigation" role="navigation">
		<h5 class="screen-reader-text">Navegação dos comentários</h5>
		<div class="nav-previous"><?php previous_comments_link( 'Comentários mais antigos' ); ?></div>
		<div class="nav-next"><?php next_comments_link(  'Comentários mais recentes'  ); ?></div>
	</nav><!-- #comment-nav-above -->
	<?php endif; // Check for comment navigation. ?>

	<ol class="comment-list">
		<?php
			wp_list_comments( array(
				'style'      => 'ol',
				'short_ping' => true,
				'avatar_size'=> 34,
			) );
		?>
	</ol><!-- .comment-list -->

	<?php if ( get_comment_pages_count() > 1 && get_option( 'page_comments' ) ) : ?>
	<nav id="comment-nav-above" class="navigation comment-navigation" role="navigation">
		<h5 class="screen-reader-text">Navegação dos comentários</h5>
		<div class="nav-previous"><?php previous_comments_link( 'Comentários mais antigos' ); ?></div>
		<div class="nav-next"><?php next_comments_link(  'Comentários mais recentes'  ); ?></div>
	</nav><!-- #comment-nav-above -->
	<?php endif; // Check for comment navigation. ?>

	<?php if ( ! comments_open() ) : ?>
	<p class="no-comments">Os comentários estão fechados.</p>
	<?php endif; ?>
	
	<?php endif; // have_comments() ?>

	<?php comment_form(); ?>

</div><!-- #comments -->

Agora basta adicionarmos o CSS que segue abaixo.

CSS para os comentários

O CSS também é parte do código do tema Twenty Fourteen, porém, editei várias coisas para deixar com a cara que eu queria, veja:

/**
 * A área de comentários do tema "TwentyFourteen"
 * com algumas edições necessárias.
 */
.comments-area {
	margin: 30px auto;
	max-width: 100%;
	font-size: 12px;
}

.comments-area textarea {
	width: 100%;
}

.comment-body  {
	border: 1px solid #ddd;
	background: #f9f9f9;
	padding: 15px;
	margin: 15px 0;
}

.comment-reply-title,
.comments-title {
	font: 700 16px/1.5 sans-serif;
	margin: 0;
	padding: 0;
	text-transform: uppercase;
}

.comment-list {
	list-style: none;
	margin: 0 0 30px 0;
}

.comment-author {
	font-size: 14px;
	line-height: 1.7142857142;
}

.comment-list .reply,
.comment-metadata {
	font-size: 10px;
	text-transform: uppercase;
}

.comment-reply-link {
	padding: 5px 10px;
	color: #fff;
	display: inline-block;
	background: #1e88e5;
}

.comment-author .fn {
	font-weight: 900;
}

.comment-list article,
.comment-list .pingback,
.comment-list .trackback {
	border-top: 1px solid rgba(0, 0, 0, 0.1);
	margin-bottom: 24px;
	padding-top: 24px;
}

.comment-list > li:first-child > article,
.comment-list > .pingback:first-child,
.comment-list > .trackback:first-child {
	border-top: 0;
}

.comment-author {
	position: relative;
}

.comment-author .avatar {
	border: 1px solid rgba(0, 0, 0, 0.1);
	height: 18px;
	padding: 2px;
	position: absolute;
	top: 0;
	left: 0;
	width: 18px;
}

.says {
	display: none;
}

.comment-author,
.comment-awaiting-moderation,
.comment-content,
.comment-metadata {
	padding-left: 30px;
}

.comment-edit-link {
	margin-left: 10px;
}

.comment-content {
	-webkit-hyphens: auto;
	-moz-hyphens:    auto;
	-ms-hyphens:     auto;
	hyphens:         auto;
	word-wrap: break-word;
}

.comment-content ul,
.comment-content ol {
	margin: 0 0 24px 22px;
}

.comment-content li > ul,
.comment-content li > ol {
	margin-bottom: 0;
}

.comment-content > :last-child {
	margin-bottom: 0;
}

.comment-list .children {
	list-style: none;
	margin-left: 15px;
}

.comment-respond {
	margin-bottom: 24px;
	padding: 0;
}

.comment .comment-respond {
	margin-top: 24px;
}

.comment-respond h3 {
	margin-top: 0;
	margin-bottom: 24px;
}

.comment-notes,
.comment-awaiting-moderation,
.logged-in-as,
.no-comments,
.form-allowed-tags,
.form-allowed-tags code {
	color: #767676;
}

.comment-notes,
.comment-awaiting-moderation,
.logged-in-as {
	font-size: 14px;
	line-height: 1.7142857142;
}

.no-comments {
	font-size: 16px;
	font-weight: 900;
	line-height: 1.5;
	margin-top: 24px;
	text-transform: uppercase;
}

.comment-form label {
	display: block;
}

.comment-form input[type="text"],
.comment-form input[type="email"],
.comment-form input[type="url"] {
	width: 100%;
}

.form-allowed-tags,
.form-allowed-tags code {
	font-size: 12px;
	line-height: 1.5;
}

.required {
	color: #c0392b;
}

.comment-reply-title small a {
	color: #2b2b2b;
	float: none;
	overflow: hidden;
	font-size: 12px;
	display: block;
	clear: both;
}

.comment-navigation {
	font-size: 12px;
	line-height: 2;
	margin-bottom: 48px;
	text-transform: uppercase;
}

.comment-navigation .nav-next,
.comment-navigation .nav-previous {
	display: inline-block;
}

.comment-navigation .nav-previous a {
	margin-right: 10px;
}

#comment-nav-above {
	margin: 15px 0;
}

O trecho de código acima deverá ser adicionado no arquivo css/main-style.css do nosso tema básico.

Nosso sistema de comentários ficou assim:

Sistema de comentários - Tutsup Básico

Sistema de comentários – Tutsup Básico

Download

Se quiser baixar o nosso tema até o momento (com template de comentários WordPress), segue o link:

Em caso de dúvidas é só perguntar nos comentários abaixo.

Adicionar seu próprio formulário de pesquisa para temas WordPress é bastante simples na verdade, basta criar um arquivo chamado searchform.php dentro da pasta do seu tema com o novo formulário, em seguida chamar a função get_search_form no local onde você deseja que ele seja apresentado.

Antes que você continue, lembre-se de ler as aulas anteriores:

Vamos ver mais detalhes sobre o novo formulário do seu tema abaixo.

Criando o novo formulário

Abra seu editor de textos padrão (texto puro) e crie um novo arquivo chamado searchform.php.

Nele adicione o seguinte:

<div class="conteudo-pesquisa">
	<form role="search" method="get" class="formulario-pesquisa" action="<?php 
		echo home_url( '/' ); ?>">
		
		<!-- Os campos estão invertidos, por conta do nosso CSS, 
		você pode modificar isso se preferir -->
		<input type="submit" class="submit-pesquisa" value="Pesquisar" />
		<input type="search" class="input-pesquisa" placeholder="Pesquisar" value="<?php 
		echo get_search_query() ?>" name="s" required />
		
	</form>
</div>

Perceba que o HTML é maleável, você pode adicionar o que preferir ali, as únicas partes que são importantes são:

  • O nome do campo principal deve ser “s”;
  • O action do formulário deverá conter echo home_url( ‘/’ );

O resto é a gosto do freguês.

Adicionando o form em nosso “header.php”

Agora devemos chamar a função que vai adicionar o arquivo searchform.php em nosso layout. Para nosso caso, vamos utilizar o arquivo “header.php“.

Escolha o local adequado e adicione a função:

<?php get_search_form(); ?>

Veja nosso header.php completo:

<!DOCTYPE html>
<html class="no-js" <?php language_attributes(); ?>>

<head>
	<!-- O charset padrão -->
	<meta charset="<?php bloginfo('charset'); ?>">
	
	<!-- Necessário para layout responsivo -->
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	
	<!-- O título do blog -->
	<title><?php wp_title(''); ?></title>

	<!-- 
	O restante do cabeçalho que virá dentro da head. 
	Criado automaticamente pelo WordPress. 
	-->
	<?php wp_head(); ?>
</head>

<!-- Início do body -->
<body <?php body_class(); ?>>

<div id="pagina" class="pagina"> <!-- .pagina -->

<header class="conteudo cabecalho padding-total">
	<div class="linha clearfix">
		<div class="colunas principal">
			<div class="conteudo-coluna margem-total">
				<h1> 
					<a href="<?php bloginfo('url'); ?>">
						<?php bloginfo('name'); ?> 
					</a>
				</h1>
			</div>
		</div>
		
		<div class="colunas lateral">
			<div class="conteudo-coluna margem-total">
				<div class="search-form">
					<?php get_search_form(); ?>
				</div>
			</div>
		</div>
	</div>
</header>

 O CSS para nosso formulário

Para o CSS, você pode adicionar o que preferir, veja como fiz o meu (css/main-style.css):

/* Pesquisa */
.conteudo-pesquisa {
	text-align: right;
	padding: 20px 0 0 0;
}
.formulario-pesquisa {
	font-size: 0;
}
.input-pesquisa, .submit-pesquisa {
	display: inline-block;
	font-size: 14px;
	line-height: 30px;
	height: 30px;
	border: none;
	font-family: sans-serif;
	float: right;
	padding: 0 10px;
}

Isso deverá gerar o mesmo apresentado na imagem abaixo:

Formulário de pesquisa para temas WordPress

Formulário de pesquisa para temas WordPress

Download

Caso queira baixar o código que criamos até agora, acesse o link abaixo:

Descompacte o arquivo dentro da pasta wp-content/themes e ative o tema.

Em caso de dúvidas, basta deixar sua pergunta nos comentários.