Exclude parent posts and display only child posts in archive - wordpress

I have done this query and is working.I have a lot of child posts and i plan to display only child posts when listing the archive page of my custom post type city-guide.
$args = array(
'orderby' => 'date',
'order' => 'DESC',
'post_type' => 'city-guide',
'posts_per_page' => 36,
'paged' => $paged
);
$query = new WP_Query( $args );
?>
<?php $i=1; while( $query->have_posts() ): $query->the_post(); ?>
{
.....
}
I have tried
$all = get_posts(array('post_type'=> 'city-guide', 'posts_per_page' => -1));
$parents = array();
foreach ($all as $single)
{
$kids = get_children($single->ID);
if(isset($kids) && !empty($kids) && count($kids) >= 1)
{
$parents[] = $single->ID;
}
}
$args = array(
'orderby' => 'date',
'order' => 'DESC',
'post_type' => 'city-guide',
'post__not_in' => $parents,
'posts_per_page' => 36,
'paged' => $paged
);
$query = new WP_Query( $args );
?>
<?php $i=1; while( $query->have_posts() ): $query->the_post(); ?>
{
....
}
This did not work.Please help me find out where i went wrong.

I know it's an old question but hoping I can help someone that finds their way here looking for the same thing I was.
You can show ONLY child posts by excluding any posts with post_parent = 0 using the 'post_parent__not_in' argument:
$args = array(
'orderby' => 'date',
'order' => 'DESC',
'post_type' => 'city-guide',
'posts_per_page' => 36,
'paged' => $paged,
'post_parent__not_in' => array(0)
);
This avoids the need to loop thru each parent post to get each child.

I see you are trying to push the IDs into an array but why not just use the IDs while you are looping through them while getting the children within the loop at the same time? The example below is how I would tackle this.
<?php
$args = array(
'orderby' => 'date',
'order' => 'DESC',
'post_type' => 'city-guide',
'posts_per_page' => 36,
'paged' => $paged
);
$query = new WP_Query( $args );
$i=1; while( $query->have_posts() ): $query->the_post();
$parentID = get_the_ID();
$childrenArgs = array(
'post_type' => 'page',
'post_parent' => $parentID ,
);
$children = get_children($childrenArgs);
foreach ($children as $child){
echo '<h1>' . $child -> post_title . '</h1>';
$content = $child -> post_content;
$content = apply_filters('the_content', $content);
$content = str_replace(']]>', ']]>', $content);
echo $content;
}
endwhile;
?>

I think you need to look into the action pre_get_posts. Something like this in your functions.php would do the trick.
function namespace_custom_query_vars( $query ) {
if ( !is_admin() && $query->is_main_query()) {
if ( $query->query["post_type"] == 'custom_post_type' ) {
$query->set( 'post_parent__not_in', 0 );
}
}
return $query;
}
add_action( 'pre_get_posts', 'namespace_custom_query_vars' );
There's a decent post about this here. Though note that the code on this page does not compile for small syntax errors.

What about using relations? A simple disjunctive union should do the charm.
$args = array(
'post_type' => POST_TYPE,
'posts_per_page' => 36,
'orderby' => 'date',
'order' => 'DESC',
'tax_query' => array(
'relation' => 'AND',
array(
'taxonomy' => POST_TAXONOMY,
'field' => 'slug',
'terms' => $tax_slug,
'include_children' => true
),
array(
'taxonomy' => POST_TAXONOMY,
'field' => 'slug',
'terms' => $tax_slug,
'include_children' => false,
'operator' => 'NOT IN'
)
)
);
Or is there a reason why not to consider this?

Related

Filtered a query in WordPress

To display some items from a post type, I'm using this WordPress query:
$posts = get_posts(array(
'post_type' => 'realisations',
'status' => 'publish',
'order' => 'ASC'
));
But how can I filter the datas returned by this query depending the infos in the post type page ? For example, I have a input 'year' to get the year of the project.
Thanks.
You can use wp_query like Below
$args = array (
'post_type' => array( 'realisations' ),
'post_status' => array( 'publish' ),
'order' => 'ASC',
'orderby' => 'date',
'year' => 'yourinputyear' // 2021
);
$query = new WP_Query( $args );
if ( $query->have_posts() ) { ?>
<?php while ( $query->have_posts() ) : $query->the_post();
echo get_the_title();
endwhile;
}else{
echo "Data not found";
}
Please try this way. Hope is useful.
Thanks
You can use Date Parameters check below code.
$posts = get_posts( array(
'post_type' => 'realisations',
'status' => 'publish',
'order' => 'ASC',
'date_query' => array(
array( 'year' => 'yourinputyear' )
)
) );

