Recentemente os colegas do blog Problogdesign publicaram uma matéria bem interessante sobre como carregar os próximos conteúdos do seu blog WordPress usando Ajax. Para quem não sabe, Ajax é uma linguagem de programação que lhe permite poupar imenso tempo no carregamento de páginas e pedidos junto do seu servidor. O artigo explica como criar um plugin de raíz para substituir o seu link “Postagens mais Antigas” ou mesmo um outro plugin que você esteja usando como por exemplo o WP-Pagenavi para criar uma navegação, por um simples botão que lhe permite visualizar em tempo real as próximas postagens do seu blog WordPress, tal como acontece com o Twitter ou Facebook.
Pode visualizar a demo do plugin e ver a versão final do projeto se desejar. Pode ainda descarregar todos os ficheiros compilados num plugin aqui! (Faça o upload e ative-o).
Vamos então iniciar o nosso tutorial. O plugin que pretendemos desenvolver irá fazer o seguinte:
- Múltiplos cliques – O primeiro clique abre a segunda página de posts, o segundo clique abre a terceira página de posts, etc.)
- Verificar por postagens primeiro – Se não existirem mais posts para carregar, o usuário é avisado.
- Não usar o plugin – Se um usuário não usar JavaScript, o site não será modificado de forma alguma.
ESTRUTURA DO PLUGIN
Irão existir 3 ficheiros no plugin (um PHP, um CSS, um JS). Para manter as boas práticas, iremos manter os ficheiros CSS e JavaScript nas suas próprias pastas. E vamos chamar o plugin de “pbd-ajax-load-posts”.
Agora vamos começar pelas partes necessárias no topo do nosso ficheiro pbd-ajax-load-posts.php:
<?php /** * Plugin Name: PBD AJAX Load Posts * Plugin URI: https://www.escolawp.com/ * Description: Load the next page of posts with AJAX. * Version: 0.1 * Author: Pro Blog Design * Author URI: http://www.problogdesign.com/ * License: GPLv2 */
CARREGAR FICHEIROS E VALORES DE PASSAGEM
A primeira coisa que precisamos fazer é garantir que os nossos ficheiros JavaScript e CSS files são carregados nas páginas corretas. Mantenha-se em seu ficheiro pbd-ajax-load-posts.php e cole dentro dele o seguinte código:
/** * Initialization. Add our script if needed on this page. */ function pbd_alp_init() { global $wp_query; // Add code to index pages. if( !is_singular() ) { // Queue JS and CSS wp_enqueue_script( 'pbd-alp-load-posts', plugin_dir_url( __FILE__ ) . 'js/load-posts.js', array('jquery'), '1.0', true ); wp_enqueue_style( 'pbd-alp-style', plugin_dir_url( __FILE__ ) . 'css/style.css', false, '1.0', 'all' );
O código apresentado inicia com a introdução de uma nova função, pbd_alp_init() (alp = AJAX Load Posts), que mais tarde será colocada no local correto. Provavelmente irá reparar também que usámos a variável global $wp_query, a qual iremos usar no próximo passo.
A parte mais importante inicia-se na linha 8. A primeira declaração é na verdade uma declaração condicional. Isso significa que em qualquer página que não seja um artigo ou página individual, iremos correr este código.
Isto é uma forma de assegurarmos que o nosso código corre corretamente na homepage, páginas de tags, páginas de pesquisa, etc. Poderá adaptá-lo para ser mais específico, e.x. se você não desejar inclui-lo na sua homepage.
Depois disso usamos as funções wp_enqueue_script() e wp_enqueue_style() para dizermos ao WordPress sobre os nossos dois ficheiros (como também que iremos usar jQuery).
Agora, precisamos passar alguns valores ao nosso script, nomeadamente:
- O número de página em que estamos no momento.
- O número total de páginas.
- O link para a próxima página.
Iremos usar a função wp_localize_script() para calcular todos ests valores no PHP, e depois mostrá-los na nossa página web de forma a que o nosso script possa acessá-los mais tarde.
// What page are we on? And what is the pages limit? $max = $wp_query->max_num_pages; $paged = ( get_query_var('paged') > 1 ) ? get_query_var('paged') : 1; // Add some parameters for the JS. wp_localize_script( 'pbd-alp-load-posts', 'pbd_alp', array( 'startPage' => $paged, 'maxPages' => $max, 'nextLink' => next_posts($max, false) ) );
Iremos trabalhar primeiro dois valores. $max é o número máximo de páginas que a query pode retornar (ex. se cada página mostra 5 posts e existem 12 posts na categoria, o nosso máximo serão 3).
A variável $paged irá guardar a página em que nos encontramos (O objetivo do nosso plugin é garantir que o usuário nunca carrega uma segunda página).
Se saltarmos para a linha 12, você irá encontrar o nosso 3º valor (o link para a próxima página). next_posts() é uma função integrada no core do WordPress, a qual irá retornar o URL de que necessitamos.
A função wp_localize_script() é excelente porque torna bastante fácil passar valor do PHP para o JavaScript. O primeiro valor, ‘pbd-alp-load-posts’ deverá coincidir com o primeiro valor da chamada wp_enqueue_script().
O segundo valor, ‘pbd_alp’, é o nome que iremos usar no nosso JavaScript mais tarde.
Finalmente, iremos enviar uma ordem da informação. Se analisar o código-fonte do nosso HTML mais tarde, você visualizar algo parecido com isto logo antes do nosso ficheiro JavaScript ser carregado:
<script type='text/javascript'> /* <![CDATA[ */ var pbd_alp = { startPage: "1", maxPages: "6", nextLink: "http://www.problogdesign.com/demo/ajax-load-posts/page/2/" }; /* ]]> */ </script>
Agora, apenas necessitamos encerrar a nossa declaração “If”, a nossa função pbd_alp_init(), e depois colocar tudo no seu devido lugar.
} } add_action('template_redirect', 'pbd_alp_init');
jQUERY – O CORAÇÃO DO PLUGIN
Agora que já carregámos os nossos scripts e passámos os valores que necessitávamos, é altura de avançarmos para a parte mais interessante do nosso tutorial.
Abra o ficheiro load-posts.js. A primeira coisa que precisamos fazer é acessar as 3 variáveis que passámos na nossa função PHP.
jQuery(document).ready(function($) { // The number of the next page to load (/page/x/). var pageNum = parseInt(pbd_alp.startPage) + 1; // The maximum number of pages the current query can return. var max = parseInt(pbd_alp.maxPages); // The link of the next page of posts. var nextLink = pbd_alp.nextLink;
A foma de acessarmos aos nossos valores é usando o formato: pbd_alp.valueName (pbd_alp foi o segundo valor que introduzimos no wp_localize_script(), lembra?).
O mais importante a lembrar é que os nossos números foram enviados como strings, portanto, usamos a função JavaScript’s parseInt() function para voltar a convertê-los em números.
Com o pageNum, adicionamos um ao número uma vez que ele vai guardar o número da próxima página a carregar (Não a página atual).
A grande maioria dos templates wordpress já tem navegação entre as páginas, na forma de links Artigos Antigos/Novos Artigos. Nós queremos substituir isso pelo nosso botão AJAX, pelo que o nosso primeiro passo é substituir esses links pelo nosso próprio botão.
/** * Replace the traditional navigation with our own, * but only if there is at least one page of new posts to load. */ if(pageNum <= max) { // Insert the "More Posts" link. $('#content') .append('<div class="pbd-alp-placeholder-'+ pageNum +'"></div>') .append('<p id="pbd-alp-load-posts"><a href="#">Load More Posts</a></p>'); // Remove the traditional navigation. $('.navigation').remove(); }
Começamos com uma verificação da condicional. Lembre-se que o pageNum é o número da página seguinte, e caso seja maior que o max, significa que não existem mais páginas para carregar. Nesse caso, nós não queremos que apareça o nosso botão.
No caso de existir mais conteúdos para carregar, procuramos pela div #content, e adicionamos-lhe duas coisas no final. A primeira é uma div vazia, que iremos usar mais à frente para adicionar as nossas postagens.
A segunda é o nosso botão (um link regular HTML), envolvido num parágrafo.
Finalmente, procuramos pela div .navigation e removê-mo-la. Se o nosso template usar uma class diferente para os botões de navegação, você terá de alterar isso manualmente (.navigation é o padrão nos templates de 2010). O mesmo se aplica à div #content!
O resultado do código acima é que o nosso botão já se encontra no seu lugar, embora ainda não faça nada.
E porque fizemos tudo com JavaScript, temos a certeza de que o nosso plugin não faz uso do botão quando não existem mais páginas para carregar, e também porque se o JavaScript não for carregado, o plugin não faz rigorosamente nada.
Agora, vamos avançar para a funcionalidade quando o usuário clica no botão.
/** * Load new posts when the link is clicked. */ $('#pbd-alp-load-posts a').click(function() { // Are there more posts to load? if(pageNum <= max) { // Show that we're working. $(this).text('Loading posts...');
A primeira linha deste código é a manipulação de um evento com jQuery, que corre quando o usuário clica no botão.
Na linha 7, voltamos a correr a mesma verificação como anteriormente. Isto é importante porque o nosso script iria carregar uma mensagem de erro 404 caso não existam mais artigos para carregar. Isso nós não queremos!
A linha 10 atualiza o texto do nosso botão para “Loading posts…” Isto é interessante porque o usuário recebe imediatamente uma mensagem assim que carrega no botão.
O próximo passo é fazer a chamada em AJAX. Uma série de coisas acontecem aqui, portanto copie e cole o seguinte código para o seu script e depois explicaremos tudo mais à frente.
$('.pbd-alp-placeholder-'+ pageNum).load(nextLink + ' .post', function() { // Update page number and nextLink. pageNum++; nextLink = nextLink.replace(/\/page\/[0-9]?/, '/page/'+ pageNum); // Add a new placeholder, for when user clicks again. $('#pbd-alp-load-posts') .before('<div class="pbd-alp-placeholder-'+ pageNum +'"></div>') // Update the button message. if(pageNum <= max) { $('#pbd-alp-load-posts a').text('Load More Posts'); } else { $('#pbd-alp-load-posts a').text('No more posts to load.'); } } );
A primeira linha é a mais importante. Iremos usar um seletor jQuery para seleccionar o espaço reservado à nossa div. A razão pela qual adicionámos o número pageNum ao final do nome da class é porque caso o usuário volte a clicar no botão, iremos adicionar os novos posts a um novo espaço reservado (não substituindo pelos anteriores).
Na linha 2, iniciamos uma nova função que irá correr assim que a chamada AJAX termine. A primeira coisa que faz é atualizar os nossos valores para a próxima vez que o botão for clicado.
O pageNum é incrementado em um (para apontar para a próxima página), e o nextLink é atualizado usando uma expressão regular. Ele procura pelo URL para a /page/2/ (ou outro número), e atualiza o número da página pelo número da página seguinte.
Na linha 8, adicionamos um novo espaço reservado à nossa div. Este será usado da próxima vez que o botão for clicado.
Finalmente, na linha 12, voltamos a atualizar o texto do nosso botão. Se existirem mais artigos para serem carregados, revertemos para o texto original. Se não existirem, atualizaremos o texto indicando isso mesmo.
Agora apenas necessitamos concluir o nosso código:
} else { $('#pbd-alp-load-posts a').append('.'); } return false; }); });
Este código inicia fechando a nossa primeira declaração “if” (existem mais páginas para carregar?). Se não existirem, ele adiciona ‘.’ ao botão da mensagem. Isto é muito simples para dar uma resposta visual ao usuário quando o botão é clicado (veja o screenshot em baixo).
ESTILIZAR
O botão está finalmente funcionando! A única coisa que está faltando é estilizá-lo. Você poderá fazê-lo da forma que bem entender usando CSS. Neste tutorial usamos CSS3 para tornar os cantos do botão redondos, e adicionar um gradiente e uma sombra.
Adicione o seguinte código ao seu ficheiro css/style.css:
#pbd-alp-load-posts a:link, #pbd-alp-load-posts a:visited { display: block; text-align: center; padding: 4px 0; color: #444; text-decoration: none; /** Rounded Corners **/ -moz-border-radius: 8px; border-radius: 8px; /** Drop shadow **/ -moz-box-shadow: 1px 1px 1px #999; -webkit-box-shadow: 1px 1px 1px #999; box-shadow: 1px 1px 1px #999; /** Gradients : http://css-tricks.com/css3-gradients/ */ /* fallback */ background-color: #f1f1f1; /* Firefox 3.6+ */ background: -moz-linear-gradient(100% 100% 90deg, #e4e3e3, #f1f1f1); /* Safari 4-5, Chrome 1-9 */ /* -webkit-gradient(<type>, <point> [, <radius>]?, <point> [, <radius>]? [, <stop>]*) */ background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#f1f1f1), to(#e4e3e3)); /* Safari 5.1+, Chrome 10+ */ background: -webkit-linear-gradient(#f1f1f1, #e4e3e3); /* Opera 11.10+ */ background: -o-linear-gradient(#f1f1f1, #e4e3e3); } #pbd-alp-load-posts a:hover, #pbd-alp-load-posts a:active { /** Drop shadow **/ -moz-box-shadow: 1px 1px 1px #bbb; -webkit-box-shadow: 1px 1px 1px #bbb; box-shadow: 1px 1px 1px #bbb; /** Gradients : http://css-tricks.com/css3-gradients/ */ /* fallback */ background-color: #f5f5f5; /* Firefox 3.6+ */ background: -moz-linear-gradient(100% 100% 90deg, #eaeaea, #f5f5f5); /* Safari 4-5, Chrome 1-9 */ /* -webkit-gradient(<type>, <point> [, <radius>]?, <point> [, <radius>]? [, <stop>]*) */ background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#f5f5f5), to(#eaeaea)); /* Safari 5.1+, Chrome 10+ */ background: -webkit-linear-gradient(#f1f1f1, #eaeaea); /* Opera 11.10+ */ background: -o-linear-gradient(#f5f5f5, #eaeaea);
E está feito! Guarde o seu trabalho e ative o seu plugin.
Se desejar pode visualizar a demo do plugin e ver a versão final do projeto. Pode ainda descarregar todos os ficheiros compilados num plugin aqui! (Faça o upload e ative-o).
Este tutorial foi criado originalmente pelos colegas do Problogdesign. Visite-os!
Até Já!