Wordpress Custom Tax for CPT Paging 404? - wordpress

I have googled this issue for the last 4 days, and everything I have found has not fixed the issue.
My Custom Post Type's Custom Taxonomy template paging 404's unless I set the sites Blog posts per page to 1, which I cannot do, due to the fact that there will be a need to show more than 1 "blog post" per page...
How can I correct this issue?
LATEST FIX ATTEMPT
// fix the paging 404's on category/tag pages
add_action( 'pre_get_posts', function( $qry ) {
$_num_per_page = ( get_option( 'gyokb_option_name' )['gyokb_articles_pp'] ) ?? 5;
if( ( is_tax( 'kb_categories' ) || is_tax( 'kb_tags' ) ) && ! is_admin() ) {
$qry->set ( 'post_type', array( 'post', 'gyo_kb' ) );
$qry->set( 'posts_per_page', $_num_per_page );
}
} );
My CPT is here... (too much code to paste here...)
https://pastebin.com/SyKJwnCH
My Taxonomy is here...
https://pastebin.com/4BWWgGWq
And My Paging in the template:
<?php
echo paginate_links( array(
'format' => 'page/%#%',
'prev_text'=>' Previous ',
'next_text'=>' Next ',
'current' => max( 1, $page ),
'total' => $pg_ct,
'type' => 'plain',
'mid_size' => 4,
'paged' => $page, ) );
?>
with my WP_Query pulling it all together....
$args = array( 'post_type' => 'gyo_kb', 'posts_per_page' => $_num_per_page, 'paged' => $page,
'orderby' => 'date','order' => 'DESC',
'tax_query' => array(
array (
'taxonomy' => 'kb_categories',
'field' => 'slug',
'terms' => $cur_cat -> slug,
)
),
);
$the_query = new WP_Query( $args );
$page is populated with: $page = get_query_var( 'page' ); $page = ( ! empty( $page ) ) ? $page : 1;
All other variables are populating properly

I had the fix applying during the incorrect "boot" timing for wordpress. Initially I had placed in in the "wp" action.
I moved it to the "init" action, and now it works.

Related

Custom shortcode for parent and child taxonomy not working

I got a shortcode to print out the brand name connected to the current page:
add_shortcode( 'MARKE', 'marke_shortcode' );
function marke_shortcode() {
$terms = array(
'post_type' => 'fahrzeuge',
'taxonomy' => 'marken',
'hide_empty' => false,
'fields' => 'ids'
);
if( is_tax('marken') ) {
$terms['tax_query'] = array(
array(
'taxonomy' => 'marken',
'field' => 'term_id',
'terms' => (array) get_queried_object_id(),
)
);
}
$posts = get_posts( $terms );
if( ! empty( $posts ) )
return get_field( 'marken', $posts[0] );
return '0';
}
Unfortunately the code isn't working.
What I try to achieve is that the brand name, e.g. Tesla is printed out with the shortcode [MARKE] on both type of pages:
https://moinmobility.de/marken/tesla/
https://moinmobility.de/marken/tesla/model-3/
I tried a lot of code chunks and always if the brand name was printed correctly on the parent page, the child one was wrong.

Wordpress API - how to show different data in singular vs plural custom post type responses

