I'm hoping someone can help me figure this one. It's been giving me problems for a bit. I'm attempting to have a custom category page display the most recent post at the beginning of the page, and below in a separate loop I wish to display the rest of the posts in the given category WITH pagination, offsetting the loop by 1. I've searched numerous ways to do this and can't quite come up with a solution! Any help you can give for this one I'd be soooo grateful for! Thank you in advance! Here's my code:
<?php query_posts( 'cat=3&showposts=1&offset=0'); ?>
<?php while (have_posts()) : the_post(); ?>
<div class="firstPost">
Snipped post style
</div>
<div class="prevHeader">Previous Episodes</div>
<?php endwhile; ?>
<div class="container archiveContainer">
<?php
// set the "paged" parameter (use 'page' if the query is on a static front page)
$paged = ( get_query_var( 'paged' ) ) ? get_query_var( 'paged' ) : 1;
// the query
$the_query = new WP_Query( 'cat=3&posts_per_page=6&offset=1&paged=' . $paged );
?>
<?php if ( $the_query->have_posts() ) : ?>
<?php
// the loop
while ( $the_query->have_posts() ) : $the_query->the_post();
?>
<div class="prevEntries">
Snipped Post Style
</div>
<?php endwhile; ?>
</div>
<div style="width:100%">
<span style="display:inline-block; margin-left:10px; float:left" class="nav-previous"><?php next_posts_link( '<h4>Older posts</h4>', $the_query->max_num_pages ); ?></span>
<span style="display:inline-block; margin-left:10px; float:right" class="nav-next alignright"><?php previous_posts_link( '<h4>Newer posts</h4>' ); ?></span></div>
<?php
// clean up after the query and pagination
wp_reset_postdata();
?>
<?php endif; ?>
This can certainly be done, but surely not with query_posts. It a case like this, it will outright fail. Also, offsets breaks pagination and are quite difficult to work with if you don't know what you are doing
I don't have time to code now, but here is an idea:
If you need to display the latest post on all your pages, then you can do the following.
Remove you custom query and your offset so that everything works normal. Make use of the default loop and paginate as normal
To display your first post on every page, create a custom query with WP_Query and place it where you need to display this post .See the link on how to properly construct that query. Please do not use query_posts
You will now see that you have the first post displayed twice. To counter this, wrap your custom query in a is_paged() condition.
EDIT
You can try something like this. (PS! showposts is depreciated, use posts_per_page. Also, you can removed the paged parameter when setting an offset as it will be ignored)
(CAVEAT Untested)
if( is_paged() ) {
$args = array(
'posts_per_page' => 1,
'cat' => 3,
);
$q = new WP_Query( $args );
if( $q->have_posts() ) {
while( $q->have_posts() ) {
$q->the_post();
// Display your loop elements
} //end while
wp_reset_postdata();
} // end if have_posts()
} //end if is_paged
// Now for your main loop
// set the "paged" parameter (use 'page' if the query is on a static front page)
$paged = ( get_query_var( 'paged' ) ) ? get_query_var( 'paged' ) : 1;
$the_query = new WP_Query( 'cat=3&posts_per_page=6&paged=' . $paged );
if ( $the_query->have_posts() ) {
while ( $the_query->have_posts() ) {
$the_query->the_post();
// Your loop elements
}
wp_reset_postdata();
}
Codex states : Specifying hard-coded offsets in queries can and will break pagination since offset is used by WordPress internally to calculate and handle pagination.
See the following link. As described on the page you'll need to use a hook and filter.
Related
By default Wordpress shows all posts in reverse chronological order (with the newest post first).
I would like to display all of my wordpress posts in chronological order (with the oldest posts shown first).
I am trying to use a custom loop query to do this, however I cannot get it to work. What am I missing here?
<?php query_posts(array('orderby'=>'date','order'=>'ASC'));
if ( have_posts() ) :
while ( have_posts() ) : the_post(); ?>
<div class="postTitle"><?php the_title(); ?></div>
<div class="postContent"><?php the_content(); ?></div>
<?php endwhile; endif;
wp_reset_query();
?>
I thought this would be quite simple, although everything I have found to try I also cannot make work. thanks!
Using custom loop:
If you are creating a custom loop you might want to use WP_Query instead.
<?php
$the_query = new WP_Query([
'order'=>'ASC'
]);
// The Loop
if ( $the_query->have_posts() ) :
while ( $the_query->have_posts() ) :
?>
<div class="postTitle"><?php the_title(); ?></div>
<div class="postContent"><?php the_content(); ?></div>
<?php
endwhile;
/* Restore original Post Data */
wp_reset_postdata();
?>
<?php else: ?>
// no posts found
<?php endif; ?>
Using filters
Or another method is to alter the main loop using filters in your functions.php file.
function alter_order_of_posts( $query ) {
if ( $query->is_main_query() ) {
$query->set( 'order', 'ASC' );
}
}
add_action( 'pre_get_posts', 'alter_order_of_posts' );
I suggest the filter path to avoid changing a lot of your current template.
I am building a one page WordPress template. I have created a simple loop that pulls all the pages and displays each one in succession on the same page. It displays the content for each page but dose not apply the template that has been attached to the page.
Here is the loop...
$args = array(
'post_type' => 'page',
'order' => 'ASC'
);
$the_query = new WP_Query( $args );
?>
<?php if ( have_posts() ) : while ( $the_query->have_posts() ) : $the_query->the_post(); ?>
<?php the_content(); ?>
<?php endwhile; endif; ?>
When you use the_content, the function will only return the value for the filed post_content within the table. So the code is working as it is expected.
Try the following
if ( have_posts() ){
while ( $the_query->have_posts() ) {
$the_query->the_post();
locate_template( get_template_slug( $post->ID ) )
}
}
This code uses the function locate_template to find the template file, and get_template_slug to get the name of the template associated with each page.
Let me know if this helps.
My problem is pagination which I am using in Wordpress. I used the plugin WP Pagenavi. I'm not really sure what is wrong with it.
I found the answer to my problem using this code :
<?php $paged = (get_query_var('paged')) ? get_query_var('paged') : 1; ?>
<?php query_posts('cat=4&posts_per_page=15'.'&paged=' . $paged); ?>
But to my disappointment, when I reduced the posts_per_page to 5, I CAN get the pagination to work until page 2 but when I click page 3 and so on, WordPress can't find it. I used another solution from my research:
<?php
$limit = '5';
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
query_posts('cat=4&showposts=' . $limit . '&paged=' . $paged);
$wp_query->is_archive = true; $wp_query->is_home = false;
?>
It still didn't help. I don't want to touch functions.php. I'm only editing category.php.
Check my block of code below :
<?php if (is_category('category1')) { ?>
<?php $paged = (get_query_var('paged')) ? get_query_var('paged') : 1; ?>
<?php query_posts('cat=1&posts_per_page=15'.'&paged=' . $paged); ?>
<?php if (have_posts()) : while (have_posts()) : the_post(); ?>
<!-- SOME CODE TO POST THE POST -->
<?php endwhile; ?>
<?php wp_pagenavi() ?>
<?php endif; ?>
<?php } else if (is_category('category2')) { ?>
<?php $paged = (get_query_var('paged')) ? get_query_var('paged') : 1; ?>
<?php query_posts('cat=2&posts_per_page=15'.'&paged=' . $paged); ?>
<?php if (have_posts()) : while (have_posts()) : the_post(); ?>
<!-- SOME CODE TO POST THE POST -->
<?php endwhile; ?>
<?php wp_pagenavi() ?>
<?php endif; ?>
<?php } else if (is_category('category3')) { ?>
<?php $paged = (get_query_var('paged')) ? get_query_var('paged') : 1; ?>
<?php query_posts('cat=3&posts_per_page=5'.'&paged=' . $paged); ?>
<?php if (have_posts()) : while (have_posts()) : the_post(); ?>
<!-- SOME CODE TO POST THE POST -->
<?php endwhile; ?>
<?php wp_pagenavi() ?>
<?php endif; ?>
<?php } else if (is_category('category4')) { ?>
<?php $paged = (get_query_var('paged')) ? get_query_var('paged') : 1; ?>
<?php query_posts('cat=4&posts_per_page=5'.'&paged=' . $paged); ?>
<?php if (have_posts()) : while (have_posts()) : the_post(); ?>
<!-- SOME CODE TO POST THE POST -->
<?php endwhile; ?>
<?php wp_pagenavi() ?>
<?php endif; ?>
<?php } else { ?>
<!-- SOME CODE -->
<?php } ?>
Please note that category1 and category2 display 5 posts while the other 2 categories will display 15 posts. And these are all in the category.php.I don't want to use the # of posts set in the Settings > Reading.
If you think the if statement and putting also the cat ID is redundant, well, it does not get posts of that category name.
UPDATE
I used this code:
<?php $paged = (get_query_var('paged')) ? get_query_var('paged') : 1; ?>
<?php $args = array ('post_type' => 'post','cat' => '4','posts_per_page' => '5','paged' => $paged);?>
<?php $my_query = new WP_Query ($args);?>
Again, it worked BUT it only shows two pages! I don't even know where the 3rd page is, supposedly there should be a 3rd page.
Your code has some serious issues
Never ever use query_posts, ever. It breaks the main query object on which so many plugins and functionalities rely, it also breaks pagination and fails silently, so it is really hard to debug pagination when it does fail. If you really really have to use a custom query, use WP_Query instead. You should take your time to read this post and all of the linked posts. It is really helpful as it tells you why you should not use query_posts and when should you use custom queries and when not
This point are coupled to the first one and the linked post. You must never change the main query to use a custom one on the homepage or any type of archive page. This always causes much more issues than what is actually solves. Always use pre_get_posts to alter the main query before it runs. This way, you lets the main query handle all the heavy lifting correctly without you breaking a sweat.
Now, to fix your issue:
First of all, remove all your queries, and just add this code in your category.php (Remember to replace your pagination function, wp_pagenavi())
if ( have_posts() ) {
while ( have_posts() ) {
the_post();
// Your loop with template tags and html mark up
}
wp_pagenavi();
}
You will immediately see that your category posts are showing correctly, but the amount of posts will be the same as what you set in the back end under reading
We will now use pre_get_posts to alter the amount of posts per category. For this, add the following code to your functions.php (Requires PHP 5.3+ and the code is untested)
add_action( 'pre_get_posts', function ( $q )
{
if ( !is_admin() // Very important, otherwise back end queries will be affected as well
&& $q->is_main_query() // Very important, we just need to modify the main query
&& $q->is_category() // Only target category pages
) {
// Check on which category page we are and set posts_per_page accordingly
if ( $q->is_category( array( 1, 2 ) ) )
$q->set( 'posts_per_page', 15 );
if ( $q->is_category( array( 3, 4 ) ) )
$q->set( 'posts_per_page', 5 );
}
});
This should basically do it.
Assuming this could help for those who, like me, use a DIVI CHILD THEME !
I finally found the solution by searching divi pagination.
In fact, in my case, I built a divi child theme. However, the post per page in my custom category page is set to 3, but into my divi > theme option the Number of Posts displayed on Category page were set to 6.
That why the page 3 was displaying an error 404. So, I set it to 1.
I read on a post that the "Blog pages show at most" into the settings > reading option have to be under the post_per_page custom query (for the home page), or else, it create a 404 page.
However, it look like that the Number of Posts displayed into the Divi option, overwrite the Blog pages show at most. Here why into my category.php page, I was stuck on page 3.
I leave you my tiny code about my custom category.php page for divi theme child :
<?php
//query{
//print_r(get_queried_object());
$category = get_queried_object();
$the_cat_nicename = $category->slug;
$the_cat_name = $category->name;
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
$args_s = new WP_Query(array(
'post_type' => 'post',
'category_name' => $the_cat_nicename,
'posts_per_page' => 3,
'paged' => $paged,
'orderby'=>'date',
'order'=>'DESC'));
//query}
if ( $args_s->have_posts())
{
echo $the_cat_name;
echo '<br/>';
while ( $args_s->have_posts())
{
$args_s->the_post();
$the_id=get_the_ID($post->ID);
echo $the_id.'<br/>';
}
if ($args_s->max_num_pages > 1)
{
echo get_next_posts_link( $GLOBALS['older_post_lang'], $args_s->max_num_pages );
echo get_previous_posts_link( $GLOBALS['newer_post_lang'] );
}
}
//wordpress _have_posts}
?>
Do not forget to set your Number of Posts displayed on Category page to 1 into your Divi > theme option.
We have finally arrived to a final answer and working code!
If you read Mr. Pieter Goosen's answer above, it will help you. It really helped me. So, I'm going to give you the final answers. This is actually custom number of post in every category disregarding what is set in the settings.
So in my category.php
<?php if (is_category('category1')) { ?>
<?php if ( have_posts() ) {
while ( have_posts() ) {
the_post();
// Your loop with template tags and html mark up
}
wp_pagenavi();
}
?>
<?php } else if (is_category('category2')) { ?>
<?php if ( have_posts() ) {
while ( have_posts() ) {
the_post();
// Your loop with template tags and html mark up
}
wp_pagenavi();
}
?>
<?php } else if (is_category('category3')) { ?>
<?php if ( have_posts() ) {
while ( have_posts() ) {
the_post();
// Your loop with template tags and html mark up
}
wp_pagenavi();
}
?>
<?php } else if (is_category('category4')) { ?>
<?php if ( have_posts() ) {
while ( have_posts() ) {
the_post();
// Your loop with template tags and html mark up
}
wp_pagenavi();
}
?>
<?php } ?>
WHERE category1 and category2 will display 5 posts, category3 and category4 will display 15 posts.
This is what you're going to place in your functions.php.
add_action( 'pre_get_posts', function($q) {
if (!is_admin() && $q->is_main_query() && $q->is_category()) {
if ($q->is_category( array(1,2) )) {
$q->set('posts_per_page', 5);
}
if ($q->is_category( array(3,4) )) {
$q->set('posts_per_page', 15);
}
}
return;
});
WHERE the numbers inside the array are category IDs.
If you compare my code and Sir Pieter's, it's almost the same BUT I added a return; before the add_action() is closed. But I'm quoting what Sir Pieter said:
It is really strange that you should return. pre_get_posts is a
action, not a filter. But any way, glad it is solved
If it still doesn't work for you, my permalink is set to:
http://www.example.com/sample-post/[/%postname%/].
I also have a WP No Category Base plugin to eliminate /category/ in my category URL. So instead of www.example.com/category/category1, it will be www.example.com/category1.
I am creating a website that integrates a portfolio which uses custom post types, this was done based off of this tutorial.
So far it is exactly what I am looking for and works great except for one small detail. In order to fetch the posts from the new custom post type the author of the tutorial used the query_posts() codex. So the top of my portfolio page looks like this:
<?php
/* Template Name: Portfolio */
get_header();
query_posts('post_type=portfolio&posts_per_page=10');
?>
What I gather is that this declares "get posts from "post type" portfolio and show 10 per page". My problem is that I can't go get content from my portfolio page. It seems that now my portfolio page only fetches the content from the custom post type, and I can't use:
<?php while ( have_posts() ) : the_post(); ?>
<?php the_content(); ?>
<?php endwhile; // end of the loop. ?>
to get content from the actual page.
This is what I am trying to do, I've replaced:
query_posts('post_type=portfolio&posts_per_page=10');
with:
add_action( 'pre_get_posts', 'add_my_post_types_to_query' );
function add_my_post_types_to_query( $query ) {
if ( is_page( 8 ) && $query->is_main_query() )
$query->set( 'post_type', array( 'portfolio' ) );
return $query;
}
This seems like the right track, but it stills doesn't work. I'm not getting the posts from my custom post type.
Any ideas how I could modify this? I am also still learning so being clear with explanations would be greatly appreciated.
Thank you!
Editing the pre_get_posts will replace the original query and you will not have the content for your page at all. I would only recommend going this approach if you only wanted to display the content of your portfolio post type and not the content of your portfolio page.
For general post queries it is recommended to use WP_Query or get_posts.
http://codex.wordpress.org/Class_Reference/WP_Query
http://codex.wordpress.org/Template_Tags/get_posts
If you use the WP_Query function the wp_reset_postdata() will restore the post data back to the original so you can get the content of your original page.
$args = array(
'posts_per_page' => 10,
'post_type' => 'portfolio',
);
// The Query
$the_query = new WP_Query( $args );
// The Loop
if ( $the_query->have_posts() ) {
while ( $the_query->have_posts() ) {
$the_query->the_post();
echo '<li>' . get_the_title() . '</li>';
}
} else {
// no posts found
}
/* Restore original Post Data */
wp_reset_postdata();
Now you will be able to use the original loop to show the content of your page
<?php while ( have_posts() ) : the_post(); ?>
<?php the_content(); ?>
<?php endwhile; // end of the loop. ?>
Usually, I stick my query posts in a variable, like so:
$catid = get_cat_ID('My Category Name');
$args = array(
'posts_per_page' => 5,
'orderby' => 'post_date',
'order' => 'DESC',
'post_type' => 'post',
'post_status' => 'publish',
'category' => $catid
);
$posts_array = get_posts($args);
Then you can loop it like so:
<?php foreach ($posts_array as $post) : setup_postdata($post);?>
<h1><?php the_title(); ?></h1>
<p><?php the_content(); ?></p>
<?php endforeach; ?>
Finally, to access your page content you can use the variable $post, it's automatically set by wordpress. No need to add any more code than this to access your page content.
<?php foreach( $posts as $post ) : setup_postdata($post); ?>
<h1><?php the_title(); ?></h1>
<p><?php the_content(); ?></p>
<?php endforeach; ?>
The foreach loop for your page content is a little overkill, and there is a better way to do it (most likely at least), but I haven't been bothered to look into it further yet! It works though!
I'm having an issue with the listings in the WordPress site I'm working on.
I have three listings only showing up out of 6. I can't seem to figure out how to make all of them display. This is using the twentyeleven WordPress theme.
The arrows on the right are used to move the gallery back and forth. Only one more shows up on the right side.
Here's the code I believe is generating it.
<?php if ( have_posts() ) : ?>
<?php twentyeleven_content_nav( 'nav-above' ); ?>
<?php if ( is_home() ) {
query_posts($query_string . '&cat=-3');
}
?>
<?php
$page_name="Articles";
$page=get_page_by_title($page_name);
//echo $page->ID;
query_posts( 'cat=-1,-2' );
?>
<?php /* Start the Loop */ ?>
<?php while ( have_posts() ) : the_post(); ?>
<?php get_template_part( 'content', get_post_format() ); ?>
<?php endwhile; ?>
</div>
Any help would be great, thanks.
Change your query_posts() function to the following:
query_posts( 'cat=-1,-2&posts_per_page=6' ); // You can change the post_per_page variable as needed
However, I would suggest using an $args array instead of a querystring to make your query. The same query would look like this:
$args = array(
'cat' => array( -1, -2 ),
'posts_per_page' => 6
);
query_posts($args);
It is much more readable and easier to update. Also, it's worth mentioning, you are adding a negative operator to your categories. In the query_posts function, that will exclude a category. You may only be getting 3 posts because you are excluding posts from your query.