Get latest post on blog page - php

So, I am looking for a way to get the latest post in order to display it in a different way than the rest of the posts. In the settings I have my "Blog" page to display the posts, as generally everybody do.
The first thing I tried (an answer from another question), was to use the normal loop, I mean, the if (have_posts())...while(have_posts())..etc. And above that IF, place another IF just to get the latest post and through that way I could style my last post. But as I have pagination, on each page, the latest post, is actually the latest post from that page and not the real latest post. Hope this was understandable.
My second try, was to exclude from the normal loop the latest post, and for that I used a snippet from an article which explains how to exclude the latest post and keeping the pagination working using pre_get_posts and found_posts so my code was as follow:
add_action('pre_get_posts', 'myprefix_query_offset', 1 );
function myprefix_query_offset(&$query) {
//Before anything else, make sure this is the right query...
if ( ! $query->is_home() ) {
return;
}
//First, define your desired offset...
$offset = 1;
//Next, determine how many posts per page you want (we'll use WordPress's settings)
$ppp = get_option('posts_per_page');
//Next, detect and handle pagination...
if ( $query->is_paged ) {
//Manually determine page query offset (offset + current page (minus one) x posts per page)
$page_offset = $offset + ( ($query->query_vars['paged']-1) * $ppp );
//Apply adjust page offset
$query->set('offset', $page_offset );
}
else {
//This is the first page. Just use the offset...
$query->set('offset',$offset);
}
}
add_filter('found_posts', 'myprefix_adjust_offset_pagination', 1, 2 );
function myprefix_adjust_offset_pagination($found_posts, $query) {
//Define our offset again...
$offset = 1;
//Ensure we're modifying the right query object...
if ( $query->is_home() ) {
//Reduce WordPress's found_posts count by the offset...
return $found_posts - $offset;
}
return $found_posts;
}
So far so good, this code is working and it's excluding the latest post and the pagination is working, but now my problem is, how do I get the latest post? I tried to use wp_query above the loop in my home.php to get that single latest post but realized that pre_get_posts overrides the wp_query?
How can I solve this and get the latest post? Do I have to do the opposite? I mean, first get the latest post and then create a custom loop for the rest of the posts, but how to manage the pagination?
This is my html so far in home.php
<div class="blog-list">
<div class="blog-item featured-item">
// display latest post here
</div>
<?php if ( have_posts() ): ?>
<div class="teaser-inner mb-4">
<div class="row">
<?php while ( have_posts() ): ?>
<?php the_post(); ?>
<div class="blog-item col-md-6 mb-3 mb-sm-5">
<div class="row">
<div class="col-6 col-md-4">
<?php $img_url = get_the_post_thumbnail_url(get_the_ID(),'full'); ?>
<a href="<?php echo esc_url( get_permalink() ); ?>" class="blog-link">
<div class="blog-item-img bg-cover" style="background-image:url(<?php echo esc_url($img_url); ?>)"></div>
</a>
</div>
<div class="col-6 col-md-8">
<?php the_title(); ?>
</div>
</div>
</div>
<?php endwhile; ?>
</div>
</div>
<div class="blog-pagination">
<?php echo paginate_links(); ?>
</div>
<?php endif; ?>
</div>
Any clue is appreciated.

Your pagination system is working fine. What you could do, it retrieve the latest post with wp_get_recent_posts:
$latestPosts = wp_get_recent_posts(['numberposts' => 1]);
$latestPost = $latestPosts ? current($latestPosts) : null;
Then in your div, you can display the information of your latest post with $latestPost.
<?php if ($latestPost): ?>
<div class="blog-item featured-item">
// display latest post here
</div>
<?php endif; ?>
For the above to work, you need to alter the pre_get_posts a little bit to make sure to only alter the query if it's the main query:
if (! $query->is_home() || ! $query->is_main_query()) {
return;
}

Related

ACF not displaying in Wordpress Template Parts

