你的代码有点复杂,所以我不能发布一个完整的工作代码,但概念验证,然后适应你的代码取决于你。
因此,WordPress中的Ajax应该通过Ajax API, 相反,要将请求发送到相同的url(当然是打印头)和其他内容,只需通过Ajax Api发送请求并输出所需内容即可。
我假设您有如下代码:
add_shortcode( \'festival\' , array( new Events_Controller, \'festival\' ) );
以及
festival()
方法
Events_Controller
将其归类为您发布的内容。似乎从shortcode获得的仅有2个参数是
\'collection_edition_id\'
和
\'name\'
所有其他参数(我猜)都是由
Events_Controller::initialize_params()
方法(可能基于请求)。
所以,如果你的Events_Controller::festival()
方法可以从shortcode以外的其他源获取参数,而不是以相同的方式执行其工作。查看此代码:
public function festival( Array $params = array() ) {
if ( ! $this->isAjax() ) ) {
$collection = isset( $params[\'collection_edition_id\'] )
? $params[\'collection_edition_id\']
: 0;
$festival = isset( $params[\'name\'] ) ? $params[\'name\'] : \'\' ;
} elseif ( empty( $params ) ) {
$collection = filter_input(INPUT_POST, \'collid\', FILTER_SANITIZE_NUMBER_INT);
$festival = filter_input(INPUT_POST, \'festival_name\', FILTER_SANITIZE_STRING);
}
if ( empty($collection) || ! is_numeric($collection) ) {
// WordPress Ajax API need to die() on end or will append a 0 to the response
if ( $this->isAjax() ) die();
return;
}
$this->initialize_params();
$this->initialize_api_client();
$date = array_key_exists( \'date\', $this->params )
? $this->params[\'date\']
: date( \'Y-m-d\' );
$category = $this->params[\'category\'];
$page = isset( $this->params[\'page\'] ) ? $this->params[\'page\'] : 1;
$events_by_festival = $this->api_client->from_day(
$date, $collection_edition, $category, $page
);
if ( ! $this->isAjax() ) ) {
wp_enqueue_script(
\'my_ajax_script\',
plugins_url( \'js/my_ajax.js\', __FILE__ ),
array(\'jquery\'), NULL, TRUE
);
$data = array( \'ajax_url\' => admin_url( \'admin-ajax.php\' ) );
wp_localize_script( \'my_ajax_script\', \'MyScriptData\', $data );
}
if( $this->isAjax() ) {
View::render(
"events/partials/_list.php", array( \'events\' => $events_by_festival )
);
// WordPress Ajax API need to die() on end or will append a 0 to the response
die();
} else {
return View::render(
"events/festival.html.php",
array(
\'date\' => $date,
\'category\' => $category,
\'festival\' => $festival,
\'collection\' => $collection, // <-- pass also the collection
\'page\' => $page, // <-- pass the page
\'events_by_festival\' => $events_by_festival
)
);
}
}
正如你所看到的,我
$params
参数可选,我可以通过POST ajax请求而不是通过短代码ATT发送到方法集合id和节日名称,结果是您可以在短代码之外运行该方法。
我也用过wp_enqueue_script
要在页脚中添加javascript文件,并且在该文件中(我假设是相对于插件文件夹的“js/my\\u ajax.js”),您应该放置代码来触发ajax调用。
最终使用wp_localize_script
我向该脚本发送了一个变量:MyScriptData
将包含在ajax_url
属性的正确url\'admin-ajax.php\'
(即,在该脚本中,您可以使用MyScriptData.ajax_url
访问url)。
这种方法现在变得非常“简单”;“大型”;而且可能最好将其拆分为多个部分,例如javascript内容可以放在另一个方法中,就像渲染内容一样。
现在,您必须创建ajax api调用来运行该方法:
add_action( \'wp_ajax_myplugin_festival\', array( new Events_Controller, \'festival\' ) );
add_action( \'wp_ajax_nopriv_myplugin_festival\', array( new Events_Controller, \'festival\' ) );
前面的代码表示当您将请求发送到
admin-ajax.php
哪里
$_REQUEST[\'action\']
等于
\'myplugin_festival\'
(位于“wp\\u ajax\\u”和“wp\\u ajax\\u nopriv”之后的部分)然后
Events_Controller::festival
由WordPress调用。
因此,您唯一需要做的就是向发送POST请求admin-ajax.php
哪里\'action\', \'collid\' 和\'festival_name\' POST变量设置正确。
然而,“action”必须硬编码为“myplugin\\u festival”,但是“collid”和“festival\\u name”应该根据短代码显示的内容进行设置:最简单的方法是设置一个data-
由快捷码打印的html标记内的参数。
在OP中,您没有发布模板,因此我不知道它是如何构造的,但是作为概念证明,我假设有一个容器div,您可以在其中设置数据:
<div class="festival-container" id="festival-container-<?php echo $collection; ?>"
data-collid="<?php echo $collection; ?>"
data-festival="<?php echo $festival; ?>"
data-page="<?php echo $page; ?>">
当然,您需要传递到模板
$festival
,
$collection
和
$page
变量。
因此,您的js文件(我在前面的代码中假设是\'js/my_ajax.js\'
插件文件夹中的文件)写入:
jQuery(document).ready( function($) {
$( document ).on( \'click\', \'.festival-container .show-more-button a\', function(e) {
e.preventDefault();
var $container = $(this).closest(\'.festival-container\');
var collection = $container.data(\'collid\');
var festival = $container.data(\'festival\');
var paged = $container.data(\'page\') + 1;
$.ajax( {
url: MyScriptData.ajaxurl,
data: {
action: \'myplugin_festival\',
page: paged,
coll_id: collection,
festival_name: festival
},
type: \'POST\',
dataType: \'html\',
error: errorHandler
}).done( function( response ) {
$container.find(\'.list\').append( response );
});
});
});
一些注意事项请查看页面源代码以确保javascript url插入正确,因为如果文件路径
js/my_ajax.js
是相对于插件根的,则需要作为第二个参数传递给
plugins_url
插件主目录中的文件路径,我在其中使用
__FILE__
, 但是如果你的
Events_Controller
类位于url用于
js/my_ajax.js
将是错误的。
此外,在js中,您使用的是$(\'.list\').append( response );
但也许你应该选择一个比$(\'.list\')
另外,如果同一短代码被多次插入,您需要一种方法来识别响应附加到哪个短代码。我使用了容器的引用,使我的代码适应您的需要。
在countrary上,在\'#show-more-button a\'
但您可能应该使用html类而不是html id,因为您可以有多个按钮。我使用了一个使用container类的类来缩小与页面中其他内容冲突的可能性,再次调整我的代码以满足您的需要。