Wordpress: previous_post_link / next_post_link by alphabetical order? - php

I'm developing a wordpress website with custom posts which are ordered alphabetically in the loop.
<!-- THE ARGS -->
<?php global $query_string;
$args = wp_parse_args($query_string);
$args = array(
'post_type' => 'custom_post',
'orderby' => 'title',
'order' => 'ASC',
'posts_per_page' => -1,
); ?>
<!-- THE LOOP -->
<?php $wp_query = new WP_Query( $args ); ?>
<?php while ($wp_query->have_posts()) : $wp_query->the_post(); ?>
<?php endwhile; ?>
<?php wp_reset_query(); ?>
Nothing fancy there, just a normal loop.
When I open a post, in its page I have the usual previous_post_link and next_post_link so I can navigate through posts. However, this is done by chronological order of the posts, and I wish to do so by the same alphabetical order as I used in the loop, of course. Any help on this matter would be very appreciated.
Thanks in advance!

It looks like this plug-in does what you're after, e.g.:
<ul class="pager">
<?php previous_post_link_plus( array('order_by' => 'post_title') ); ?>
<?php next_post_link_plus( array('order_by' => 'post_title') ); ?>
</ul>

You can do this by using filters in the get_adjacent_post function.
In your functions.php file, add:
function mytheme_previous_post_orderby_name($orderby){
return "ORDER BY p.post_title DESC LIMIT 1";
}
function mytheme_previous_post_where_name(){
global $post, $wpdb;
return $wpdb->prepare( "WHERE p.post_title < %s AND p.post_type = %s AND ( p.post_status = 'publish' OR p.post_status = 'private' )", $post->post_title, $post->post_type );
}
function mytheme_next_post_orderby_name($orderby){
return "ORDER BY p.post_title ASC LIMIT 1";
}
function mytheme_next_post_where_name(){
global $post, $wpdb;
return $wpdb->prepare( "WHERE p.post_title > %s AND p.post_type = %s AND ( p.post_status = 'publish' OR p.post_status = 'private' )", $post->post_title, $post->post_type );
}
Then in your single.php page add the filters before you call the previous/next posts link functions:
add_filter('get_previous_post_sort', 'mytheme_previous_post_orderby_name', 10, 1);
add_filter('get_next_post_sort', 'mytheme_next_post_orderby_name', 10, 1);
add_filter('get_previous_post_where', 'mytheme_previous_post_where_name', 10);
add_filter('get_next_post_where', 'mytheme_next_post_where_name', 10);
the_post_navigation();
remove_filter('get_previous_post_sort', 'mytheme_previous_post_orderby_name', 10);
remove_filter('get_next_post_sort', 'mytheme_next_post_orderby_name', 10);
remove_filter('get_previous_post_where', 'mytheme_previous_post_where_name', 10);
remove_filter('get_next_post_where', 'mytheme_next_post_where_name', 10);
If you want to check for your specific post_type, you can add an if around the adding filter section:
if($post->post_type == 'my_custom_post_type'){
add_filter(...);
the_post_navigation();
remove_filter(...);
}
or, you can just use a post_type specific single.php file!
This worked great for me, but there may be some limitations if you are planning on combining this with posts in the same term...

Related

Interference of WordPress codes

On my site, I intend to display the total number of posts and comments on the site, as well as the total number of purchases made from my site.
The codes I wrote are as follows:
//copy to functions.php
// Total Comment
function site_total_comment_count() {
$num_comm = get_comment_count();
$num_comm = $num_comm['total_comments'];
echo $num_comm ;}
add_shortcode('total_comment_count', 'site_total_comment_count');
// Total Completed Orders
function total_completed_Orders() {
$query = new WC_Order_Query( array(
'limit' => 99999,
'status' => array( 'completed' ),
'return' => 'ids',
) );
$orders = $query->get_orders();
return count( $orders ); }
// Copy to the desired page
<h2> All Orders:
<?php echo total_completed_Orders(); ?>
</h2>
<h2> All Comments:
<?php echo site_total_comment_count(); ?>
</h2>
<h2> All Posts:
<?php
echo $wpdb->get_var("SELECT COUNT(ID) FROM $wpdb->posts WHERE post_type = 'post' AND post_status = 'publish'");
?>
</h2>
These codes work fine individually, but when I put all three on the target page, the stats show wrong.
Can you write me a code that shows the correct statistics of these three items from my site?
You can create a custom shortcode.
Try out this in your functions.php file:
add_shortcode('custom_shortcode', 'kb_get_details');
function kb_get_details()
{
//For total post.
global $wpdb;
$total_post = $wpdb->get_var("SELECT COUNT(ID) FROM $wpdb->posts WHERE post_type = 'post' AND post_status = 'publish'");
//For total comments.
$num_comm = get_comment_count();
$total_cmt = $num_comm['total_comments'];
//For total orders.
$query = new WC_Order_Query(array(
'limit' => 99999,
'status' => array('completed'),
'return' => 'ids',
));
$orders = $query->get_orders();
$total_orders = count($orders);
?>
<h2>All Posts : <?php esc_html_e($total_post); ?></h2>
<h2>All Comments: <?php esc_html_e($total_cmt); ?></h2>
<h2>All Orders : <?php esc_html_e($total_orders); ?></h2>
<?php
}
After that, this shortcode can be directly add it to your target page from the backend. You can also add it to any custom template by the use of do_shortcode('[custom_shortcode]');