Order posts by Title length in WP_QUERY

I am having problem ordering the posts based on the title length. Here is my code:
<?php
$terms = get_terms(array(
'taxonomy' => 'vendor_category',
'slug' => 'venues',
'hide_empty' => false
));
?>
<?php
foreach ($terms as $term) {
$eventargs = array(
'post_type' => 'vendor',
'posts_per_page' => -1,
'orderby' => 'title',
'order' => 'ASC',
'meta_key' => 'primary_category',
'meta_value' => $term->term_id,
);
$eventqry = new WP_Query($eventargs);
?>
How can i sort the posts based on the title length in ascending order.
You can save title length in post meta on save_post hook. and then you can retrieve post order by post meta value.
You can use save_post hook to save the post meta. put this code in your active theme.
//for existing vendors
add_action('admin_init', 'udpate_existing_vendor');
function udpate_existing_vendor(){
$existing_vendor_updated = get_option('existing_vendor_updated', 'no');
if( $existing_vendor_updated == 'no' ){
$vendor_args = array(
'post_type' => 'vendor',
'post_status' => 'publish',
'posts_per_page' => -1
);
$vendors = new WP_Query( $vendor_args );
if( $vendors->have_posts() ) {
while ( $vendors->have_posts() ) { $vendors->the_post();
$length = strlen( get_the_title() );
update_post_meta( get_the_ID(), 'title_length', $length );
} wp_reset_postdata();
}
update_option('existing_vendor_updated', 'yes');
}
}
// for new vendor
function save_vendor_title_length( $post_id ) {
$length = strlen( get_the_title( $post_id ) );
update_post_meta( $post_id, 'title_length', $length );
}
add_action( 'save_post_vendor', 'save_vendor_title_length');
Here your query will look like.
$terms = get_terms(array(
'taxonomy' => 'vendor_category',
'slug' => 'venues',
'hide_empty' => false
));
foreach ($terms as $term) {
$eventargs = array(
'post_type' => 'vendor',
'posts_per_page' => -1,
'orderby' => 'meta_value_num',
'order' => 'ASC',
'meta_key' => 'title_length'
);
$eventqry = new WP_Query( $eventargs );
}

Woocommerce products only "in stock"

There is the following code, the problem is that it displays all the goods in a row, regardless of status, but I would like to display only those that are "in stock".
function get_products($categories = array(), $product_type = 'featured_product', $paged = 1, $post_per_page = -1, $orderby = '', $order = '') {
global $woocommerce, $wp_query;
$args = array(
'post_type' => 'product',
'posts_per_page' => $post_per_page,
'post_status' => 'publish',
'paged' => $paged,
'orderby' => $orderby,
'order' => $order
); }
I'm not really sure what you're trying to do with your code, as your function and your args seem to be unrelated... but if you're just trying to get the products, try a custom loop:
$paged = get_query_var('paged') ? get_query_var('paged') : 1;
$args = array(
'post_type' => 'product',
'posts_per_page' => -1,
'post_status' => 'publish',
'paged' => $paged,
'tax_query' => array(
array(
'taxonomy' => 'product_visibility',
'field' => 'name',
'terms' => 'featured',
),
),
'meta_query' => array(
array(
'key' => '_stock_status',
'value' => 'instock',
'compare' => '=',
),
),
);
$query = new WP_Query( $args );
if ( $query->have_posts() ) {
while ( $query->have_posts() ) : $query->the_post();
// Do stuff.
endwhile;
endif;
wp_reset_postdata();
Note that I have not tested this and you clearly have something unique going on with how you're trying to display the posts, so you may need to make a few adjustments.

How do i show only 1 post from latest 10 post?

my english language is not good. sorry!
this code is for checkbox in advanced custom field plugin.
i want show only 1 post(randomly) from latest 10 post.
please help me. thanks
('posts_per_page' => 10) and ('numberposts' => 10) is not working.
<?php
$gallery = array(
"offset" => "0",
'showposts' => '1',
'orderby' => 'rand',
'meta_query' => array(
array(
'key' => 'postcat',
'value' => '"selection"',
'compare' => 'LIKE'
)));
// query
$qgallery = new WP_Query( $gallery );
?>
<?php if( $qgallery->have_posts() ): ?>
<?php while( $qgallery->have_posts() ) : $qgallery->the_post(); ?>
<div class="fromgallery">
<a href="0" class="frgall">
<span class="frgdesc"><?php the_title() ?></span>
</a></div>
<?php endwhile; ?><?php endif; ?>
Try this
$gallery = array(
'post_type' => 'post',
'posts_per_page' => 10,
'order' => 'DESC',
'no_found_rows' => 'true',
'_shuffle_and_pick' => 1
'meta_query' => array(
array(
'key' => 'postcat',
'value' => '"selection"',
'compare' => 'LIKE'
)));
$qgallery = new \WP_Query( $gallery );
I only do change in your code. For randomly one post you need to use '_shuffle_and_pick' => 1 , 'posts_per_page' => 10 is from 10 post and 'order' => 'DESC' is for latest posts. for custom '_shuffle_and_pick' you need to add
add_filter( 'the_posts', function( $posts, \WP_Query $qgallery )
{
if( $pick = $qgallery->get( '_shuffle_and_pick' ) )
{
shuffle( $posts );
$posts = array_slice( $posts, 0, (int) $pick );
}
return $posts;
}, 10, 2 );
To show Random post , Please use below script:
$args = array(
'post_type' => 'post',
'posts_per_page' => 10,
'orderby' => 'date',
'order' => 'DESC',
'no_found_rows' => 'true',
'_shuffle_and_pick' => 1
'post_status' => 'publish',
'meta_query' => array(
array(
'key' => 'postcat',
'value' => '"selection"',
'compare' => 'LIKE'
)
)
);
$the_query = new WP_Query( $args );
//check is post found
if ( $the_query->have_posts() ) {
while ( $the_query->have_posts() ) {
$the_query->the_post();
echo get_the_title();
}
wp_reset_postdata();
} else {
echo 'no posts found';
}
I hope it will help you :)

In Wordpress, wp_query with special attribute

When I use the WP_Query, I want to filter them by titles' initial letter, Like I only want the post when the initial is between 'F-J', what should I do with it.
$query_arguments = array(
'post_type' => $atts['_type'],
'post_status' => 'publish',
'orderby' => 'title',
'order' => 'ASC',
'posts_per_page' => $atts['postsPerPage'],
'ignore_sticky_posts'=> 1,
'paged' => $paged
);
$trombinoscope_query = new WP_Query($query_arguments);
You can try the mysql solution described here.
Something as :
<?php
$child_pages = $wpdb->get_results("SELECT * FROM $wpdb->posts WHERE (post_title like 'F%' OR post_title like 'G%' OR post_title like 'I%' OR post_title like 'F%') AND post_status='publish'");
if ( $child_pages ) : foreach ( $child_pages as $pageChild ) : setup_postdata( $pageChild );
//Your code comes here.
endforeach; endif;
?>
I add a meta_key, it's fine for me now.
like this
function set_meta_for_employe_post() {
$post_title = get_the_title();
$post_id = get_the_ID();
if ('employe' == get_post_type()) {
if($post_title) {
add_post_meta($post_id, 'initial_letter', $post_title[0], true);
}
}
}
add_action( 'save_post', 'set_meta_for_employe_post');
and after:
$query_arguments = array(
'post_type' => $atts['_type'],
'post_status' => 'publish',
'orderby' => 'title',
'order' => 'ASC',
'posts_per_page' => $atts['postsPerPage'],
'ignore_sticky_posts'=> 1,
'paged' => $paged,
'meta_key' => 'initial_letter',
'meta_value' => $letters,
);

Resources