我使用入门主题Sage创建自定义Wordpress主题。我制作了一个非常简单的无限滚动系统来显示每个帖子。在这一点上,一切似乎都很好。
现在,我必须在循环中每N个帖子显示一个广告块。乍一看,它似乎很容易,但不幸的是,事实并非如此。
我的系统以这种方式工作:
显示博客页面时,会显示第一个N个帖子。在该模板(模板1)中,在循环中,我调用一个方法来检查是否必须显示广告。
当用户开始滚动时,接下来的N个帖子都会加载AJAX。因此,JS调用Wordpress操作,该操作加载下一个帖子并调用相应的模板(模板2)。在该模板中,我再次检查已经过了多少帖子以及是否必须显示广告。
计数信息存储在会话变量中。
问题在于:
加载页面时,一切都很好。当无限卷轴第一次运行时,它仍然很好。但是,当系统再次被调用时,变量会话中存储的计数信息并不好。它们采用先前的值,就像会话变量没有增加一样。
第一次,我使用了一些静态属性和一个静态方法,但它没有用。所以,我认为这是因为脚本不是立即调用而是使用了全局变量。但它也没有用。
似乎计数工作正常,但每次加载AJAX调用的模板时,会话变量都会重置为之前的值,就像它们迟到一样。
以下是我使用的文件:
模板1,它是主题的index.php
模板2,由AJAX调用的文件
Ajax函数,包含我在Wordpress中需要的所有AJAX操作
广告控制器,其中包含与广告块相关的所有方法
具有不同AJAX查询的JS文件。
有人能说出我做错了什么吗?非常感谢。
请在下面找到我的代码:
模板1
/****************************************/
/********** TEMPLATE 1 - INDEX **********/
/****************************************/
use Roots\Sage\ThemeAdvertisementController;
$AdvertisementController = new ThemeAdvertisementController\AdvertisementController();
$_SESSION['globalCountAds'] = 0;
$_SESSION['globalArrayAds'] = '';
$_SESSION['globalCountPosts'] = 1;
get_template_part('templates/page', 'header');
while (have_posts()) {
the_post();
get_template_part('templates/content', get_post_type() != 'post' ? get_post_type() : get_post_format());
$theLoopAd = $AdvertisementController->getTheLoopAds();
if ( $theLoopAd ) {
echo $theLoopAd;
}
}
模板2
/**************************************************/
/********** TEMPLATE 2 - CALLDED BY AJAX **********/
/**************************************************/
use Roots\Sage\ThemeAdvertisementController;
$AdvertisementController = new ThemeAdvertisementController\AdvertisementController();
while (have_posts()) {
the_post();
get_template_part( 'templates/content', get_post_type() != 'post' ? get_post_type() : get_post_format() );
$theLoopAd = $AdvertisementController->getTheLoopAds();
if ( $theLoopAd ) {
echo $theLoopAd;
}
}
广告控制器
/**********************************************/
/********** ADVERTISEMENT CONTROLLER **********/
/**********************************************/
namespace Roots\Sage\ThemeAdvertisementController;
use Roots\Sage\ThemeViewController;
use Roots\Sage\ThemePostController;
class AdvertisementController {
public function __construct() {
}
private function getTheAds() {
$PostController = new ThemePostController\PostController();
$postType = 'advertisement';
$nbPosts = -1;
$status = 'publish';
$orderBy = 'title';
$order = 'ASC';
$meta = '';
$taxQuery = '';
$metaQuery = array(
array(
'key' => 'advertisement_in_news',
'value' => true,
'compare' => '='
)
);
return $PostController->getThePosts( $postType, $nbPosts, $status, $orderBy, $order, $meta, $taxQuery, $metaQuery );
}
private function displayTheAd() {
$ViewController = new ThemeViewController\ViewController();
$theAdsArray = $_SESSION['globalArrayAds'];
$theGlobalCountAds = $_SESSION['globalCountAds'];
$thePostID = $theAdsArray->posts[ $theGlobalCountAds ]->ID;
if ( !empty( $thePostID ) ) {
$_SESSION['globalCountAds']++;
$ViewController->postID = $thePostID;
$ViewController->postType = 'advertisement';
$ViewController->nbPosts = 1;
$ViewController->status = 'publish';
$ViewController->orderBy = 'ID';
$ViewController->order = 'ASC';
$ViewController->meta = '';
$ViewController->taxQuery = '';
return $ViewController->displayAdvertisementBlock();
} else {
return false;
}
}
public function getTheLoopAds() {
$arrayAds = $_SESSION['globalArrayAds'];
$adsCount = $_SESSION['globalCountAds'];
$postCount = $_SESSION['globalCountPosts'];
$_SESSION['globalCountPosts']++;
if ( empty( $arrayAds ) ) {
$theAds = $this->getTheAds();
$_SESSION['globalArrayAds'] = $theAds;
}
if ( $postCount%2 == 0 && $postCount != 0 ) {
$displayedAd = $this->displayTheAd();
if ( $displayedAd ) {
return $displayedAd;
} else {
return false;
}
} else {
return false;
}
}
}
Ajax函数
/************************************/
/********** AJAX FUNCTIONS **********/
/************************************/
function infinitePaginateAjax() {
$paged = $_POST['paged'];
$postsPerPage = get_option('posts_per_page');
$args = array( 'paged' => $paged,
'post_status' => 'publish',
'order' => 'DESC',
'post_type' => 'post',
'posts_per_page' => $postsPerPage
);
query_posts( $args );
get_template_part('templates/loop-news');
exit;
}
add_action( 'wp_ajax_infinitePaginateAjax','infinitePaginateAjax' );
add_action( 'wp_ajax_nopriv_infinitePaginateAjax','infinitePaginateAjax' );
function getNbPostsPerPageAjax() {
$value = array();
$nbPostsPerPage = get_option('posts_per_page');
if ( !empty( $nbPostsPerPage ) ) {
$value['answer'] = 1;
$value['value'] = $nbPostsPerPage;
$value['globalCountAds'] = $_SESSION['globalCountAds'];
$value['globalCountPosts'] = $_SESSION['globalCountPosts'];
} else {
$value['answer'] = 0;
$value['value'] = 0;
}
$data = json_encode( $value );
die( $data );
}
add_action( 'wp_ajax_getNbPostsPerPageAjax','getNbPostsPerPageAjax' );
add_action( 'wp_ajax_nopriv_getNbPostsPerPageAjax','getNbPostsPerPageAjax' );
function getTotalPostsAjax() {
global $wp_query;
$value = array();
$nbPosts = wp_count_posts( 'post' );
$nbPublishedPosts = $nbPosts->publish;
if ( !empty( $nbPublishedPosts ) ) {
$value['answer'] = 1;
$value['value'] = $nbPublishedPosts;
$value['globalCountAds'] = $_SESSION['globalCountAds'];
$value['globalCountPosts'] = $_SESSION['globalCountPosts'];
} else {
$value['answer'] = 0;
$value['value'] = 0;
}
$data = json_encode( $value );
die( $data );
}
add_action( 'wp_ajax_getTotalPostsAjax','getTotalPostsAjax' );
add_action( 'wp_ajax_nopriv_getTotalPostsAjax','getTotalPostsAjax' );
JS
jQuery(document).ready(function() {
var pageInfinite = '.infinite-page';
var loaderInfinite = '.infinite-loader';
var contentInfinite = '.main-content';
var getTotalPosts = function() {
var totalPosts = '';
jQuery.ajax({
type : "POST",
contentType: 'application/x-www-form-urlencoded; charset=UTF-8',
async: false,
url : data_sage_js.ajaxurl,
data: {
action: 'getTotalPostsAjax'
},
success: function( data ) {
data = jQuery.parseJSON( data );
if ( data.answer !== 0 ) {
totalPosts = data.value;
} else {
totalPosts = 0;
}
},
error: function () {
console.log( 'error: cannot get nb posts' );
totalPosts = 0;
}
});
return totalPosts;
};
var getNbPostsPerPage = function() {
var postsPerPage = '';
jQuery.ajax({
type : "POST",
contentType: 'application/x-www-form-urlencoded; charset=UTF-8',
async: false,
url : data_sage_js.ajaxurl,
data: {
action: 'getNbPostsPerPageAjax'
},
success: function( data ) {
data = jQuery.parseJSON( data );
if ( data.answer !== 0 ) {
postsPerPage = data.value;
} else {
postsPerPage = 0;
}
},
error: function () {
console.log( 'error: cannot get max posts page' );
postsPerPage = 0;
}
});
return postsPerPage;
};
var infiniteLoadArticle = function( pageNumber ) {
jQuery( loaderInfinite ).show( 'fast' );
setTimeout(function(){
jQuery.ajax({
type:'POST',
contentType: 'application/x-www-form-urlencoded; charset=UTF-8',
async: false,
url: data_sage_js.ajaxurl,
data: {
action: 'infinitePaginateAjax',
paged: pageNumber
},
success: function( html ) {
jQuery( loaderInfinite ).hide( 'fast' );
jQuery( contentInfinite ).append( html);
}
});
}, 1000);
return false;
};
if ( jQuery( pageInfinite ).length > 0 ) {
var postsTotal = parseInt( getTotalPosts() );
var incPost = parseInt( getNbPostsPerPage() );
var postsCount = parseInt( incPost );
var nbPage = parseInt( 1 );
var nbTotalPage = parseInt( Math.ceil( postsTotal / incPost ) );
jQuery(window).scroll(function() {
if ( jQuery(window).scrollTop() === jQuery(document).height() - jQuery(window).height() ) {
if ( nbTotalPage > nbPage ) {
nbPage++;
infiniteLoadArticle( nbPage );
postsCount = postsCount + incPost;
} else if ( nbTotalPage <= nbPage ) {
return false;
}
}
});
}
});
修改/ SOLVE
所以,经过几个小时的搜索,我决定采取另一种方式:我决定使用&#34; posts_per_page&#34;属性以计算帖子并知道何时必须显示广告。我只需要重构一些函数和方法。
答案 0 :(得分:0)
会话变量是否在Ajax调用之外工作?在页面刷新等。
如果他们不这样做,那可能与wordpress可以非常奇怪地处理会话变量这一事实有关。
我认为它的安全性,但如果在你的php.ini中,如果'register_globals'在其上,则取消注册所有的php全局。
在这种情况下,我相信像https://wordpress.org/plugins/wp-session-manager/之类的东西填补了空白,或者你可以关闭php.ini中的register_globals(虽然我不明白这样做的后果是抱歉