I am using the ACF plugin to create custom fields for my wordpress site. Everything is going well with zero issues when I keep my code all on the same page. However, when I break the code into template parts, the ACF’s for each section’s hero and custom fields stopped outputting data. It’s almost as if being in template parts is making the fields read as empty, but when I reorder the get_template_parts php (ie, move content-rolls before content-pizza or vice versa), whichever part comes first displays correctly while the second does not.
<?php get_template_part('template-parts/home/content', 'callout'); ?>
<?php get_template_part('template-parts/home/content', 'menu'); ?>
<?php get_template_part('template-parts/home/content', 'pizza'); ?>
<?php get_template_part('template-parts/home/content', 'rolls'); ?>
The same thing happens if I move content-menu.php under content-pizza.php – the ACF’s stop showing that anything is filled into them on the backend. I suspect the issue is in the content-pizza.php (content-rolls.php is the same code copied, with the correct variables filled in), but I can’t see what the issue is.
The content-pizza.php page coding is:
<?php
/**
* Template part for displaying pizza content in page-home.php
*
* #link https://developer.wordpress.org/themes/basics/template-hierarchy/
*
* #package JJs_Pizza
*/
// Variables
$pizza_hero = get_field('pizza_hero');
$pizza_custom = get_field('pizza_custom');
$pizza_args = array(
'posts_per_page' => 50,
'post_type' => 'food',
'category_name' => 'pizza',
'orderby' => 'post_id',
'order' => 'ASC'
);
?>
<!-- Pizza Section -->
<section class="menu-pizza mt-4" id="pizza">
<div class="row no-gutters p-3">
<div class="col">
<?php if( !empty($pizza_hero) ) : ?>
<?php echo($pizza_hero); ?>
<?php endif; ?>
</div>
</div>
<div class="row p-3 justify-content-center">
<?php if ( !empty($pizza_custom) ) : ?>
<div class="col-lg-4 col-sm-6 col-xs-12 custom-menu pt-2">
<?php echo($pizza_custom);?>
</div>
<?php endif; ?>
<?php $loop = new WP_Query($pizza_args);?>
<?php while( $loop ->have_posts() ) : $loop->the_post(); ?>
<div class="col-lg-4 col-sm-6 col-xs-12 menu p-4">
<div class="row">
<div class="col d-flex justify-content-center">
<?php if (get_field('image')):?>
<img src=”<?php the_field('image'); ?>" class="img-fluid">
<?php endif; ?>
</div>
</div>
<div class="row">
<div class="col">
<h3 class="text-center"><?php the_title();?></h3>
<p class="text-center mx-auto">
<?php
$labels = get_field(‘labels’);
if( $labels && in_array(‘vegetarian’, $labels) ) {
echo(‘<i class="fas fa-leaf"></i>');
}
?>
<?php
$labels = get_field(‘labels’);
if( $labels && in_array(‘spicy’, $labels) ) {
echo(‘<i class="fas fa-fire"></i>');
}
?>
</p>
<?php if (get_field('description')):?>
<p class="text-center"><em><?php the_field('description');?></em></p>
<?php endif; ?>
</div>
</div>
</div>
<?php endwhile;?>
</div>
</section><!-- End Pizza Section -->
I also uploaded the code I have so far to a live site at https://demo.jjs-pizza.com/ but so far, the only dynamic sections I’ve coded are the pizza and pizza rolls section so you can get an idea of the issue.
Thank you in advance for any help! If worse comes to it, I’ll just nix the template parts and work from the same page, but for the sake of cleaner code, I’m hoping for a solution.
You are calling WP_Query in your templates and not resetting the post data afterwards. I suspect it is something to do with this, although it is difficult to tell without seeing all of the code, how the fields are set up and on what pages, and how it all works together.
If we look at what's happening in the code:
First, your content-pizza.php template part gets executed
It gets the pizza_hero and pizza_custom fields for the current post (presumably set on the homepage?)
Then it does a custom WP_Query and loops through all of the posts in it
Next up your content-rolls.php template part gets called. Assuming is is the same code as content-pizza...
it then to get the pizza_hero and pizza_custom fields for the current post. However because the code doesn't reset the post data after the WP_Query, the current post is still the last post from that loop.
I'm not sure what post this is supposed to be calling get_field on, but I suspect it isn't the post that is still set up as the current post after the custom query.
When you are finished with a custom loop, you can call wp_reset_postdata to reset the post data after you have finished the loop for that query, like this:
<?php $loop = new WP_Query($pizza_args);?>
<?php while( $loop ->have_posts() ) : $loop->the_post(); ?>
// do stuff...
<?php endwhile;?>
<?php wp_reset_postdata(); /* RESET POST DATA HERE */ ?>
You can find out more about wp_reset_postdata in the WP Code Reference for it
Try adding wp_reset_query() after each loop! You need to destroy the existing query to run a new one.

first loop breaks the second loop

Im trying to display data via a loop using ACF[advance custom fields, Option Page] in my Footer.
This works on my homepage without any problems. But if i navigate to sub-pages it breaks , meaning it would show maybe only the page_links row or on another page only the images_footer row.
It confuses me because home page works perfectly normal and shows all footer data from below.
Also i looked if there is any conflict in the custom-fields names towards the sub-pages custom-fields names and the footer but i dont find any.
Another thing if i would remove the first loop the second one works this is only on some pages, so weird.
If i keep the first while loop ,delete the second while loop, and navigate to other pages,the first while loop show on some pages and some not, how is this even possible.
*I have done some var_dumps(); after both if statements, but obviously the dump does not. So it doesnt even pick up the row -> ('page_links', 'option') or in some cases ('images_footer', 'option').
Any helpful tips would be much appreciated.
<div class="col-lg-8">
<div class="links">
<?php
if( have_rows('page_links', 'option') ):
while( have_rows('page_links', 'option') ): the_row();
?>
<p><?php the_sub_field('footer_link_name'); ?></p>
<?php endwhile; ?>
<?php endif; ?>
</div>
<div class="foot-images">
<?php
if( have_rows('images_footer', 'option') ):
while( have_rows('images_footer', 'option') ): the_row();
?>
<div><img class="img-fluid" src="<?php the_sub_field('logo_image'); ?>" alt=""></div>
<?php endwhile;endif; ?>
</div>
</div>
Following this documentation: ACF - Get values from an options page

Wordpress Category Filter not working

I am completely not sure if I am just being blind but not 100% used to wordpress as yet and would love some assistance with this.
I have my blog posts page showing all the blog posts it also has the categories in the sidebar but when a category is selected it changes the URI with the /categories/events but does not limit the posts content to what should be in the category?
<?php get_header(); ?>
<div class="container posts">
<div class="row">
<div class="col-xs-8 col-md-8">
<?php
$args = array (
'post-type' => 'post'
);
$post_query = new WP_Query($args);
if ($post_query->have_posts())
while ($post_query->have_posts()) {
$post_query->the_post();
?>
<div class="post">
<?php
the_post_thumbnail( 'large' );
echo '<a href="' . get_permalink() . '">';
the_title('<h2>', '</h2>');
echo '</a>';
the_excerpt();
echo do_shortcode( "[icon name='fa-calendar-o']" ) . " ";
the_date("d F");
?>
</div>
<?php
}
?>
</div>
<div class="col-xs-4 col-md-4">
<?php get_sidebar(); ?>
</div>
</div>
</div>
Any ideas? This is a full custom WP Theme from start to finish so I may be missing something very simple and if someone knows what that is I would greatly appreciate it.
Before loading your index.php page, WordPress will have set up a WP_Query object for you according to the page URL/parameters. So on the main blog posts page, it will be a query that finds all posts; on the Foo category page it'll be a query that finds all posts in category Foo.
In your existing code, you're ignoring that pre-set-up query object and creating a new one, $post_query, that always just grabs all posts. That's why the results aren't changing when viewing a Category.
You should dump your specially-created $post_query object and use the basic WordPress "The Loop" code instead:
if (have_posts())
while (have_posts()) {
the_post();
...
This will use the WP_Query object that's been set up for you by WordPress. Typically you don't create your own WP_Query object unless you're doing something a little out of the ordinary.

Wordpress loop is not showing all posts

I got lots of articles I show on my category page.
Here is the code.
<?php if(is_category(4)) {
while ( have_posts() ) : the_post(); ?>
<div class="work">
<div class="work-thumb">
<a href="<?php echo get_permalink(); ?>">
<?php the_post_thumbnail(); ?>
</a>
</div>
<div class="work-title">
<?php the_title(); ?>
</div>
</div>
<?php endwhile; // end of the loop.
} ?>
It is just loop on all articles, but it doesn't show all of them, just like 50%
What could be the problem>?
Is the page that's using that template/code the page that you have set to be the Posts Page, in admin settings?
If so, then the posts per page setting could be less than the total number of posts (and you would need pagination, or to increase this number).
If it's a custom query with the code in your question, then you need to add this to the query arguments:
'posts_per_page' => -1
Note: Even if your case is the former, you could alter the query by using the pre_get_posts filter. E.g. put this in your theme's functions.php:
add_action('pre_get_posts', 'my_filter');
function my_filter( $query ){
$query->set('posts_per_page', -1);
return $query;
}
Inside that function, you want to wrap the code inside an if statement, to do it specifically for the, for example, post type or taxonomy in question.

How to wrap two posts in ajax-load-more Wordpress plugin?

I am writing blog for Wordpress using Bootstrap grid. My first post is sticky, 100% width of column. Next posts should be placed undearneath it in two columns.
Every two posts are wrapped in div with .row class to keep them in line. I've done this and it worked perfectly.
<div class="col-md-8">
<div class="top-news">
// sticky post
</div>
<div class="next-news-grid">
<?php while ( have_posts() ) : the_post(); ?>
<?php if(is_sticky()) continue; ?>
<?php if( $wp_query->current_post%2 != 0 ) echo "\n".'<div class="row">'."\n"; ?>
<div class="col-md-6 next-news">
<?php if ( has_post_thumbnail() ) { ?>
<?php the_post_thumbnail('next- news-thumbnail'); ?>
<?php } ?>
<h4><?php the_title(); ?></h4>
<hr>
<?php the_content( "read more" ); ?>
</div>
<?php if( $wp_query->current_post%2 != 1 || $wp_query->current_post == $wp_query->post_count-1 ) echo '</div> <!--/.row-->'."\n"; ?>
<?php endwhile; ?>
</div>
</div>
But I want to use ajax-load-more plugin to automatically load posts on the same page after button is clicked. Unfortunately it won't wrap my posts in .row class anymore.
I copied my while loop into repeater template in plugin settings but it seems like it's ignoring the if statement parts with div appending. Therefore it looks ugly when one post is longer and is pushing another to the right AND another down making huge gaps between them.
So how can I wrap every two posts in div.row container with this plugin? Or can I use something else to achieve infinite loading with button?

Categories