我在WordPress网站工作,该网站有许多自定义帖子类型,并广泛使用高级自定义字段(ACF)。该网站还使用节点模块、从头开始的自定义代码和Git来支持预构建的主题和;“典型”;插件。我做的许多任务都涉及到使用已经编写的代码。
该网站是一家狩猎公司。我们有大陆、国家(有时在某些情况下称为目的地)、地方和推荐信——所有这些都是定制的帖子。其中没有一个使用任何分类法。通过ACF,推荐信已经有了自定义字段,将推荐信与相应的大陆、国家和地区连接起来。
我的问题很复杂,我会尽力解释的。
My goal创建一个Ajax过滤器,按大陆、国家和(最终)地点显示推荐信,无需插件。大陆和国家可以select
字段,并且只需要一个字段,也可以同时设置这两个字段。
该网站已经有一个几乎相同的版本,正在运行。它有下拉列表select
筛选其他自定义邮件类型(行程)之一的。我需要的就是这样,只是为了纪念而不是行程。该页是https://extraordinaryjourneys.com/plan-your-trip/itineraries/.
它使用NPM Select-custom 还有一些PHP和JS文件。我在下面列出了其中的两个。
What I have tried我已经为推荐制作了重复的行程文件,并试图使这些工作就像行程页面的工作示例一样。写起来可能更容易meta_queries
如果是这样的话,我需要一些指导,但我认为这会更容易。这些是文件,包括我注释掉的部分,因为它们与行程页面上的下拉列表相关,而不需要在这个推荐页面上,比如行程预算,或者因为这是我了解这一切如何运作的一部分。
Where I am stuck我已经将代码推送到了临时站点,您可以看到控制台错误。你能帮我解决api 404调用的故障吗?上面链接的已存在行程页面具有相同的内容,但没有错误。https://staging.extraordinaryjourneys.com/testimonial-troubleshooting 您可以单击选择的大陆或国家/地区,您将收到一个警报,该警报必须与api调用相关。这里的屏幕截图显示了您将在控制台中看到的内容。
如果还有什么要包括或补充的,我很乐意。
hero-filter-testimonials.js
import \'../elements/filter-results-grid\';
$(document).ready(function () {
const $body = $(\'body\');
const $filterTestimonials = $(\'.filter-testimonials\');
$body.on(\'click\', \'.btn-load-more\', function (e) {
$(e.currentTarget).hide();
getResults(null, parseInt(e.currentTarget.dataset.page));
});
$(\'.clear-all\').click(function () {
window.history.replaceState(null, null, \'#\');
triggerSearch(getParamsObject(), $filterTestimonials);
});
continentContainer.find(\'.custom-select__option\').on(\'click\', function (e) {
let continentId = e.currentTarget.dataset.value;
showCountriesOptions(continentId);
});
function showCountriesOptions(continentId = null) {
const $selectContainer = $filterTestimonials.find(\'#destination\').parent();
console.log(\'Line 38 hero-filter-testimonials.js: continentId: \' + continentId);
if (continentId) {
$selectContainer.find(\'.custom-select__option\').hide();
$selectContainer.find(".custom-select__option[data-continent=\'" + continentId + "\']").show();
} else {
$selectContainer.find(\'.custom-select__option\').not(\'[data-value="placeholder"]\').show();
}
}
function getResults(origin = null, page = 1) {
console.log("getResults(): " + getResults);
let data = {action: \'get_testimonial_results\'};
$filterTestimonials.find(\'.filter-panel\').hide();
const $select = $filterTestimonials.find(\'.custom-select\');
data = getDataFromSelectors(data, $select);
if (origin && origin === \'continent\') {
if (data[\'destination\']) {
delete data[\'destination\'];
resetSingleSelector($filterTestimonials.find(\'#destination\')[0]);
}
}
$filterTestimonials.find(\'#special_departures\').prop("checked");
console.log("Line below is log.data");
console.log(data);
console.log("Line below is dir.data");
console.dir(data);
updateUrl(data);
if (Object.keys(data).length === 1) {
getContainer().show();
getResultsContainer().hide();
$body.find(\'.clear-all-btn-container\').hide();
} else {
let $loader = $body.find(\'.filter-loader\');
$body.find(\'.clear-all-btn-container\').show();
getFilterResults(\'get_testimonial_results\', \'Testimonials\', data, $loader, page);
}
addBadges($filterTestimonials, [\'continent\']);
}
window.getResults = getResults;
let data = getParamsObject();
console.log("Line below is data");
console.table(data);
console.log("Line below is $filterTestimonials");
console.table($filterTestimonials);
// console.log(JSON.stringify($filterTestimonials,null,2));
triggerSearch(data, $filterTestimonials);
});
testimonials_results.php
这个页面进行自定义api调用,返回404,我不知道为什么。它还可以查询以获取推荐帖子
<?php
add_action(\'rest_api_init\', function () {
register_rest_route(\'ejourneysnineteen/v1\', \'/get_testimonial_results\', array(
\'methods\' => \'POST\',
\'callback\' => \'get_testimonial_results\',
\'permission_callback\' => function () {
return true;
}
));
});
function get_testimonial_results() {
$pageSize = $_REQUEST[\'pageSize\'] ?? 10;
$args = [
\'posts_per_page\' => $pageSize,
\'ignore_sticky_posts\' => 1,
\'post_type\' => \'testimonial\',
\'orderby\' => \'title\',
\'order\' => \'ASC\',
];
if (isset($_REQUEST[\'page\'])) {
$args[\'paged\'] = $_REQUEST[\'page\'];
}
if (isset($_REQUEST[\'continent\']) ||
isset($_REQUEST[\'destination\'])
// isset($_REQUEST[\'region\']) ||
// isset($_REQUEST[\'accommodation_type\']
) {
// $metaQueries = [\'relation\' => \'AND\'];
if (isset($_REQUEST[\'region\'])) {
$regions = explode(\',\', $_REQUEST[\'region\']);
$subquery = [
\'relation\' => \'OR\'
];
foreach ($regions as $region) {
$subquery[] = [
\'key\' => \'accommodation_region\',
\'value\' => $region,
\'compare\' => \'LIKE\'
];
}
$metaQueries[] = $subquery;
}
else {
if (isset($_REQUEST[\'destination\'])) {
$metaQueries[] = [
\'key\' => \'testimonial_country\',
\'value\' => $_REQUEST[\'destination\'],
\'compare\' => \'LIKE\',
];
}
else {
if (isset($_REQUEST[\'continent\'])) {
$metaQueries[] = [
\'key\' => \'testimonial_continent\',
\'value\' => $_REQUEST[\'continent\'],
\'compare\' => \'LIKE\',
];
}
}
}
$args = array_merge($args, [
\'meta_query\' => $metaQueries
]);
}
$result = [];
if (count($metaQueries) > 1) {
$query = new WP_Query($args);
foreach ($query->get_posts() as $post) {
$post_thumbnail_id = get_post_thumbnail_id($post);
$image_url = fly_get_attachment_image_src($post_thumbnail_id, [500, 500], true);
$result[] = [
\'link\' => get_the_permalink($post),
\'title\' => $post->post_title,
\'excerpt\' => html_entity_decode(ellipsis(get_the_excerpt($post), 80)),
\'image_url\' => $image_url,
\'category\' => \'Testimonial\'
];
}
}
wp_send_json_success([
\'results\' => $result,
\'total\' => $query->found_posts,
\'pages\' => $query->max_num_pages,
]);
}
还有其他文件,但我太困了,我不确定是否应该将它们全部添加到那里。这是否足以帮助我解决api调用404的故障?
最合适的回答,由SO网友:Sally CJ 整理而成
正如我在评论中所说,我向您的自定义端点发出了POST请求(here) 然后收到一条404错误消息:“No No No modHFGen.dll未找到与URL和请求方法匹配的路由“;,这可能意味着从未注册路由,或者请求方法不受支持,即不在methods
注册期间指定的列表(使用register_rest_route()
).
因此,您只需要确保正确注册了路由,并且(AJAX)请求使用了正确的HTTP请求方法,然后404错误就会消失。
在您的情况下,您可以通过加载testimonials_results.php
来自主题的functions.php
文件例如。
// Assuming the file is at the same level as the functions.php file
require_once __DIR__ . \'/testimonials_results.php\';
<代码中的其他问题
$metaQueries
变量未定义,应在
if (isset($_REQUEST[\'continent\']) ...)
线
在isset($_REQUEST[\'region\'])
应该not 被注释掉,否则如果region
参数,则您的自定义帖子查询将永远不会运行。
只有在以下情况下,上述帖子查询才会运行$metaQueries
有2个或更多项,因此如果数组为空或只有1个项,则$query
在您的return
part将是一个未定义的部分,并导致PHP通知中显示Undefined variable: query
.
这取决于你该如何解决。。但例如,您可以添加else
, 并返回一个错误。
当WP_Query
类使用非空的参数进行实例化,即。new WP_Query($args)
而不是new WP_Query()
, 这个get_posts()
方法将自动调用,因此不应手动调用它。
因此,请更换$query->get_posts()
具有$query->posts
访问/检索通过自动调用get_posts()
方法
来自REST API handbook:
重要的是,REST API路由的回调应该始终返回数据;它不应该试图发送响应主体本身。这确保了REST API服务器所做的额外处理,如处理链接/嵌入、发送标头等。换句话说,不要打电话die( wp_json_encode( $data )
); 或wp_send_json( $data )
.
所以不要打电话wp_send_json_success()
(使用wp_send_json()
), 而且很简单return 数据。一、 e。return [ \'results\' => $result, ... ];
WordPress有一个__return_true()
函数,因此您可以\'permission_callback\' => \'__return_true\'
:)
在$args = array_merge($args, [ \'meta_query\' => $metaQueries ]);
可以写为$args[\'meta_query\'] = $metaQueries;
..