The specific problem
The global variable js_global
is not defined on the page. It seems to me that you are loading the template without using the query ?js_global=1
there the check in template_redirect
passes hit and the variable is not available.
That said: this implementation is not legal. It looks like a mix of two different methods without a specific gain.
How to make Ajax in WordPress the right way:
Before you begin: there are some right ways.
The most common is to make requests directly to the wp-admin/admin-ajax.php
file and receive them on the server side using the wp_ajax_{nome_da_funcao}
and wp_ajax_nopriv_{nome_da_funcao}
hooks. This is the recommended method in Codex and in numerous other online resources. I learned using this link many years ago, and is still current. This method has the disadvantage of not being cacheable, with each request it loads the entire back end. It was primarily developed to be used in the back end, but also works on the front if the volume of requests is small.
Less common but also very useful is to use the Rewrite API to create specific endpoints and treat the data there. This method is 100% cacheable because it works by stopping loading early, and works well with higher traffic sites for front-end requests.
When WordPress 4.7 leaves there will also be the native REST API and that's another conversation and that's going to stay much more interesting.
For now we will see how to implement this same code using methods 1 and 2. In both cases we will use the same form:
<form>
<input type="text" id="dados" />
<?php wp_nonce_field( 'recebe_dados', 'nonce' ); ?>
<input type="submit" name="Enviar" id="botao" />
</form>
Method 1, using
admin-ajax.php
:
add_action( 'wp_enqueue_scripts', 'registrar_e_chamar_scripts' );
// wp_ajax_{nome} roda somente quando o usuário está logado
add_action( 'wp_ajax_funcao_que_recebe_os_dados', 'funcao_que_recebe_os_dados' );
// wp_ajax_nopriv_{nome} roda somente quando o usuário não está logado
add_action( 'wp_ajax_nopriv_funcao_que_recebe_os_dados', 'funcao_que_recebe_os_dados' );
/**
* Essa é função que define os arquivos js a serem usados e as variáveis globais
* que estarão disponíveis
* @hook wp_enqueue_scripts
*/
function registrar_e_chamar_scripts() {
// O primeiro passo é determinar em qual arquivo está o nosso javascript,
// se ele tem alguma dependência, usa um numero de versão e se deve ser
// declarado em <head> ou ao final do HTML. wp_register_script
wp_register_script( 'nosso_js',
get_template_directory_uri() . '/js/nosso.js',
array( 'jquery' ), false, true );
// Uma vez registrado, colocamos na fila para ser inserido no tema.
// wp_enqueue_script() se encarrega de chamar o jQuery antes do nosso
// arquivo pra que as funções estejam disponíveis. wp_enqueue_script
wp_enqueue_script( 'nosso_js' );
// Agora vamos criar um objeto global 'nosso_js' para uso com o script,
// ele terá uma referência à url que precisamos chamar
// wp_localize_script
wp_localize_script( 'nosso_js', 'nosso_js',
array( 'ajax' => admin_url( 'admin-ajax.php' ) ) );
}
/**
* Essa é a função que será chamada pelo Ajax. O arquivo admin_ajax age como
* roteador junto com as actions definidas e traz as requisições para serem
* recebidas aqui
*
* @hook wp_ajax_funcao_que_recebe_os_dados
* @hook wp_ajax_nopriv_funcao_que_recebe_os_dados
*/
function funcao_que_recebe_os_dados() {
// A primeira coisa a fazer é tratar o input do usuário
$request = stripslashes_deep( $_POST );
if ( ! wp_verify_nonce( $request['nonce'], 'recebe_dados' ) ) {
wp_send_json_error('Nonce inválido');
}
// Se necessário também faça um check de permissões para o usuário
if ( ! current_user_can( 'edit_posts' ) ) {
wp_send_json_error('Usuário não tem permissões suficientes');
}
// Por fim, trate o request como desejar e envie a resposta
$resposta = funcao_que_produz_a_resposta( $request['dados'] );
// wp_send_json, wp_send_json_success e wp_send_json_error são funções
// padrão para retornar valores via Ajax. Elas se encarregam de enviar
// os cabeçalhos corretos e transformar os valores em JSON
wp_send_json( $resposta );
}
in the file nosso.js
:
jQuery(document).ready(function () {
jQuery('#botao').on('click', function(e){
e.preventDefault();
jQuery.ajax({
url: nosso_js.ajax,
type: 'POST',
data: {
'action': 'funcao_que_recebe_os_dados',
'nonce': jQuery('#nonce').val(),
'dados': jQuery('#dados').val()
},
success: function(response){
// fazer alguma coisa com a resposta
console.log(response);
}
});
});
});
Method 2, using
Rewrite API
:
no functions.php
add_action( 'init', 'criar_endpoints' );
add_action( 'template_redirect', 'funcao_que_recebe_os_dados' );
/**
* Registra os novos endpoints. Qualquer alteração nessa função deve ser
* seguida de uma limpeza nos permalinks. Basta salvar os permalinks novamente
* pelo painel.
*/
function criar_endpoints() {
// adiciona um parâmetro "dados" às variáveis interpretadas nativamente
add_rewrite_tag( '%dados%', '([0-9]+)' );
// opcional, permite chamadas para URLs específicas tipo /api/dados/dado1
// (ao invés de ?dados=dado1), para deixar as URLs mais amigáveis.
// Não está sendo usado no exemplo.
add_rewrite_rule( 'api/dados/([0-9]+)/?', 'index.php?dados=$matches[1]', 'top' );
}
/**
* Recebe e responde às requisições
*/
function funcao_que_recebe_os_dados() {
global $wp_query;
$dados = $wp_query->get( 'dados' );
$nonce = $_GET['nonce'];
if ( empty( $dados ) || empty( $nonce ) ) {
return;
}
// Conferindo o nonce
if ( ! wp_verify_nonce( $nonce, 'recebe_dados' ) ) {
wp_send_json_error('Nonce inválido');
}
// Conferindo permissões
if ( ! current_user_can( 'edit_posts' ) ) {
wp_send_json_error('Usuário não tem permissões suficientes');
}
$dados = stripslashes_deep( $dados );
$resposta = funcao_que_produz_a_resposta( $dados );
// Enviando a resposta
wp_send_json( $resposta );
}
in the file nosso.js
:
jQuery(document).ready(function () {
jQuery('#botao').on('click', function(e){
e.preventDefault();
jQuery.ajax({
data: {
'nonce': jQuery('#nonce').val(),
'dados': jQuery('#dados').val()
},
success: function(response){
// fazer alguma coisa com a resposta
console.log(response);
}
});
});
});