I've created a custom WP-Query with the possibility to load more posts on button click with AJAX. Everything works fine. Now I'd like to hide the button if there are less or exactly four posts. The button should also disappear if there are all posts loaded with AJAX.
I'd be very thankful if somebody could help me! Thank you in advance.
My PHP:
<div class="masonry category-single-magazin__inner entry-content">
<?php $args = array('category_name' => 'magazin', 'posts_per_page' => '4', 'paged' => 1, 'orderby'=> 'date', 'order' => 'DESC'); $custom_query = new WP_Query( $args ); while($custom_query->have_posts()) : $custom_query->the_post(); ?>
<article class="object <?php if ( get_field( 'beitragsfarbe' ) == 1 ) { echo 'object--blue'; } else { echo 'object--yellow'; } ?>" id="post-<?php the_ID(); ?>">
<a href="<?php the_permalink(); ?>">
<div class="lazy object__inner" data-src="<?php echo get_the_post_thumbnail_url(); ?>">
<div class="overline">
<h6>
<?php $posttags = get_the_tags(); if ($posttags) { foreach($posttags as $tag) { echo $tag->name . ' '; }}?>
</h6>
</div>
<div class="object__inner__text content-no-margin">
<h4>
<?php the_title(); ?>
</h4>
<p class="textlink" href="<?php the_permalink(); ?>">Mehr erfahren</p>
</div>
</div>
</a>
</article>
<?php endwhile ?>
</div>
<button class="load-more reload-masonry button-full button-full--yellow">
<div class="button-full__inner">Mehr anzeigen</div>
</button>
<script type="text/javascript">
jQuery(document).ready(function() {
var ajaxurl = "<?php echo admin_url( 'admin-ajax.php' ); ?>";
var page = 2;
var pageNumber = <?php echo count_cat_post('magazin')/4; ?>;
$('.load-more').on('click', function() {
var data = {
'action': 'load_posts_by_ajax',
'page': page,
'security': '<?php echo wp_create_nonce("load_more_posts"); ?>',
};
$.post(ajaxurl, data, function(response) {
$('.masonry').append(response);
page++;
});
});
if (page == (parseInt(pageNumber) - 1)) {
$('.load-more').hide();
}
});
</script>
My functions.php:
function load_posts_by_ajax_callback() {
check_ajax_referer('load_more_posts', 'security');
$paged = $_POST['page'];
$args = array(
'category_name' => 'magazin',
'posts_per_page' => '4',
'paged' => $paged,
'orderby'=> 'date',
'order' => 'DESC'
);
$custom_query = new WP_Query( $args ); while ( $custom_query->have_posts() ) : $custom_query->the_post() ?>
<article class="object <?php if ( get_field( 'beitragsfarbe' ) == 1 ) { echo 'object--blue'; } else { echo 'object--yellow'; } ?>" id="post-<?php the_ID(); ?>">
<a href="<?php the_permalink(); ?>">
<div class="lazy-ajax object__inner" style="background-image:url('<?php echo get_the_post_thumbnail_url(); ?>')">
<div class="overline"><h6><?php $posttags = get_the_tags(); if ($posttags) { foreach($posttags as $tag) { echo $tag->name . ' '; }}?></h6></div>
<div class="object__inner__text content-no-margin">
<h4><?php the_title(); ?></h4>
<p class="textlink" href="<?php the_permalink(); ?>">Mehr erfahren</p>
</div>
</div>
</a>
</article>
<?php endwhile ?>
<?php wp_die();}
I will not write whole code but here is the possible solution. First you need to know how many pages of post are there, you can get total number of post by using following Wordpress function
<?php
$count_posts = wp_count_posts();
/*this function only works with post type is post .
if you using for categories first you need to find how many
post are there in that categories.*/
?>
If you divide total count_post by number of post per page you will get total number of page.
Now you can simply check it in your javascript like this.
var pageNumber = <?php echo (wp_count_posts()/4); ?>
//make sure pageNumber is number not string can use javascript parseInt function
jQuery(document).ready(function() {
if(page==(parseInt(pageNumber)-1)){
//send ajax request to get last page post but hide the button
}
});
I hope this will help you. Let me know if anything is not clear.
Solved it by myself. Although thank you for guiding me to the solution!
I've created a function for this with jQuery counting the visible posts:
function hideButton(){
var poststotal = <?php echo count_cat_post('magazin'); ?>;
var postsvisible = $('.masonry > article').length;
if (poststotal == postsvisible) {
$('.load-more').addClass('hidden');
}
};
Related
Situation
I'm creating a custom Wordpress website where I want to show the most recent articles grouped by day and have it scroll infinitely when you've reached the bottom of your screen.
Problem
I don't know how to continue with the date you were on without breaking the layout.
I've seen many code that involve having infinite scroll, but none of them really worked for me since it also needs to match the design.
Here is the design:
The image pretty much explains what I need to create and so I've written the following code:
<div class="recent">
<?php
$args = array(
'posts_per_page' => -1,
'orderby' => 'date'
);
$myQuery = new WP_Query($args);
$date = '';
$postCount = 0;
$newDay = false;
if ( $myQuery->have_posts() ) : while ( $myQuery->have_posts() ) : $myQuery->the_post();
$postCount++;
if ( $date != get_the_date() ) {
if ( $postCount != 1 ) {
$newDay = false;
if (!$newDay) {
?></div><?php
}
?>
</div>
<?php
}
?>
<div class="recent__articles">
<?php
$newDay = true;
$date = get_the_date();
?>
<div class="recent__header">
<img class="header__icon" src="<?php echo get_home_url() ?>/wp-content/themes/insane/assets/images/time.svg" alt="time-icon">
<?php echo $date; ?>
</div>
<?php
if ($newDay) {
?>
<div class="articles__wrapper"><?php
}
}
?>
<div class="recent__article">
<a href="<?php the_permalink(); ?>" title="<?php the_title_attribute(); ?>">
<figure class="article__image">
<?php if ( has_post_thumbnail() ) :
the_post_thumbnail();
else : ?>
<img src="<?php echo get_home_url() ?>/wp-content/themes/insane/assets/images/article-placeholder.png" alt="image-placeholder">
<?php endif ?>
</figure>
<div class="article__meta">
<span class="article__cat">
<?php
foreach((get_the_category()) as $category){
echo $category->name;
}
?>
</span>
<h2 class="article__title"><?php echo get_the_title() ?></h2>
<div class="article__date">
<?php echo esc_html( time_difference( get_the_time('U'), current_time('timestamp') ) ); ?>
</div>
</div>
</a>
</div>
<?php
endwhile; endif;
wp_reset_postdata();
?>
</div>
Top part where I check the date and increment the postCount is so I can group the articles of that day in separate div and style it accordingly.
Now all I need is to check wether I've reached the bottom and continue with where I left off.
Any help with the directions I need to be going is much appreciated.
Thank you!
I've fixed my problem in combination with the Ajax Load More plugin.
I hope this will help others facing the same problem as I did.
If anybody sees improvement in my code, I'd much appreciate it.
Tested on: MacOS - Chrome/Safari/Firefox & iOS - Chrome/Safari
I've installed the Ajax Load More plugin
They have a Repeat Templates section which is basically the while loop in php and I've added the following code (a bit stripped from what I've showed here above).
<?php $postCount++;
if ( $date != get_the_date() ) {
if ( $postCount != 1 ) {
$newDay = false;
if (!$newDay) {
?></div><?php
}
?>
</div>
<?php
}
?>
<div class="recent__articles">
<?php
$newDay = true;
$date = get_the_date();
?>
<div class="recent__header">
<img class="header__icon" src="<?php echo get_home_url() ?>/wp-content/themes/insane/assets/images/time.svg" alt="time-icon">
<?php echo $date; ?>
</div>
<?php
if ($newDay) {
?>
<div class="articles__wrapper"><?php
}
}
?>
<div class="recent__article">
<a href="<?php the_permalink(); ?>" title="<?php the_title_attribute(); ?>">
<figure class="article__image">
<?php if ( has_post_thumbnail() ) :
the_post_thumbnail();
else : ?>
<img src="<?php echo get_home_url() ?>/wp-content/themes/insane/assets/images/article-placeholder.png" alt="image-placeholder">
<?php endif ?>
</figure>
<div class="article__meta">
<span class="article__cat">
<?php
foreach((get_the_category()) as $category){
echo $category->name;
}
?>
</span>
<h2 class="article__title"><?php echo get_the_title() ?></h2>
<div class="article__date">
<?php echo esc_html( time_difference( get_the_time('U'), current_time('timestamp') ) ); ?>
</div>
</div>
</a>
</div>
I've a .php file that I load in somewhere els that looks like this:
<div class="recent">
<?php
$date = '';
$postCount = 0;
$newDay = false;
echo do_shortcode("[ajax_load_more post_type='post' posts_per_page='2' scroll_distance='0']");
?>
</div>
Now for the last part I've written the following in jQuery:
// Ajax load more fix
function ajaxShowMore() {
var oldXHR = window.XMLHttpRequest;
function newXHR() {
var realXHR = new oldXHR();
realXHR.addEventListener("readystatechange", function() {
if (realXHR.readyState === 4) { // When the Ajax call is finished new content is loaded
var oldRecentHeaders = $('.recent__header'); // Store all previous recent headers in variable
setTimeout(function() { // Set a timeout, since it goes a bit to fast to store the data
var newRecentHeaders = $('.recent__header'); // Store all the headers in a variable
newRecentHeaders.splice(0, oldRecentHeaders.length); // Splice it, so you only get the new added headers
if (newRecentHeaders.first().text() === oldRecentHeaders.last().text()) { // Check if the first of new header date is the same as the last of the old header date
var newArticles = newRecentHeaders.first().parent().find('.articles__wrapper').children(); // Store all the articles
newRecentHeaders.first().parent().remove(); // Remove the first new added articles
oldRecentHeaders.last().parent().find('.articles__wrapper').append(newArticles); // Add them here
}
}, 10);
}
}, false);
return realXHR;
}
window.XMLHttpRequest = newXHR;
}
So for me this specific solution works, based on the classes and structure of my project I've set.
I hope this helps
I added a load more button onto one of my category pages. I have three posts in a row and after two columns (6 posts) I have a load more button. The problem is when you press the load more button it scrolls back to the top. I'm assuming because the load more code is in the wrong spot, however I can't find the error. (you have to wrap content in div id=ajax) Does anyone have a solution? Thanks in advance.
by the way I am using this plugin
<?php
get_header();
get_template_part ('inc/carousel-food');
get_template_part ('inc/food-double-posts');
$the_query = new WP_Query( [
'posts_per_page' => 6,
'paged' => get_query_var('paged', 1),
'cat'=> 10
] );
if ( $the_query->have_posts() ) { ?>
<div id="ajax">
<?php
$i = 0;
while ( $the_query->have_posts() ) { $the_query->the_post();
if($i % 3 == 0) {
echo '</div><div class="row">';
}
?>
<article <?php post_class('col-md-4'); ?> >
<?php the_post_thumbnail('medium-thumbnail'); ?>
<h2><a class="post-title" href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2>
<p class="post-excerpt"><?php echo get_the_excerpt(); ?></p>
<?php get_template_part( 'share-buttons' ); ?>
<a class="moretext" href="<?php the_permalink(); ?>">Read more</a>
<?php comments_popup_link ('No Comments', '1 Comment', '% Comments', 'comment-count', 'none'); ?>
</article>
<?php
$i++;
}?>
</div>
<?php if(get_query_var('paged') < $the_query->max_num_pages) {
load_more_button();
}
}
elseif (!get_query_var('paged') || get_query_var('paged') == '1') {
echo '<p>Sorry, no posts matched your criteria.</p>';
}
wp_reset_postdata();
get_footer();
I am attempting to use ajax in my WordPress project to dynamically load videos depending on their post ID. At the moment when I click on the video link I get the error 500 internal server error. I send the post ID via ajax to a PHP script, there I attempt to get the post meta of the post using the ID and then display the video url stored within that post meta. Can anyone see where I am going wrong?
Below is my shortcode function
/**
* Render the HTML code for the speaker interviews
*
* #return $output string The HTML code to be rendered, caught by ob_start();
*/
function test_view_shortcode_fn( $attributes ) {
ob_start();
$args = array( 'post_type' => 'test_video',
'post_status' => 'publish',
'posts_per_page' => 1
);
$main_video = new WP_Query( $args );
if( $main_video->have_posts() ) : while ( $main_video->have_posts() ) : $main_video->the_post();
$video = get_post_meta( get_the_ID(), '_video_url' );
$poster = get_post_meta( get_the_ID(), '_video_poster' );
?>
<div class="row">
<div class="columns small-12 medium-7 large-8 video-single">
<?php echo do_shortcode("[video src='" . $video[0] . "' poster='" . $poster[0] . "' width='800' height='640' preload='none' ]") ?>
<ul class="channel-share">
<li><a class="text-center" href="https://www.facebook.com/sharer/sharer.php?u=<?php the_permalink(); ?>" title="Share on Facebook" target="_blank"><i class="fa fa-facebook"></i></a></li>
<li><a class="text-center" href="https://twitter.com/home?status=<?php the_title(); ?>-<?php the_permalink(); ?>" title="Share on Twitter" target="_blank"><i class="fa fa-twitter"></i></a></li>
<li><a class="text-center" href="https://www.linkedin.com/shareArticle?mini=true&url=<?php the_permalink(); ?>&title=<?php the_title(); ?>" title="Share on Linked In" target="_blank"><i class="fa fa-linkedin"></i></a></li>
<li><a class="text-center" href="https://plus.google.com/share?url=<?php the_permalink(); ?>" title="Share on Google+" target="_blank"><i class="fa fa-google-plus"></i></a></li>
</ul>
<?php the_content(); ?>
</div>
<div class="columns small-12 medium-5 large-4 video-single">
<aside>
<ul class="iot-channel-sidebar">
<?php
$args = array(
'post_type' => 'test_video',
'posts_per_page' => 5,
'orderby' => 'rand'
);
$channel = new WP_Query( $args );
if( $channel->have_posts() ) : while( $channel->have_posts() ) : $channel->the_post();
$poster = get_post_meta( get_the_ID(), '_video_poster' );
$id = get_the_ID();
$video_ajax_url = VIDEO_URI . '/inc/video_ajax.php';
?>
<?php if( $poster ) { ?>
<li class="video-archive-item">
<div class="video-poster">
<a title="<?php the_title(); ?>" id="video_<?php echo $id; ?>">
<img src="<?php echo $poster[0]; ?>" alt="<?php the_title(); ?>" />
</a>
</div>
<div class="video-title">
<a title="<?php the_title(); ?>">
<h4><?php the_title(); ?></h4>
</a>
</div>
</li>
<script type="text/javascript">
jQuery("#video_<?php echo $id; ?>").click(function(){
jQuery.ajax({
url: '<?php echo $video_ajax_url; ?>',
type: 'POST',
data: {id: '<?php echo $id; ?>'},
success: function(data){
$('.wp-video').html(data); // Load data into a <div> as HTML
}
});
});
</script
<?php } ?>
<?php endwhile; endif; ?>
</ul>
</aside>
</div>
</div>
<?php endwhile; endif;
$output = ob_get_clean();
return $output;
}
My ajax:
<?php
global $post;
$postID = $_POST['id'];
setup_postdata( $postID );
echo $postID;
$video = get_post_meta( $postID, '_video_url' );
$poster = get_post_meta( $postID, '_video_poster' );
echo do_shortcode("[video src='" . $video[0] . "' poster='" . $poster[0] . "' width='800' height='640' preload='none' ]")
?>
I finally realised this was due to the fact that WordPress wasn't being loaded on the PHP file being called via Ajax.
To fix this I included wp-load.php at the top of my PHP script the Ajax was calling and it works perfectly. Here's what I added to my PHP file.
<?php
$filename = "../../../../wp-load.php";
include($filename);
?>
I'm would like to make this code load using the post ID of the item clicked inside the internal UL. How can this be done?
Currently creates a side menu containing the specified categories.
After which it creates a ul sub menu within with each li being a post from the category. The post from the category is also inserted using ajax into the specified div.
I need for the posts that are shown in the div and side menu to also load into the div when they're clicked.
Currently I am using cat ids to create the menu and insert into the div. I need to have post ids working from the sub menu.
It's rather difficult to explain.
index.php
<?php
$args = array(
'include' => '4,5,7,8'
);
$categories = get_categories($args);
?>
<ul id="category-menu" class="nav nav-list">
<?php
foreach ( $categories as $cat ) { ?>
<?php $show = 'cat=' . $cat->term_id; ?>
<li id="cat-<?php echo $cat->term_id; ?>">
<a class="<?php echo $cat->slug; ?> ajax tree-toggle" onclick="cat_ajax_get('<?php echo $cat->term_id; ?>');" href="#">
<?php echo $cat->name; ?>
</a>
<ul class="nav nav-list tree" style="display: none">
<?php query_posts($show); ?>
<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
<?php $post_id = $wp_query->post->ID; echo $post_id; ?>
<li>
<a class="ajax" onclick="cat_ajax_get('<?php echo $post_id ?>');" href="#"><?php the_title(); ?></a>
</li>
<?php endwhile; endif; ?>
</ul>
</li>
header.php
<script>
function cat_ajax_get(catID) {
jQuery("a.ajax").removeClass("current");
jQuery("a.ajax").addClass("current"); //adds class current to the category menu item being displayed so you can style it with css
var ajaxurl = '<?php echo admin_url( 'admin-ajax.php' ); //must echo it ?';
jQuery.ajax({
type: 'POST',
url: ajaxurl,
data: {"action": "load-filter", cat: catID },
success: function(response) {
jQuery("#category-post-content").html(response);
return false;
}
});
}
</script>
functions.php
add_action( 'wp_ajax_nopriv_load-filter', 'prefix_load_cat_posts' );
add_action( 'wp_ajax_load-filter', 'prefix_load_cat_posts' );
function prefix_load_cat_posts () {
$cat_id = $_POST[ 'cat' ]; $args = array (
'cat' => $cat_id,
'posts_per_page' => 10,
'order' => 'DESC'
);
$posts = get_posts( $args );
ob_start ();
foreach ( $posts as $post ) {
setup_postdata( $post ); ?>
<div id="post-<?php echo $post->ID; ?> <?php post_class(); ?>">
<h1 class="post-title"><?php the_title(); ?></h1>
<div id="post-content">
<?php the_content(); ?>
</div>
</div>
<?php
}
wp_reset_postdata();
$response = ob_get_contents(); ob_end_clean();
echo $response;
die(1);
}
After hours of research and try and errors I start my first question here.
If it can be done with wordpress syntax even better. Otherwise I think I'm near to the solution.
I want a custom gallery on a wordpress template page but with the post image from certain categories with the content from it. So far so good.
In my designerin.php template I give every images a class img-x.
class="img-<?php echo $img_counter; ?>
And the content get the id img-x
id="img-<?php echo $post_counter; ?>
The counter is just an increment. So image 1 has class img-1, image 2 img-2 and so on.
Now I want the related content of that image created in the wordpress editor showing up when you are clicking on this specific image.
Say you click on image 5 and want the content from image 5.
I'm stucked on the step where I say (in jQuery), that display the content
if .img-x == #img-x {
display the_content()
}
Enough said - here is my jQuery code:
$(".large-img-wrapper").hide();
$('.gallery li').on('click', function(e) {
e.preventDefault();
var largeImgLink = $(this).find('a').attr('href');
$(".large-img-wrapper").first().fadeIn();
var imgContent = $('#img-5').html();
$('#large-img').remove();
$('#append-id').remove();
$(".large-img").append('<img id="large-img" src="' + largeImgLink + '">').fadeIn();
$(".large-img").append('<div id="append-id">' + imgContent + '</div>').fadeIn();
$(".large-img-container .img-title").remove();
});
The var imgContent was just a test. Every image shows up the content from image 5 at the moment.
My template page code:
<div class="row content full-width">
<div class="cats row">
Alle Kategorien
<?php query_posts( 'category_name=designerin&posts_per_page=-1'); if (have_posts()) : while (have_posts()) : the_post();
$categories = get_the_category();
$separator = ' ';
$output = '';
if($categories){
foreach($categories as $category) {
$output .= $category->cat_name;
}
}
$cat_name = get_category(get_query_var('cat'))->name;
?>
<?php echo trim($output); ?>
<?php endwhile; ?>
<?php endif; ?>
<?php wp_reset_query(); ?>
</div>
<ul class="row small-block-grid-3 medium-block-grid-5 large-block-grid-8 gallery">
<?php $img_counter = 0; ?>
<?php query_posts( 'category_name=designerin&posts_per_page=-1'); if (have_posts()) : while (have_posts()) : the_post();
$img_counter++;
$thumb_id = get_post_thumbnail_id();
$thumb_url_array = wp_get_attachment_image_src($thumb_id, 'thumbnail', true);
$large_url_array = wp_get_attachment_image_src($thumb_id, 'large', true);
$thumb_url = $thumb_url_array[0];
$large_url = $large_url_array[0];
$categories = get_the_category();
$separator = ' ';
$output = '';
if($categories){
foreach($categories as $category) {
$output .= $category->cat_name;
}
}
?>
<li>
**<img src="<?php echo $thumb_url; ?>" alt="<?php echo the_title(); ?>">**
</li>
<?php endwhile; ?>
<?php endif; ?>
<?php wp_reset_query(); ?>
</ul>
<?php $post_counter = 0; ?>
<?php query_posts( 'category_name=designerin&posts_per_page=-1'); if (have_posts()) : while (have_posts()) : the_post();
$post_counter++;
?>
**<ul class="large-img-wrapper">
<li>
<div class="large-img-container">
<div class="large-img"></div>
<div class="img-content" id="img-<?php echo $post_counter; ?>">
<div class="img-title">
<?php echo the_title(); ?>
</div>
<div class="img-text">
<?php echo the_content(); ?>
</div>
</div>
</div>
</li>
</ul>**
<?php endwhile; ?>
<?php endif; ?>
<?php wp_reset_query(); ?>
</div>
The first query is for filtering the categories by slug.
My last attempt feels so near..
var inc = '5';
var objClass = $(this).find("a").hasClass( "img-" + inc );
console.log(objClass);
When I'm clicking on the 5th image I get "true". But how can I get the X (inc) related to my template php code?
Sorry for my english and possible bad code
If i'm understanding correctly this might help
$('.gallery li').on('click', function(e) {
e.preventDefault();
var className = $(this).find('a').attr('class');
var imgContent = $('#'+className).html();
});