How do I access the array of posts from a custom taxonomy so I can sort it?

I have a custom taxonomy called mwp_ss_supp. I have a page that displays all the posts using this code:
<?php $count = wp_count_posts('mwp_ss_supp')->publish;
echo '<div id="post-count">' . $count . ' posts displayed</div>';?>
<?php
if ( have_posts() ) :
while (have_posts()) : the_post();
DO STUFF
<?php
endwhile;
endif; ?>
The problem is that all the posts are displaying in the order of latest post is the first on the list published. But I want to print them in a different order (ie, posts 1-10 are published first, posts 15-20 are published next, and 11-14 are published last, which ends up being published in alphabetical order by title). So how do I access this array of posts? There doesn't seem to be an array variable to play around with.
Show sql query for that. The sql query gets data from the database and determines the sort
Try adding a pre_get_posts() modifier to your theme's functions.php:
function taxo_posts($query)
{
if ($query->is_tax('mwp_ss_supp') && $query->is_main_query())
{
$query->set( 'orderby', 'title' );
$query->set( 'order', 'ASC' ); // or DESC
}
}
add_action('pre_get_posts', 'taxo_posts');
You need to build a custom wordpress query WP_Query() to query posts against taxonomies:
<?php
$args = array(
'post_type' => 'custom_post_type',
'tax_query' => array(
array(
'taxonomy' => 'custom_taxonomy_type',
);
);
'orderby'=> 'title',
'order' => 'ASC',
);
/**
* WP_Query()
* The WordPress Query class.
* #link https://developer.wordpress.org/reference/classes/wp_query/
*/
$query = new WP_Query( $args );
if ( $query->have_posts() ) :
while ( $query->have_posts() ) : $query->the_post();
if( get_the_title() !== '' ):
the_title( '<h1>', '</h1>' );
endif;
if( get_the_content() !== '' ):
the_content();
endif;
endwhile;
endif;
/**
* wp_reset_postdata()
* After looping through a separate query, this function restores the $post global to the current post in the main query.
* #link https://developer.wordpress.org/reference/functions/wp_reset_postdata/
*/
wp_reset_postdata(); ?>
Learn more
wp_query # https://developer.wordpress.org/reference/classes/wp_query/

Show custom post type taxonomy with URL in WordPress site

I am working in a WordPress site that has a custom post type of photos. I have added a custom taxonomy caller category. I want to show the custom category name with URL. But for some reason it is showing blank. How can I fix it?
Here are my codes I am trying
<?php
$args = array(
'post_type' => 'photos',
'post_status' => 'publish',
'paged' => get_query_var('paged')
);
$the_query = new WP_Query($args);
?>
<?php
if ($the_query->have_posts()):
while ($the_query->have_posts()):
$the_query->the_post();
?>
<div>Meal type: <?php echo get_the_term_list($post->ID, 'category', '', ', ', ''); ?></div>
<?php endwhile; ?>
<?php wp_reset_postdata(); ?>
<?php else: ?>
<p><?php _e('Sorry, no posts matched your criteria.'); ?></p>
<?php endif; ?>
If your question is why the "div" tag in the while loop is appearing blank, that's due to the while loop's conditions not being met. One or more of your arguments are returning false.
<?php
$args = array(
'post_type' => 'photos',
'post_status' => 'publish',
'paged' => get_query_var('paged')
);
$the_query = new WP_Query($args);
?>
<?php
if ($the_query->have_posts()):
while ($the_query->have_posts()):
$the_query->the_post();
?>
Essentially, WP_Query is calling multiple classes such as WP_Tax_Query and WP_Meta_Query and is doing an SQL request as follows based on the criteria you provided:
SELECT SQL_CALC_FOUND_ROWS wp_posts.ID FROM wp_posts
WHERE 1=1 AND wp_posts.post_type = 'photos' AND ((wp_posts.post_status = 'publish'))
ORDER BY wp_posts.post_date DESC LIMIT 0, 10
It's searching to see if there are posts that fit the criteria that you specified, a post type of "photos" and a "published" status. I would assume that it's not finding these criteria and is returning with a value of false.
More information:
WP_QUERY
I think the issue is with your custom taxonomy name category, because category is already associated with post type post. So you are getting a blank output.
How to fix:: rename category to photos_cat (or with any name of your wish).
Hope this helps!

Wordpress combine query and output different styling dependant on post type

