admin管理员组文章数量:1122792
I'm looking to dynamically change the page-comments option based on whether the user clicks a URL. I have two functions to do this:
function psb_comment_listener_func(){
echo "
<script>
function myFunction(event) {
event.preventDefault();
console.log('in my function');
'<?php echo do_shortcode(\"[psb_all_comments]\"); ?>';
}
console.log('in the listener');
document.getElementsByClassName('nav-previous')[0].onclick = function() {myFunction(event)};
</script>
";
}
add_filter( 'learn-press/after-content-item-summary/lp_lesson', 'psb_comment_listener_func');
function psb_all_comments_func(){
echo "
<script>
console.log('in the shortcode');
</script> ";
update_option('page_comments', false);
}
add_shortcode( 'psb_all_comments', 'psb_all_comments_func');
The plan is that the listener catches the onclick and the function then stops the hyperlink from happening and calls the shortcode to update_option for page_comments. I have two problems:
Problem 1: If I copy and paste the javascript
function myFunction(event) {
event.preventDefault();
console.log('in my function');
'<?php echo do_shortcode(\"[psb_all_comments]\"); ?>';
}
console.log('in the listener');
document.getElementsByClassName('nav-previous')[0].onclick = function() {myFunction(event)};
into the browser console and press enter. The "in the listener" message appears (this is good) when the link ('older comments') is clicked the "in my function" appears (this is also good). But the call to the other function via the shortcode doesnt happen. There is no "in the shortcode" message. What am I missing here ?
Problem 2: None of it works when called from within the PHP function file. It only works in the browser console. Again, what am I missing ? Thanks Paul.
This is where I'm at now
PHP code
function psb_register_script() {
wp_register_script(
'psb_navprev',
plugin_dir_url( __FILE__ ).'/js/psb_navprev.js',
array(),
wp_get_theme()->get( 'Version' ),
array(
'strategy' => 'defer',
'in_footer' => true,
)
);
}
function psb_enqueue_script() {
//if ( is_singular( 'lp_course' ) ) {
wp_enqueue_script( 'psb_navprev', plugin_dir_url( __FILE__ ).'/js/psb_navprev.js',array('jquery'), '1.0', true );
//localize script
wp_localize_script( 'psb_navprev', 'psb_object',
array(
'ajax_url' => admin_url( 'admin-ajax.php' ),
'nonce' => wp_create_nonce('psb-nonce'),
)
);
//}
}
//register and enqueue script
add_action( 'wp_enqueue_scripts', 'psb_register_script' );
add_action( 'template_redirect', 'psb_enqueue_script' );
add_action( 'wp_ajax_nopriv_psb_comment_cmd', 'psb_comment_cmd' );
add_action( 'wp_ajax_psb_comment_cmd', 'psb_comment_cmd' );
function psb_comment_cmd(){
echo " <script> console.log('in the handler'); </script> ";
check_ajax_referer( 'psb-nonce', 'nonce' ); // Check the nonce.
if (isset($_POST['psb_comment_cmd'])) {
//psb_all_comments()
echo " <script> console.log('comment => all'); </script> ";
wp_die(); // clean up
}
}
function psb_all_comments_func(){
echo "
<script>
console.log('in the update function');
</script> ";
update_option('page_comments', false);
}
// clicky-script.js
(function(){
const navPrevElement = document.querySelector('.nav-previous');
if (navPrevElement) {
navPrevElement.addEventListener('click', function(event){
console.log('in the clicky script');
event.preventDefault();
jQuery(document).ready(function($) {
$.ajax({
url:psb_object.ajax_url,
type: "post",
contentType: "json",
dataType: "json",
data: {action: "psb_comment_cmd"},
success: function(msg) {
console.log("AJAX success");
},
error: function() {
console.log("AJAX fail");
}
})
});
});
}
})();
Final resolution :-)
PHP
add_action ('rest_api_init', function() {
register_rest_route('psb/v1', 'posts', [
'methods' => 'GET',
'callback' => 'psb_posts',
]);
});
function psb_posts() {
update_option('page_comments', false);
return 'in the posts callback';
}
Javascript
// clicky-script.js
(function(){
const navPrevElement = document.querySelector('.nav-previous');
if (navPrevElement) {
navPrevElement.addEventListener('click', function(event){
console.log('in the clicky script');
event.preventDefault();
const apiUrl = window.location.origin + '/wp-json/psb/v1/posts';
fetch(apiUrl)
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then(data => {
console.log(data); // set comment count
location.reload(); // refresh the page
})
.catch(error => {
console.error('API Error:', error);
});
});
};
})();
I'm looking to dynamically change the page-comments option based on whether the user clicks a URL. I have two functions to do this:
function psb_comment_listener_func(){
echo "
<script>
function myFunction(event) {
event.preventDefault();
console.log('in my function');
'<?php echo do_shortcode(\"[psb_all_comments]\"); ?>';
}
console.log('in the listener');
document.getElementsByClassName('nav-previous')[0].onclick = function() {myFunction(event)};
</script>
";
}
add_filter( 'learn-press/after-content-item-summary/lp_lesson', 'psb_comment_listener_func');
function psb_all_comments_func(){
echo "
<script>
console.log('in the shortcode');
</script> ";
update_option('page_comments', false);
}
add_shortcode( 'psb_all_comments', 'psb_all_comments_func');
The plan is that the listener catches the onclick and the function then stops the hyperlink from happening and calls the shortcode to update_option for page_comments. I have two problems:
Problem 1: If I copy and paste the javascript
function myFunction(event) {
event.preventDefault();
console.log('in my function');
'<?php echo do_shortcode(\"[psb_all_comments]\"); ?>';
}
console.log('in the listener');
document.getElementsByClassName('nav-previous')[0].onclick = function() {myFunction(event)};
into the browser console and press enter. The "in the listener" message appears (this is good) when the link ('older comments') is clicked the "in my function" appears (this is also good). But the call to the other function via the shortcode doesnt happen. There is no "in the shortcode" message. What am I missing here ?
Problem 2: None of it works when called from within the PHP function file. It only works in the browser console. Again, what am I missing ? Thanks Paul.
This is where I'm at now
PHP code
function psb_register_script() {
wp_register_script(
'psb_navprev',
plugin_dir_url( __FILE__ ).'/js/psb_navprev.js',
array(),
wp_get_theme()->get( 'Version' ),
array(
'strategy' => 'defer',
'in_footer' => true,
)
);
}
function psb_enqueue_script() {
//if ( is_singular( 'lp_course' ) ) {
wp_enqueue_script( 'psb_navprev', plugin_dir_url( __FILE__ ).'/js/psb_navprev.js',array('jquery'), '1.0', true );
//localize script
wp_localize_script( 'psb_navprev', 'psb_object',
array(
'ajax_url' => admin_url( 'admin-ajax.php' ),
'nonce' => wp_create_nonce('psb-nonce'),
)
);
//}
}
//register and enqueue script
add_action( 'wp_enqueue_scripts', 'psb_register_script' );
add_action( 'template_redirect', 'psb_enqueue_script' );
add_action( 'wp_ajax_nopriv_psb_comment_cmd', 'psb_comment_cmd' );
add_action( 'wp_ajax_psb_comment_cmd', 'psb_comment_cmd' );
function psb_comment_cmd(){
echo " <script> console.log('in the handler'); </script> ";
check_ajax_referer( 'psb-nonce', 'nonce' ); // Check the nonce.
if (isset($_POST['psb_comment_cmd'])) {
//psb_all_comments()
echo " <script> console.log('comment => all'); </script> ";
wp_die(); // clean up
}
}
function psb_all_comments_func(){
echo "
<script>
console.log('in the update function');
</script> ";
update_option('page_comments', false);
}
// clicky-script.js
(function(){
const navPrevElement = document.querySelector('.nav-previous');
if (navPrevElement) {
navPrevElement.addEventListener('click', function(event){
console.log('in the clicky script');
event.preventDefault();
jQuery(document).ready(function($) {
$.ajax({
url:psb_object.ajax_url,
type: "post",
contentType: "json",
dataType: "json",
data: {action: "psb_comment_cmd"},
success: function(msg) {
console.log("AJAX success");
},
error: function() {
console.log("AJAX fail");
}
})
});
});
}
})();
Final resolution :-)
PHP
add_action ('rest_api_init', function() {
register_rest_route('psb/v1', 'posts', [
'methods' => 'GET',
'callback' => 'psb_posts',
]);
});
function psb_posts() {
update_option('page_comments', false);
return 'in the posts callback';
}
Javascript
// clicky-script.js
(function(){
const navPrevElement = document.querySelector('.nav-previous');
if (navPrevElement) {
navPrevElement.addEventListener('click', function(event){
console.log('in the clicky script');
event.preventDefault();
const apiUrl = window.location.origin + '/wp-json/psb/v1/posts';
fetch(apiUrl)
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then(data => {
console.log(data); // set comment count
location.reload(); // refresh the page
})
.catch(error => {
console.error('API Error:', error);
});
});
};
})();
Share
Improve this question
edited May 19, 2024 at 1:30
pbee
asked May 14, 2024 at 7:34
pbeepbee
52 bronze badges
1 Answer
Reset to default 1I'm afraid the code you've shared is rather wonky and there isn't just one thing that is backwards. Here are the first few things that came into my mind.
add_filter( 'learn-press/after-content-item-summary/lp_lesson', 'psb_comment_listener_func');
When you attach a callback function to a filter with add_filter
, the callback should return a value. If the callback isn't supposed to return anything, but for example print something on the screen, then you should generally use add_action
to hook the callback to an action. echo
ing inside a filter may cause unexpected results as the printed content may not appear in the intended place.
function psb_all_comments_func() {...}
The shortcode callback is also supposed to return a string
and not echo
anything. As noted on the Shortcode API Codex page, "..anything that is echoed will be output to the browser, but it won't appear in the correct place on the page..".
Another problematic thing is calling update_option()
inside the shortcode callback. The option is updated every time the shortcode is evaluated and executed whether the user clicked anything or not.
As there isn't any additional details about the option, I assume it is a global option with a single boolean value. Based on this assumption update_option()
poses another issue. Unless there is other code, or manual admin intervention, to toggle the option back to true
, then its value is set to false
for everyone until the end of time when the shortcode is executed the first time.
myFunction(event) {...}
When copying and pasting the script to the browser console '<?php echo do_shortcode(\"[psb_all_comments]\"); ?>';
is evaluated as a plain string, not PHP, and that is why it doesn't do anything. PHP is a server side language and you can't execute it with javascript on the frontend.
What to do instead?
I recommend splitting the code into smaller parts by the different responsibilities. Something along these lines,
- A separate script file to house the js clicky thing
- A PHP function to register the script file for later when needed
- A custom WP REST API endpoint and a controller (or admin-ajax.php handler, if you're not into WP REST API) for receiving js requests and toggling settings in the backend
- A callback attached to suitable action for determining, if the script file should be enqueued or not
The script file.
// clicky-script.js
(function(){
const navPrevElement = document.querySelector('.nav-previous');
if (navPrevElement) {
navPrevElement.addEventListener('click', function(event){
// do something e.g.
// hide element with js
// or send ajax request to REST endpoint or admin-ajax.php
});
}
})();
The PHP stuff.
// e.g. functions.php
add_action( 'wp_enqueue_scripts', 'wpse_425194_register_script' );
function wpse_425194_register_script() {
wp_register_script(
'wpse_425194_clicky_script',
get_template_directory_uri() .'/assets/clicky-script.js',
array(),
wp_get_theme()->get( 'Version' ),
array(
'strategy' => 'defer',
'in_footer' => true,
)
);
}
add_action( 'template_redirect', 'wpse_425194_enqueue_script' );
function wpse_425194_enqueue_script() {
if ( is_singular( 'my-post-type' ) ) {
wp_enqueue_script( 'wpse_425194_clicky_script' );
}
}
See WP REST API Handbook or Ajax documentation for registering the backend handler.
本文标签: phpCalling a function via a shortcode in javascript
版权声明:本文标题:php - Calling a function via a shortcode in javascript 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1736306717a1933059.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论