I have a custom post type 'product' that returns quite a lot of data in the API response, up to 400 posts with a lot of nodes. Almost all the data is coming from advanced custom fields (I'm using ACF to API plugin to expose it).
On the 'products' page, I only need to show the title & image of the product. Is there a way to remove all other fields when requesting all products with https://example.com/wp-json/wp/v2/product, but leave that data in place when requesting a specific product with https://example.com/wp-json/wp/v2/product/123 ?
You better create a custom endpoint for all products. Add the code below in your custom plugin or add it in functions.php of theme (I will recommend the custom plugin approach though)
You can then access it using https://example.com/wp-json/custom/v1/all-products
add_action( 'rest_api_init', 'rest_api_get_all_products' );
function rest_api_get_all_products() {
register_rest_route( 'custom/v1', '/all-products', array(
'methods' => WP_REST_Server::READABLE,
'callback' => 'rest_api_get_all_products_callback',
'args' => array(
'page' => array(
'sanitize_callback' => 'absint'
),
'posts_per_page' => array(
'sanitize_callback' => 'absint'
)
)
));
}
function rest_api_get_all_products_callback( $request ) {
$posts_data = array();
$paged = $request->get_param( 'page' );
$posts_per_page = $request->get_param( 'posts_per_page' );
$paged = ( isset( $paged ) || ! ( empty( $paged ) ) ) ? $paged : 1;
$posts_per_page = ( isset( $posts_per_page ) || ! ( empty( $posts_per_page ) ) ) ? $posts_per_page : 10;
$query = new WP_Query( array(
'paged' => $paged,
'posts_per_page' => $posts_per_page,
'post_status' => 'publish',
'ignore_sticky_posts' => true,
'post_type' => array( 'product' )
)
);
$posts = $query->posts;
if( empty( $posts ) ){
return new WP_Error( 'no_post_found', 'No Products Found.', array( 'status' => 404 ) );
}
foreach( $posts as $post ) {
$id = $post->ID;
$post_thumbnail = ( has_post_thumbnail( $id ) ) ? get_the_post_thumbnail_url( $id ) : null;
$posts_data[] = (object) array(
'id' => intval($id),
'title' => $post->post_title,
'featured_img' => $post_thumbnail
);
}
$response = rest_ensure_response( $posts_data );
return $response;
}

Group Posts by meta_query

I'm trying to group my posts by a meta value, and can't seem to figure it out. My query below just returns "featured" posts. I would like the query to return all posts, but have the "featured" results before the rest.
Any ideas?
$args = array(
'posts_per_page' => '20',
'paged' => $current_page,
'meta_query' => array(
array(
'key' => 'tags',
'value' => 'featured',
'compare' => 'like'
)
),
'order_by' => 'date',
'order' => 'DESC'
);
Your answer is rewind_posts(). Run your query to get all the posts, run your loop and filter out all posts which is not featured, rewind the loop, rerun the loop and filter out featured posts.
Something like this will do
$args = [
// Your query arguments to get all postst
];
$q = new WP_Query( $args );
if ( $q->have_posts() ) {
while ( $q->have_posts() ) {
$q->the_post();
if ( get_post_meta( $post->ID, 'tags', true ) == 'featured' ) {
// Run your loop for featured posts
}
}
$q->rewind_posts(); // Rewind the loop to rerun it
while ( $q->have_posts() ) {
$q->the_post();
if ( get_post_meta( $post->ID, 'tags', true ) != 'featured' ) {
// Run your loop for non featured posts
}
}
wp_reset_postdata();
}

Wordpress paginated list of terms showing wrong number of pages?

I've created a paginated list of terms for a custom taxonomy, but the pagination is not showing correctly. No matter how many posts per page I set, only two pages are output.
So with 6 posts and set to 6 per page, I see two pages, the second one blank. With 6 posts and 2 per page I see two pages, and there is no third page (I've tried typing /page/3/ into the url bar and the page is not found, so it's not just a problem with the pagination buttons but seems to be a problem with the number of pages being output by Wordpress).
Can anyone see why this might be? How can I get the pagination working correctly?
I've added a bounty to this question, if anyone can suggest a way of getting this pagination working correctly.
UPDATE 19/12:
I'm part of the way to solving this. I've discovered part of the issue seems to be partly to do with the Reading settings in WP. I had the reading settings set to 6 per page, which is why no matter what I set in $posts_per_page in the template file, I only got an output of 2 pages.
Now I can get Wordpress to output all the pages and pagination links if I make sure that the reading settings match the number set in the template file, but I always get an extra output from the for loop, resulting in an empty div. This causes an extra page in some instances depending on the number of posts on the last page. I'm also getting no pagination links on the last page.
Code excerpt from archive-prints.php:
$posts_per_page = 6;
$page = ( get_query_var( 'paged' ) ) ? get_query_var( 'paged' ) : 1;
$offset = ( $page - 1 );
$categories = get_terms('prints_cat');
for( $i = $offset * $posts_per_page; $i < ( $offset + 1 ) * $posts_per_page; $i++ ) {
$category = $categories[$i];
echo '<div class="cat-preview"><a href="';
echo get_term_link($category->slug, 'prints_cat');
echo '"><h2>';
echo $category->name;
echo '</h2></a></div>';
}
unset( $category );
custom_page_navi();
And the code for my custom_page_navi() function, from my functions.php file:
function custom_page_navi() {
global $wp_query;
$bignum = 999999999;
if ( $wp_query->max_num_pages <= 1 )
return;
echo '<nav class="pagination">';
echo paginate_links( array(
'base' => str_replace( $bignum, '%#%', esc_url( get_pagenum_link($bignum) ) ),
'format' => '',
'current' => max( 1, get_query_var('paged') ),
'total' => $wp_query->max_num_pages,
'prev_text' => 'Prev',
'next_text' => 'Next',
'type' => 'list',
'show_all' => false,
'end_size' => 2,
'mid_size' => 0
) );
echo '</nav>';
}
You could create a custom page template file tpl_list.php with the following code:
<?php
/**
* Template Name: Paginated list of terms for a custom taxonomy
*
*/
// Edit:
$taxonomy = 'prints_cat';
$number = 3; // number of terms to display per page
// Setup:
$page = ( get_query_var( 'paged' ) ) ? get_query_var( 'paged' ) : 1;
$offset = ( $page > 0 ) ? $number * ( $page - 1 ) : 1;
$totalterms = wp_count_terms( $taxonomy, array( 'hide_empty' => TRUE ) );
$totalpages = ceil( $totalterms / $number );
// Debug:
// printf( 'taxonomy: %s - number: %s - page: %s - offset: %s - totalterms %s - totalpages: %s' , $taxonomy, $number, $page, $offset, $totalterms, $totalpages );
// Here I list all the available paramters to get_terms():
$args = array(
'orderby' => 'name',
'order' => 'ASC',
'hide_empty' => true,
'exclude' => array(),
'exclude_tree' => array(),
'include' => array(),
'number' => $number,
'fields' => 'all',
'slug' => '',
'parent' => '',
'hierarchical' => true,
'child_of' => 0,
'get' => '',
'name__like' => '',
'pad_counts' => false,
'offset' => $offset,
'search' => '',
'cache_domain' => 'core'
);
$terms = get_terms( $taxonomy, $args );
foreach ( $terms as $term )
{
printf( '<div class="cat-preview"><h2>%s</h2></div>',
get_term_link($term->slug, 'country'),
$term->name,
$term->name
);
}
// Show custom page navigation
printf( '<nav class="pagination">%s</nav>',
custom_page_navi( $totalpages, $page, 3, 0 )
);
where
function custom_page_navi( $totalpages, $page, $end_size, $mid_size )
{
$bignum = 999999999;
if ( $totalpages <= 1 || $page > $totalpages ) return;
return paginate_links( array(
'base' => str_replace( $bignum, '%#%', esc_url( get_pagenum_link( $bignum ) ) ),
'format' => '',
'current' => max( 1, $page ),
'total' => $totalpages,
'prev_text' => 'Prev',
'next_text' => 'Next',
'type' => 'list',
'show_all' => false,
'end_size' => $end_size,
'mid_size' => $mid_size
) );
}
Create a page (for example called prints ) and select the above page template.
Then you can visit:
example.com/prints/
example.com/prints/page/2/
example.com/prints/page/3/
And if you uncomment the debug line, you will get for example:
taxonomy: prints_cat -
number: 3 -
page: 2 -
offset: 3 -
totalterms 6 -
totalpages: 2
The value of your
'end_size' => 2, 'mid_size' => 0
is different from the the default values mentioned in codex, can you try changing them to
'end_size' => 1,
'mid_size' => 2

WordPress pagination showing extra blank page after filtering past events

I have a list of events that are displaying in date order, with events in the past being hidden.
The issue is that in total, there are 3 pages of events, but once the past events are hidden, there are only enough events to fill 2 pages. However, a third, blank page is still present and can be accessed through the paging links.
This is the code on my events list page:
<?php $today = date("Ymd");?>
<?php $paged = 1;
if ( get_query_var('paged') ) $paged = get_query_var('paged');
if ( get_query_var('page') ) $paged = get_query_var('page');
query_posts( '&post_type=upcomingevents&paged=' . $paged );?>
<?php $loop = new WP_Query( array( 'post_type' => 'upcomingevents', 'paged'=> $paged, 'meta_key' => 'start_date', 'meta_compare' => '>=', 'meta_value' => $today, 'orderby' => 'meta_value_num', 'order' => 'ASC' )); ?>
<?php while ( $loop->have_posts('post_type=upcomingevents') ) : $loop->the_post(); ?>
And this is the paging code in my functions file:
function paginate() {
global $wp_query, $wp_rewrite;
$wp_query->query_vars['paged'] > 1 ? $current = $wp_query->query_vars['paged'] : $current = 1;
$pagination = array(
'base' => #add_query_arg('page','%#%'),
'format' => '',
'total' => $wp_query->max_num_pages,
'current' => $current,
'show_all' => true,
'type' => 'plain'
);
if ( $wp_rewrite->using_permalinks() ) $pagination['base'] = user_trailingslashit( trailingslashit( remove_query_arg( 's', get_pagenum_link( 1 ) ) ) . 'page/%#%/', 'paged' );
if ( !empty($wp_query->query_vars['s']) ) $pagination['add_args'] = array( 's' => get_query_var( 's' ) );
echo paginate_links( $pagination );
}
I have also discovered a second issue, when moving to page 2 or 3 of results, the CSS class of current remains on the number 1 within the paging, so impossible to tell which page you are on.
Any suggestions would be greatly appreciated, many thanks.
$paged value is 0 on 1st page so edit your first snippet:
$paged = 0;
also, as you're using WP_Query, you can safely delete following line, which is probably doing more wrong than good:
query_posts( '&post_type=upcomingevents&paged=' . $paged );

Resources