JavaScript

O WordPress possui um gerenciador de dependência, que lhe permite controlar os imports do JavaScript. Não use a tag <script> para fazer embeds de scripts, ao invés disso, crie um arquivo separado e o importe.

Registrando e Importando

Os scripts devem ser registrados, isso facilita o trabalho do gerenciador de dependência, pois quando você registra o arquivo, você declara a existência do script para o WordPress.

Vamos registrar e importar um script.

  1. // Usa a função wp_enqueue_scripts para registrar e importar os scripts no Front-End.
  2. add_action( 'wp_enqueue_scripts', 'register_and_enqueue_a_script' );
  3. function register_and_enqueue_a_script() {
  4. // Associa uma ID chamada `my-script` para este script em específico.
  5. // + este arquivo está localizado na raiz do tema,
  6. // + que possui como dependência o o jQuery,
  7. // + Um *timestamp* é adicionado toda vez que o arquivo é modificado, isso previne o cache do arquivo durante o desenvolvimento,
  8. // + ele é posicionado no final da página (footer)
  9. wp_register_script(
  10. 'my-script',
  11. get_template_directory_uri().'/js/functions.js',
  12. array( 'jquery' ),
  13. filemtime( get_template_directory().'/js/functions.js',
  14. true
  15. );
  16. // Importamos o script.
  17. wp_enqueue_script( 'my-script' );
  18. }

Pro-Tips:

  • Os scripts devem ser importados apenas quando necessário; Envolvendo a função wp_enqueue_script() usando condicionais para controle do mesmo.
  • Quando você for importar seus scripts no Painel do Admin, use o hook admin_enqueue_scripts.
  • Se for adicionar scripts para a tela de login, use o hook login_enqueue_scripts.

Localização

A localização é um script que lhe permite passar variáveis(dados) ​​do PHP para JavaScript. Isso normalmente é usado para internacionalização de strings (tradução), mas existem muitas outras meneiras de usarmos esta técnica.

De um ponto de vista técnico, localizar um script significa que haverá uma nova tag <script> adicionada logo antes dos scripts registrados, que contém o objeto _global_ JavaScript com o nome que você especificou durante a localização no segundo argumento. Isso significa que, se você adicionar um outro script que possui esse mesmo script como dependência, você poderá usar o mesmo objeto _global_ no novo script sem problemas. O WordPress trabalha muito bem com encadeamento de dependências.

Vamos localizar um script.

  1. add_action( 'wp_enqueue_scripts', 'register_localize_and_enqueue_a_script' );
  2. function register_localize_and_enqueue_a_script() {
  3. wp_register_script(
  4. 'my-script',
  5. get_template_directory_uri().'/js/functions.js',
  6. array( 'jquery' ),
  7. filemtime( get_template_directory().'/js/functions.js' ),
  8. true
  9. );
  10. wp_localize_script(
  11. 'my-script',
  12. 'scriptData',
  13. // Estes são os dados, que irão ser mandados para o arquivo JavaScript.
  14. array(
  15. 'alertText' => 'Are you sure you want to do this?',
  16. )
  17. );
  18. wp_enqueue_script( 'my-script' );
  19. }

No arquivo de javascript, os dados estão disponíveis através do objeto especificado durante o processo de localização.

  1. ( function( $, plugin ) {
  2. alert( plugin.alertText );
  3. } )( jQuery, scriptData || {} );

Remover os importes e registros padrão do WordPress

Você pode remover um registro ou um importe através das funções wp_deregister_script() e wp_dequeue_script().

AJAX

WordPress oferece endpoints no servidor para requisições AJAX, localizado em wp-admin/admin-ajax.php. Vamos configurar um endpoint no servidor para manipulação AJAX.

  1. // É acionado quando o usuário está logado no Painel.
  2. add_action( array( 'wp_ajax_nopriv_create_new_post', 'wp_ajax_create_new_post' ), 'wp_ajax_create_new_post_handler' );
  3. function wp_ajax_create_new_post_handler() {
  4. // Este é um dado que não foi filtrado, validado e tratado.
  5. $data = $_POST['data'];
  6. // Faz coisas aqui.
  7. // Por exemplo: Insere ou atualiza um post.
  8. $post_id = wp_insert_post( array(
  9. 'post_title' => $data['title'],
  10. ) );
  11. // Se tudo der certo, insira qualquer tipo de dado para o callback do JavaScript.
  12. // Neste exemplo, wp_insert_post() retorna a ID de último post criado.
  13. // Isso adiciona um `exit`/`die` por si só, então não há necessidade de ser chamada.
  14. if ( ! is_wp_error( $post_id ) ) {
  15. wp_send_json_success( array(
  16. 'post_id' => $post_id,
  17. ) );
  18. }
  19. // Se alguma coisa der errado, a última parte será passada e só então executada:
  20. wp_send_json_error( array(
  21. 'post_id' => $post_id,
  22. ) );
  23. }
  24. add_action( 'wp_enqueue_scripts', 'register_localize_and_enqueue_a_script' );
  25. function register_localize_and_enqueue_a_script() {
  26. wp_register_script(
  27. 'my-script',
  28. get_template_directory_uri().'/js/functions.js',
  29. array( 'jquery' ),
  30. filemtime( get_template_directory().'/js/functions.js' ),
  31. true
  32. );
  33. // Manda os dados do PHP através de variáveis para o JavaScript.
  34. wp_localize_script(
  35. 'my-script',
  36. 'scriptData',
  37. array(
  38. 'ajax_url' => admin_url( 'admin-ajax.php' ),
  39. )
  40. );
  41. wp_enqueue_script( 'my-script' );
  42. }

Em seguida vem o JavaScript:

  1. ( function( $, plugin ) {
  2. $( document ).ready( function() {
  3. $.post(
  4. plugin.ajax_url,
  5. {
  6. // Os nomes especificados são os `triggers` correspondentes aos hookers
  7. // wp_ajax_* e wp_ajax_nopriv_* do lado do servidor.
  8. action : 'create_new_post',
  9. // Encapsula todos os dados do lado do servidor em um objeto.
  10. data : {
  11. title : 'Hello World'
  12. }
  13. },
  14. function( response ) {
  15. // wp_send_json_success() define a propriedade "sucsess" para verdadeiro
  16. if ( response.success ) {
  17. // Qualquer dado que passou pela função wp_send_json_sucesess(), está disponível na propriedade "data".
  18. alert( 'A post was created with an ID of ' + response.data.post_id );
  19. // wp_send_json_error() define a propriedade "sucsess" para falso.
  20. } else {
  21. alert( 'There was a problem creating a new post.' );
  22. }
  23. }
  24. );
  25. } );
  26. } )( jQuery, scriptData || {} );

ajax_url representa o endpoint do admin via AJAX, que é automaticamente definida na página do Admin, mas não no front-end.

Vamos localizar nosso script para incluir a URL do admin:

  1. add_action( 'wp_enqueue_scripts', 'register_localize_and_enqueue_a_script' );
  2. function register_localize_and_enqueue_a_script() {
  3. wp_register_script( 'my-script', get_template_directory_uri() . '/js/functions.js', array( 'jquery' ) );
  4. // Manda os dados do PHP através de variáveis para o JavaScript.
  5. $data_for_script = array( 'ajax_url' => admin_url( 'admin-ajax.php' ) );
  6. wp_localize_script( 'my-script', 'scriptData', $data_for_script );
  7. wp_enqueue_script( 'my-script' );
  8. }

JavaScript com WP AJAX

Existe várias maneiras de fazermos isto. A maneira mais comum é usar $.ajax(). É claro que existem atalhos disponíveis como $.post() e $.getJSON().

Aqui esta um exemplo padrão.

  1. /*globals jQuery, $, scriptData */
  2. ( function( $, plugin ) {
  3. "use strict";
  4. // Variação do jQuery.ajax()
  5. // Você também pode usar o $.post(), $.getJSON() se quiser
  6. // Eu prefiro declarar explicitamente o carregamento & as promessas descritas abaixo
  7. $.ajax( {
  8. url : plugin.ajaxurl,
  9. data : {
  10. action : plugin.action,
  11. _ajax_nonce : plugin._ajax_nonce,
  12. // Objeto-Global do WordPress
  13. // É mostrado apenas no "admin"
  14. postType : typenow,
  15. },
  16. beforeSend : function( d ) {
  17. console.log( 'Before send', d );
  18. }
  19. } )
  20. .done( function( response, textStatus, jqXHR ) {
  21. console.log( 'AJAX done', textStatus, jqXHR, jqXHR.getAllResponseHeaders() );
  22. } )
  23. .fail( function( jqXHR, textStatus, errorThrown ) {
  24. console.log( 'AJAX failed', jqXHR.getAllResponseHeaders(), textStatus, errorThrown );
  25. } )
  26. .then( function( jqXHR, textStatus, errorThrown ) {
  27. console.log( 'AJAX after finished', jqXHR, textStatus, errorThrown );
  28. } );
  29. } )( jQuery, scriptData || {} );

Perceba que o exemplo acima usa _ajax_nonce para verificar o valor NONCE, o qual você terá de definir sozinho, quando for localizar o script. É só adicionar '_ajax_nonce' => wp_create_nonce( "some_value" ), no objeto array. Você então poderá adicionar um marcador nos seus callbacks do PHP, que se parecem um pouco com isso check_ajax_referer( "some_value" ).

Trabalhando com AJAX e Eventos

Na verdade é muito simples executar uma requisição AJAX por cliques (ou qualquer outro tipo de interação do usuário) em algum elemento. Apenas envolva a sua chamada $.ajax() (ou algum de seu similares). Você pode ainda, adicionar um delay na requisição.

  1. $( '#' + plugin.element_name ).on( 'keyup', function( event ) {
  2. $.ajax( { ... etc ... } )
  3. .done( function( ... ) { etc }
  4. .fail( function( ... ) { etc }
  5. } )
  6. .delay( 500 );

Multiplos callbacks para uma única requisição AJAX

Você pode acabar caindo em uma situação da qual multiplas tarefas acontecem depois de que uma requisição AJAX é finalizada. Felizmente jQuery retorna um objeto, onde você pode anexar todos os seus callbacks.

  1. /*globals jQuery, $, scriptData */
  2. ( function( $, plugin ) {
  3. "use strict";
  4. // Variação do jQuery.ajax()
  5. // Você também pode usar o $.post(), $.getJSON() se quiser
  6. // Eu prefiro declarar explicitamente o carregamento & as promessas
  7. var request = $.ajax( {
  8. url : plugin.ajaxurl,
  9. data : {
  10. action : plugin.action,
  11. _ajax_nonce : plugin._ajax_nonce,
  12. // Objeto-Global do WordPress
  13. // É mostrado apenas no "admin"
  14. postType : typenow,
  15. },
  16. beforeSend : function( d ) {
  17. console.log( 'Before send', d );
  18. }
  19. } );
  20. request.done( function( response, textStatus, jqXHR ) {
  21. console.log( 'AJAX callback #1 executed' );
  22. } );
  23. request.done( function( response, textStatus, jqXHR ) {
  24. console.log( 'AJAX callback #2 executed' );
  25. } );
  26. request.done( function( response, textStatus, jqXHR ) {
  27. console.log( 'AJAX callback #3 executed' );
  28. } )
  29. } )( jQuery, scriptData || {} );

Encadeamento de Callbacks

Um cenário comum (do qual muitas vezes um callback é necessário e como ele é simples de ser utilizado), é o encadeamento de callbacks quando uma requisição AJAX é finalizada.

Vamos dar uma olhada no problema primeiro:

O callback (A) é executado.
O callback (B) não sabe que deve esperar por (A).
Você não pode ver o problema na sua instalação local se (A) terminar rapidamente.

A grande questão é, quando nós devemos esperar (A) finalizar, para só então, inicializarmos o processo de (B).

A resposta é que o processo é “adiado” carregando suas “promessas”, também conhecido como “futuros”.

Veja um exemplo:

  1. ( function( $, plugin ) {
  2. "use strict";
  3. $.when(
  4. $.ajax( {
  5. url : pluginURl,
  6. data : { /* ... */ }
  7. } )
  8. .done( function( data ) {
  9. // 2nd call finished
  10. } )
  11. .fail( function( reason ) {
  12. console.info( reason );
  13. } );
  14. )
  15. // Novamente, você poderia utliziar o método .done() se quisesse. Veja a documentação do jQuery.
  16. .then(
  17. // Sucesso
  18. function( response ) {
  19. // Has been successful
  20. // In case of more then one request, both have to be successful
  21. // Sucesso! Em caso de mais de uma requisição, ambos deverão ser bem sucedidos.
  22. },
  23. // Falhou
  24. function( resons ) {
  25. // É jogado um erro, em caso de multiplos erros, é o primeiro que é cuspido.
  26. },
  27. );
  28. //.then( /* and so on */ );
  29. } )( jQuery, scriptData || {} );

Fonte: WordPress.StackExchange / Kaiser