Is there a way to use THE LOOP in Wordpress to load pages instead of posts?
I would like to be able to query a set of child pages, and then use THE LOOP function calls on it - things like the_permalink() and the_title().
Is there a way to do this? I didn't see anything in query_posts() documentation.
Yes, that's possible. You can create a new WP_Query object. Do something like this:
query_posts(array('showposts' => <number_of_pages_to_show>, 'post_parent' => <ID of the parent page>, 'post_type' => 'page'));
while (have_posts()) { the_post();
/* Do whatever you want to do for every page... */
}
wp_reset_query(); // Restore global post data
Addition: There are a lot of other parameters that can be used with query_posts. Some, but unfortunately not all, are listed here: http://codex.wordpress.org/Template_Tags/query_posts. At least post_parent and more important post_type are not listed there. I dug through the sources of ./wp-include/query.php to find out about these.
Given the age of this question I wanted to provide an updated answer for anyone who stumbles upon it.
I would suggest avoiding query_posts. Here's the alternative I prefer:
$child_pages = new WP_Query( array(
'post_type' => 'page', // set the post type to page
'posts_per_page' => 10, // number of posts (pages) to show
'post_parent' => <ID of the parent page>, // enter the post ID of the parent page
'no_found_rows' => true, // no pagination necessary so improve efficiency of loop
) );
if ( $child_pages->have_posts() ) : while ( $child_pages->have_posts() ) : $child_pages->the_post();
// Do whatever you want to do for every page. the_title(), the_permalink(), etc...
endwhile; endif;
wp_reset_postdata();
Another alternative would be to use the pre_get_posts filter however this only applies in this case if you need to modify the primary loop. The above example is better when used as a secondary loop.
Further reading: http://codex.wordpress.org/Class_Reference/WP_Query
Related
I know, this question has been asked a lot. I have been through a lot of them already, but my issue seems to be more bespoke.
Initially, I had this issue, but seems to be another issue, therefore I am asking a new question in hopes for a solution.
I am using the WP Download Manager Pro plugin that creates a custom post type wpdmpro.
So, the crux of my issue seems to be that my pagination in my loop.php, seems to be connected someone to the default post type and not the custom post type I am using, as in, if I have 0 Posts in my default posts, navigating to /page/2 will not work, but if I have 11 default posts it will, but then /page/3 will not work.
I have 11 wpdmpro posts and 0 default posts. Therefore, I would expect here, that with 2 posts per page, that I would have 6 pages? Wordpress seems to think differently!
Here is my query
<?php
$category = get_queried_object();
$paged = ( get_query_var('paged') ) ? get_query_var('paged') : 1;
$args = array(
'orderby' => 'date',
'order' => 'DESC',
'post_status' => 'publish',
'posts_per_page' => 2,
'paged' => $paged,
'post_type' => 'wpdmpro',
'wpdmcategory' => $category->category_nicename,
'tag' => $cat_tag
);
// Query
$wpdmpro_query = new WP_Query( $args );
// The Loop
if( $wpdmpro_query->have_posts() ) : while( $wpdmpro_query->have_posts() ) : $wpdmpro_query->the_post();
?>
<!-- Do stuff -->
<?php endwhile; ?>
<!-- Do stuff if there are no posts -->
endif; wp_reset_postdata(); ?>
So WHY does /page/2 return a 404 when that page SHOULD exist? As mentioned, if I start to add posts to the default post (on the 11th post), then /page/2 seems to work, with the 21st post /page/3/ works, so it has to be linked to that. But why? I clearly define that I am NOT using 'post_type' => 'post',. So where could this be defined and how can I override it?
Just a few things to add in case they are somehow linked.
In my permalinks settings, I have a custom structure of
/%category%/%postname%/
and my default category base is .
I have tried resetting the permalinks settings, but still getting the 404 page on /page/2.
In my WP Download Manager Settings, my WPDM Category URL Base is .
So, with all that my url is.
{domain}/category-name/page/2/ which is returning the 404.
{domain}/category-name/ returns 2 posts of the stated category.
Part of me is concerned this is a configuration issue, mixing a custom post type with custom structure and category base. Someone out there must have had this issue? It seems like this should be very simple, but I cannot for the life of me find a solution, perhaps I am looking in the wrong places?
Any help will be massively appreciated.
Edit:
I have tried to regenerate the permalinks on multiple different occassions to no effect.
I am working on a website in Wordpress where I need to use custom posts (which I already created with the help of a plugin).
The problem is that the theme that I use allows me to display the post on the page organized according to categories, but when I create a custom post and put it into a category it is not displayed on the web (as if I had never created the post) but if I create the same post from the normal page of Wordpress entries (a standard Wordpress post type) and I put it in the same category this is shown on the page. Also, when I enter the custom post page the entry I created appears but when I enter the normal entries page it does not appear.
I went to a portal where they said how to add the custom post to the Wordpress categories by writing some lines of code in the functions.php file but this did not work, now I see the custom post within the category page but I still do not see them inside of the Wordpress entries page and also still not shown on the web.
You need to create a custom query. This page has good explanations and examples: https://codex.wordpress.org/Class_Reference/WP_Query
The most important thing in your case is to include this in your arguments array, which selects posts and your CPT:
'post_type' => array('post', 'your-custom-posttype'),
and also this which filters by category:
'category_name' => 'your_category_name'
So a typical simple custom query would look like this:
$args = array(
'post_type' => array('post', 'your-custom-posttype'),
'category_name' => 'your_category_name',
'post_status' => 'publish',
'posts_per_page' => 12
);
$query1 = new WP_Query( $args );
if ( $query1->have_posts() ) {
while ( $query1->have_posts() ) {
$query1->the_post();
echo '<li>' . get_the_title() . '</li>';
// Other stuff echoing content etc. to be added here.....
}
wp_reset_postdata();
}
I'm develop a theme for WordPress and I have created index.php for the original loop, and home.php for 4 latest posts, now I need to put a link for show all posts, how to I do that?
Instead of a link to show all posts, I would use WordPress's have_posts() function inside a while loop (first check to see if there are posts to display, if there are do so, if not exit loop and display other content). You could potentially look at WP's documentation for the function and maybe even glance at file used for the default page template (page.php).
In order to display only the latest 4 posts, you could simply add a counter variable and end each while loop iteration with an if statement checking to see if count == 4.
Also, just so you are aware, home.php sometimes takes precedence over index.php so either nest home.php inside an internal directory or call your '4 latest posts' page 'posts.php' or something similar.
Wordpress documentation: https://codex.wordpress.org/Function_Reference/have_posts
To get latest post with url:
<?php
$args = array( 'numberposts' => '1', 'category' => CAT_ID );
$recent_posts = wp_get_recent_posts( $args );
foreach( $recent_posts as $recent ){
echo 'Latest Post';`enter code here`
}
?>
Hope this helps .
It's a bit more complicated than that.
For a travel website, I have 3 parent categories: Series, Post Type, and Location.
Each post is assigned to a child category. For example (respectively): EU2014, Picture Gallery, and Rome.
On each post, there is a sidebar. My intention is that this sidebar will contain links to the other related posts. A post is related if it is:
1.) In the same Series child category (such as "EU2014")
AND
2.) in the same Location child category (let's say "Rome").
Really what I'm doing here is making it so that way the client can write any number of posts, and a network of links will appear on all of them (in the sidebar).
So, in sum, all posts designated "EU2014" AND "Rome" will be part of a collection.
Then I can format the sidebar nicely based on what Post Type a post in question is (with appropriate icons or whatnot).
My problem is this:
I need pseudo code. I've started working on it, but I'm very concerned that, if I am to iterate through the entire database of posts every time I load a post, simply to write that sidebar, it will be a massive resource drain on the system.
How can I
1.) Identify the child categories of the current post
and
2.) get the names and links of each post whose Series and Location child categories match those of the current post in order to write that information to the sidebar of the current post
without creating a black hole of fuckery when the site grows to more than just a few total posts?
This is going to be written in PHP, so if anyone has any interest in helping me figure out more than just pseudo, I'd be thrilled to suss it out with you.
<?php
$args = array(
'posts_per_page' => -1,
'offset' => 0,
'category' => 8, // specify category id here
'orderby' => 'post_date',
'order' => 'DESC',
'post_type' => 'post',
'post_parent' => '',
'post_status' => 'publish',
'suppress_filters' => true );
$myposts = get_posts( $args );
foreach( $myposts as $post )
{
setup_postdata( $post );
?>
<?php the_title(); ?>
<?php
}
wp_reset_postdata();
?>
For Reference see this
http://codex.wordpress.org/Template_Tags/get_posts
I am reading that query_posts() should be avoided in favor of wp_query() and pre_get_posts(). I am not confident with messing with the Loop and do not fully understand the codex.
Does the code below use query_posts() ? If yes and since query_posts() should be avoided, can you suggest a method that does not use query_posts() but still accomplish the same thing?
This code in functions.php is used to sort posts by random or by price.
function my_custom_query($query){
if ( $query->is_home() && $query->is_main_query() ) {
$sort= $_GET['sort'];
if($sort == "pricelow"){
$query->set( 'meta_key', 'price' );
$query->set( 'orderby', 'meta_value_num' );
$query->set( 'order', 'ASC' );
}
if($sort == "random"){
$query->set( 'orderby', 'rand' );
}
}
}
add_action( 'pre_get_posts', 'my_custom_query' );
.
Link A (Random) and Link B (Price) are posted in my menu by using this code. Thus the visitor to the website can sort the posts simply by clicking a link.
Random
Price
I have done a very detailed explanation on this very topic on WPSE, and for the sake of the value and benefit it might have for SO users, here is the complete post copied from that question on WPSE. For interest sake, here is a link to the complete post on WPSE: Some doubts about how the main query and the custom query works in this custom theme?
Your actual question is basically when to run a custom query and when to make use of the main query. Lets break it down in three parts
PART ONE
When to run a custom query (This is not a definitive list)
To create custom content sliders
To create a featured content area in a page
On page.php templates if you need to display posts
If you require custom content on a static front page
Display related, popular or informational posts
Any other secondary or supplementary content outside the scope of the main query
When to make use of the main query.
To display the primary content on
On your homepage and the page set as a blogpage in the backend
All archive pages which includes templates like archive.php, category.php, author.php, taxonomy.php, tag.php and date.php
PART TWO
To select all the featured posts I use this line that create a new WP_Query object that define a query having the specific tag featured:
So, from what I have understand, this is not the WordPres main query but it is a new query created by me. From what I have understand it is better create a new query (as done) and not use the main query when I want perform this kind of operations
Correct. This falls out of scope for the main query. This is secondary or supplementary content which cannot be created with the main query. You SHOULD ALWAYS use either WP_Query or get_posts to create your custom queries.
NEVER USE query_posts to create custom queries, or even any other query. My emphasis.
Note: This function isn't meant to be used by plugins or themes. As explained later, there are better, more performant options to alter the main query. query_posts() is overly simplistic and problematic way to modify main query of a page by replacing it with new instance of the query. It is inefficient (re-runs SQL queries) and will outright fail in some circumstances (especially often when dealing with posts pagination).
Moving on
Ok, going on I show all the posts that have not the featured tag, to do this I use this code snippet that on the contrary modify the main query:
query_posts( array( 'tag__not_in' => array ( $term->term_id )));
So I think that this is pretty horrible. Is it true?
That is all wrong and your statement is unfortunately true. As said before, NEVER use query_posts. It runs a complete new query, which is bad for performance, and it most cases breaks pagination which is an integral part of the main query for pagination to work correctly.
This is your primary content, so you should be using the main query with the default loop, which should look like this, and this is all you need
<?php
if (have_posts()) :
// Start the Loop.
while (have_posts()) : the_post();
get_template_part('content', get_post_format());
endwhile;
else :
// If no content, include the "No posts found" template.
get_template_part('content', 'none');
endif;
?>
You can completely get rid of this part, delete it, burn it and forget about it
<?
// get the term using the slug and the tag taxonomy
$term = get_term_by( 'slug', 'featured', 'post_tag' );
// pass the term_id to tag__not_in
query_posts( array( 'tag__not_in' => array ( $term->term_id )));
?>
OK, once you've done that, you'll see that posts from the feature tag appear in your home page using the main query and default loop.
The correct way of removing this tag from the homepage is with pre_get_posts. This is the proper way to alter the main query and the hook you should always use to make changes to your primary content loop.
So, the code with pre_get_posts is correct and this is the function that you should use. Just one thing, always do a check that you are not on an admin page because pre_get_posts alters the back end as well. So this is the proper code to use in functions.php to remove posts tagged featured from the homepage
function exclude_featured_tag( $query ) {
if ( !is_admin() && $query->is_home() && $query->is_main_query() ) {
$query->set( 'tag__not_in', 'array(ID OF THE FEATURED TAG)' );
}
}
add_action( 'pre_get_posts', 'exclude_featured_tag' );
PART THREE
Extra reading material which will be helpful in future
Conditional tags
When should you use WP_Query vs query_posts() vs get_posts()?
When to use WP_query(), query_posts() and pre_get_posts
Query Overview
Guidance with The Loop for CMS
Creating a new WP_Query() object is always fine.
$sort= $_GET['sort'];
if($sort == "pricelow"){
$sort_args = array('meta_key' => 'price', 'orderby' => 'meta_value_num', 'order', 'ASC');
$new_query = new WP_Query($sort_args);
}
blah blah blah...
No no no sorry about that. I didn't see the pre_get_posts hook.
The code in your question is good for hooking queries. As in described in WordPress Plugin API/Action Reference/pre_get_posts:
pre_get_posts runs before WP_Query has been setup.
So it hooks the default WP_Query() where you want (in your code, it changes WP_Query on GET request).
In your template files, use new WP_Query($args).