通过AJAX请求将WordPress短代码插入JS



我正在尝试将WordPress短代码插入JS中,但到目前为止还没有成功。我发现了一些jQuery代码,我需要将其翻译成香草JS,我很确定我没有做正确的事情,因为它不起作用。我不完全理解我遇到的代码,这意味着我需要一些帮助来了解我哪里出了问题,以及为什么我的短代码没有显示在我的网站上。也许PHP代码没有正确地链接到JS文件,我不太确定。

我们的目标是让快捷代码(在这种情况下是WP形式(在点击时显示在模态中。非常感谢任何帮助!

以下是jQuery代码(AJAX请求(:

$.ajax({
url: `<?php echo admin_url('admin-ajax.php'); ?>`,
type: "GET",
data: {
action: "runThisPhpFunction",
},
success: function (data) {
$("#trigger_target").html(data);
},
});

这是我的JS模态代码,我正试图将短代码放入其中:

function newsletterModal() {
const ajaxurl = `<?php echo admin_url('admin-ajax.php'); ?>`;
const btn = document.querySelector("#menu-item-2745");
btn.setAttribute("id", "trigger_my_shortcode");
const modal = document.createElement("div");
modal.setAttribute("id", "trigger_target");
modal.classList.add("modal");
modal.innerHTML = `<div class="modal-content">
<span class="close">&times;</span>
<h2>Sign up to our newsletter</h2>
<h5>And get hold of your 10% discount!</h5>
<p>insert [wpforms id="1703"] here</p>
</div>`;

btn.onclick = function (e) {
e.preventDefault();
modal.style.display = "block";
document
.querySelector("#trigger_my_shortcode")
.addEventListener("click", (e) => {
e.preventDefault();
fetch(ajaxurl, {
type: "GET",
data: {
action: "runThisPhpFunction",
},
success: function (data) {
document.querySelector("#trigger_target").html(data);
},
});
});
};
modal.querySelector(".close").onclick = function () {
modal.style.display = "none";
};
window.onclick = function (e) {
if (e.target == modal) {
modal.style.display = "none";
}
document.body.appendChild(modal);
};
}

函数.php代码:

function runThisPhpFunction() {
if ( isset($_REQUEST) ) {

echo do_shortcode( '[wpforms id="1703"]' );

}
die();
}
add_action( 'wp_ajax_runThisPhpFunction', 'runThisPhpFunction' );
add_action( 'wp_ajax_nopriv_runThisPhpFunction', 'runThisPhpFunction' );

您的代码有很多问题,所以答案不会很短。通常,将代码拆分为较小的函数是一种很好的做法,这些函数都有其特定的用途。因此,我冒昧地重写了一些函数,这样它们将帮助您达到需要的目的。

下面的代码如下所示:buildModal函数为您的模态构建所有HTML,并可以将form作为参数。form应该是文本,因为它需要与同一字符串中的其他元素进行插值(组合(。

buildModal函数将从getFormAndBuildModal函数中调用。getFormAndBuildModal函数使用fetch向服务器发送请求,并将响应解释为文本。此文本是您的表单,它将被传递给buildModal,以构建包含表单的模态。

带有#menu-item-2745的按钮将触发发送请求和构建表单。

以这种方式工作意味着,每次单击按钮时,它都会调用服务器,构建一个新的模态并将其显示在页面上。然后,当关闭模态时,它会从页面中删除该模态。

我试图尽可能多地解释代码中发生的事情以及每一步都在做什么。如果有些事情还不清楚,请告诉我,我会尽力澄清的。

function buildModal(form) {
const modal = document.createElement("div");
modal.id = "trigger_target"
modal.classList.add("modal");
/**
* Create close button here so we can attach the 
* event listener without having to select it later.
*/
const modalClose = document.createElement("span");
modalClose.classList.add("close");
modalClose.addEventListener("click", function() {
/**
* Remove the modal completely from the document.
* This isn't mandatory and you can change it if you'd like.
*/
modal.remove();
});
const modalContent = document.createElement("div");
modalContent.classList.add("modal-content");
/**
* The form will be a string of HTML that gets injected
* into another string of HTML here below. The innerHTML setter
* will then parse the entire string, with form, to HTML.
*/
modalContent.innerHTML = `
<div class="modal-content">
<h2>Sign up to our newsletter</h2>
<h5>And get hold of your 10% discount!</h5>
<p>${form}</p>
</div>`;
/**
* First append the close button, then the content.
*/
modal.append(modalClose, modalContent);
/**
* Return the HTML modal element.
*/
return modal;
}

在这里,我添加了如何在JavaScript中使用PHP,以及如何通过选择按钮来解决这个问题。这个问题有两个解决方案,一个在第二个注释处,另一个解决方案在这个注释之后的PHP代码段中。

/**
* Check the PHP snippet at the bottom how this gets here.
* This is the result of the array turned into JSON and then
* placed into the document with wp_add_inline_script. 
*
* Sidenote: __wp__ looks ugly, but it will make sure that if 
* a browser might get updated and a new property is added to the
* window object, it will never overwrite or break anything because
* the name is so unique.
*/
const ajaxurl = __wp__.ajax;
/**
* Select the button and listen for the click event.
* When clicked, fire the getFormAndBuildModal function.
*
* Update: with selecting elements it is paramount that the element is
* above the <script> tag in the document. 
* Otherwise the element would not yet exist and the result would come up empty.
* Another way is to wait for the document to give a signal when every element has been rendered with the DOMContentLoaded event.
*/
// document.addEventListener('DOMContentLoaded', function(event) {
//  const button = document.querySelector("#menu-item-2745");
//  button.addEventListener("click", getFormAndBuildModal);
// });
const button = document.querySelector("#menu-item-2745");
button.addEventListener("click", function(event) {
event.preventDefault();
getFormAndBuildModal();
});
function getFormAndBuildModal() {
/**
* Fetch uses the GET method by default.
* All you need to do is to add the action to the URL
* so that WP knows what action to call on the server.
*/
fetch(`${ajaxurl}?action=runThisPhpFunction`)
/**
* Fetch can take while to load, so it uses a promise.
* With .then() we say what happens after fetch is finished.
* Fetch gives us a response object as a result, which we need to inspect.
*/
.then(response => {
/**
* If the response has gone wrong, show an error.
*/
if (!response.ok) {
throw new Error("runThisPhpFunction request has failed");
}
/**
* Otherwise we use the content that the response has send us.
* Currently the "body" (your form) of the response is just bits and bytes.
* We can tell the response how we want to use the response.
* With the .text() method we turn the raw data into a string.
* That string can later be used as HTML. :)
*/
return response.text();
})
/**
* response.text() also returns a promise, just like fetch. So to go to the next step
* we use another .then() function. In here we have our form in a string.
* Now we can build the modal and pass the form as an argument. The modal 
* will be build and the form turned into HTML and put in the correct position.
* When the buildModal function is done it returns the result.
* Now append it to the body and it's done.
*/ 
.then(form => {
const modal = buildModal(form);
document.body.append(modal);
});
}

在这里,我又添加了一些内容来对脚本进行排队,以及如何以正确的方式将PHP转换为JavaScript。(

function enqueue_my_custom_script() {
/**
* Instead of printing PHP variables directly inside JavaScript, 
* you could use this method to let PHP do that for you. 
* The array here below we be turned into a JSON string, 
* which will later be turned into a JavaScript object that you
* can use in your main script.
*/
$wp_js_data = json_encode( 
array(
'ajax' => admin_url( 'admin-ajax.php' ),
)
);
/**
* The last parameter of wp_register_script (there are 5) will
* determine if the script will be placed in the <head> tag when 
* the value is false, or before the end of the </body> tag when
* the value is true. The latter will make sure that your JS executes
* AFTER all other HTML elements have been rendered. With this you don't
* have to listen for the DOMContentLoaded event in JavaScript.
*
* Use get_stylesheet_directory_uri() to get the path to your child
* theme directory instead of hard linking to your sheet. This will
* output the URL to the directory of your style.css file of your theme.
*/
wp_register_script( "scriptjs", get_stylesheet_directory_uri() . "/script.js", array(), null, true );
/**
* Here we create a global variable on the window object. This makes
* the data is available in every JavaScript file. Here we insert the JSON string
* that will be turned into a usable JS object.
*
* Be sure to output this script BEFORE the "scriptjs" file.
*/
wp_add_inline_script( "scriptjs", "window.__wp__ = {$wp_js_data}", "before" );
/**
* This used to be the first line. wp_register_script only registers
* the script but does not output it. This enables you to do something
* like wp_add_inline_script before outputting the script.
* wp_enqueue_script makes sure that the registered script will be 
* placed in the document.
*/
wp_enqueue_script( "scriptjs" );
} 
add_action( "wp_enqueue_scripts", "enqueue_my_custom_script" );

最新更新