I have two WordPress post types the normal 'post' and a custom post type called 'notes'. I want to combine both and sort them by date. I managed to find the combine query and that's working fine. The problem is I'd like to have different styling for notes. I thought I could do a wordpress if_singlular('notes') to try and target it.. but I'm guessing it's getting lost when the merge happens.
Does anyone know how I could achieve this functionality?
Many thanks!
My php:
<?php
// An example of creating two separate WP queries, combining the results,
// sorting by date and formatting the results for us in a loop like a regular query.
// order the posts by date in descending order (should go in functions.php to keep things tidy)
function order_by_date( $a, $b )
{
return strcmp( $b->post_date, $a->post_date );
}
// get the posts for the first query
$q1_args = array(
'post_type' => 'post',
'posts_per_page' => -1,
'post_status' => 'publish'
);
$q1_posts = get_posts( $q1_args );
// get the posts for the second query
$q2_args = array(
'post_type' => 'notes',
'posts_per_page' => -1,
'post_status' => 'publish'
);
$q2_posts= get_posts( $q2_args );
// Merge the post arrays together, and sort by date using the order_by_date function
$final_posts = array_merge( $q1_posts, $q2_posts );
usort( $final_posts, 'order_by_date' );
// Loop over the posts and use setup_postdata to format for template tag usage
foreach ( $final_posts as $key => $post ) {
setup_postdata( $post );
// Now we can use template tags as if this was in a normal WP loop
foreach ( $final_posts as $key => $post ) {
setup_postdata( $post );
// Now we can use template tags as if this was in a normal WP loop
echo '
<article class="item shortNote">
<div class="snMeta clearfix">
<img src="'.get_bloginfo('template_url').'/assets/images/sn-icon.png" alt="Short Note" />
<span class="metaDate">'. get_the_date('M / d / Y').'</span>
<strong>Short Note</strong>
</div>
<h2>'.get_the_title().'</h2>
</article>';
}
}
?>
Ok so this should do it:
<?php
// An example of creating two separate WP queries, combining the results,
// sorting by date and formatting the results for us in a loop like a regular query.
// order the posts by date in descending order (should go in functions.php to keep things tidy)
function order_by_date( $a, $b ) {
return strcmp( $b->post_date, $a->post_date );
}
// get the posts for the first query
$q1_args = array(
'post_type' => 'post',
'posts_per_page' => -1,
'post_status' => 'publish'
);
$q1_posts = get_posts( $q1_args );
// get the posts for the second query
$q2_args = array(
'post_type' => 'notes',
'posts_per_page' => -1,
'post_status' => 'publish'
);
$q2_posts= get_posts( $q2_args );
// Merge the post arrays together, and sort by date using the order_by_date function
$final_posts = array_merge( $q1_posts, $q2_posts );
usort( $final_posts, 'order_by_date' );
// Loop over the posts and use setup_postdata to format for template tag usage
foreach ( $final_posts as $key => $post ) {
$post_type = $post->post_type;
setup_postdata( $post );
// Now we can use template tags as if this was in a normal WP loop
<article class="item shortNote ' . $post_type . '">
<div class="snMeta clearfix">
<img src="'.get_bloginfo('template_url').'/assets/images/sn-icon.png" alt="Short Note" />
<span class="metaDate">'. get_the_date('M / d / Y').'</span>
<strong>Short Note</strong>
</div>
<h2>'.get_the_title().'</h2>
</article>';
}
?>
I just had to test it on my server to see if it works. So I added the $post_type variable that should return the post type, and then I just put that in your class in the <article> tag, so you can differentiate :)
Tip:
When in doubt what your loop outputs, always do print_r(). This will show you what you are dealing with (arrays, strings, objects) so you easily know what to target :)
Hope this helps.

Wordpress query to display most commented articles over X days

I'm creating a wordpress widget to display the most commented articles over the last 4 days.
I have this so far
global $wpdb;
global $pagepost;
function filter_where( $where = '' ) {
// posts in the last 4 days
$where .= " AND post_date > '" . date('Y-m-d', strtotime('-4 days')) . "'";
return $where;
}
add_filter( 'posts_where', 'filter_where' );
$the_query = new WP_Query( 'posts_per_page=4;orderby=comment_count' );
remove_filter( 'posts_where', 'filter_where' );
?>
<ul>
<?php while ( $the_query->have_posts() ) : $the_query->the_post();
echo "<li>";
echo "<a href='".get_permalink()."' class='linkTitle'>";
echo get_the_title();
echo "</a>";
woo_post_meta();
echo "<div class='fix'>";
echo "</li>";
endwhile;
echo "</ul>";
wp_reset_postdata();
Which from what I can find on the wordpress site should return the articles from the last 4 days ordered by comment_count
but it's just showing me my last 4 articles, I'm sure I'm doing something very obviously wrong here but I can't get it
I want the 4 articles with the most comments where the article was posted in the last 4 days.
someone please save what little hair I have left
Thanks to #swapnesh I found the answer.
My query wasn't correct, it should have been like this
$the_query = new WP_Query(array( 'posts_per_page' => 4, 'orderby' => 'comment_count', 'order'=> 'DESC' ));
$querystr = "
SELECT $wpdb->posts.* FROM $wpdb->posts WHERE 1=1 AND $wpdb->posts.post_status = 'publish' AND $wpdb->posts.post_type = 'post' ORDER BY $wpdb->posts.comment_count DESC
";
Use this custom query
$pageposts = $wpdb->get_results($querystr, OBJECT);
echo''; print_r($pageposts); echo'';

Categories