Re-Order Posts / Queries

More from this category




RE-Order Custom Post Type

Example #1

https://stackoverflow.com/questions/31434373/in-wordpress-how-do-i-set-the-default-admin-sort-order-for-a-custom-post-type-t

[code style=”css”]
is_admin() && add_action( ‘pre_get_posts’, ‘extranet_orderby’ );

function extranet_orderby( $query )
{
// Nothing to do:
if( ! $query->is_main_query() || ‘clientarea’ != $query->get( ‘post_type’ ) )
return;

//——————————————-
// Modify the ‘orderby’ and ‘meta_key’ parts
//——————————————-

$orderby = $query->get( ‘orderby’);

switch ( $orderby )
{
case ‘extranet_sort_office’:
$query->set( ‘meta_key’, ‘extranet_case_office’ );
$query->set( ‘orderby’, ‘meta_value_num’ );
break;
case ‘extranet_sort_date’:
$query->set( ‘meta_key’, ‘extranet_appointment_date’ );
$query->set( ‘orderby’, ‘meta_value’ );
break;
case ”: // <– The default empty case
$query->set( ‘meta_key’, ‘extranet_appointment_date’ );
$query->set( ‘orderby’, ‘meta_value’ );
break;
case ‘extranet_sort_type’:
$query->set( ‘meta_key’, ‘extranet_appointment_type’ );
$query->set( ‘orderby’, ‘meta_value’ );
break;
case ‘extranet_sort_IP’:
$query->set( ‘meta_key’, ‘extranet_insolvency_practioner’ );
$query->set( ‘orderby’, ‘meta_value_num’ );
break;
default:
break;
}
}
[/code]

where we added a main query check and an empty switch case.

Example #2

Here’s another approach, without the switch part (PHP 5.4+):

[code style=”css”]
is_admin() && add_action( ‘pre_get_posts’, ‘extranet_orderby’ );

function extranet_orderby( $query )
{
// Nothing to do
if( ! $query->is_main_query() || ‘clientarea’ != $query->get( ‘post_type’ ) )
return;

//——————————————-
// Modify the ‘orderby’ and ‘meta_key’ parts
//——————————————-
$orderby = strtolower( $query->get( ‘orderby’) );
$mods = [
‘office’ => [ ‘meta_key’ => ‘extranet_sort_office’, ‘orderby’ => ‘meta_value_num’ ],
‘date’ => [ ‘meta_key’ => ‘extranet_appointment_date’, ‘orderby’ => ‘meta_value’ ],
” => [ ‘meta_key’ => ‘extranet_appointment_date’, ‘orderby’ => ‘meta_value’ ],
‘type’ => [ ‘meta_key’ => ‘extranet_sort_type’, ‘orderby’ => ‘meta_value_num’ ],
‘ip’ => [ ‘meta_key’ => ‘extranet_insolvency_practioner’, ‘orderby’ => ‘meta_value_num’ ],
];
$key = ‘extranet_sort_’ . $orderby;
if( isset( $mods[$key] ) )
{
$query->set( ‘meta_key’, $mods[$key][‘meta_key’] );
$query->set( ‘orderby’, $mods[$key][‘orderby’] );
}
}
[/code]

Re-Order by Title- site wide (not admin)

[code style=”css”]
function order_posts_by_title( $query ) {

if ( $query-is_home() && $query-is_main_query() ) {

$query-set( ‘orderby’, ‘title’ );

$query-set( ‘order’, ‘ASC’ );

}

}

add_action( ‘pre_get_posts’, ‘order_posts_by_title’ );
[/code]

EXTENDED TRACK

https://premium.wpmudev.org/blog/arrange-wordpress-posts-any-order/

How to Arrange WordPress Posts in Any Order

Have you ever tried to change the standard order of posts on your site’s blog page? By default, posts are ordered based on the date that each post is published, and there’s no built-in way to change the order in which posts appear.

If you do want to change the post order, you have three options: change the post publish date, write some code to sort posts using a parameter other than the date of publication, or find a plugin that will do the job for you.

Changing the publish date is not a viable option for many blogs. So, in this article, we’ll look at the second and third options on the list. First, I’ll show you how to build a custom plugin to implement a custom post order. Second, we’ll take a look at a two plugins available from the WordPress plugin directory that can be used to create a custom post order.

Prerequisite Knowledge

This post assumes a certain level of WordPress programming knowledge. If you’ve never created a simple plugin or a page template before, you will struggle to follow along. If you do struggle to follow along, the following posts will help you learn what you need to know to understand the material in this tutorial:

Creating Custom Page Templates in WordPress

How to Create a WordPress Plugin

An In-Depth Guide to Conquering WP_Query

If you aren’t interested in building a custom plugin you can skip to the list of plugins available from the WordPress plugin directory that make the process a lot easier.

In addition, I’ve pulled all of the code in this tutorial into a GitHub repo. If you’d like to see what the finished product should look like, you can view and download all of the code from GitHub.

Build Your Own Custom Post Order Plugin

There are two major steps to take to implement a custom post order:

Add a custom field to posts that can be used as a basis for sorting the posts.
Implement the custom sort order by modifying the main WordPress loop or building a custom loop and adding it to a sidebar widget or custom page template.
Let’s start by adding a custom field to the WordPress post editing screen. However, before doing that you’ll need to fire up your WordPress development environment, create a new plugin folder, and create a plugin file in that folder. If you want to see what my plugin’s structure looks like, you can see the finished product at GitHub.

Set Up the Custom Field

While you could just use the Custom Fields meta box in the post edit screen to add custom meta data to each post, I prefer to add a custom meta box and field right to the backend. That way, you can’t accidentally assign meta data to the wrong field.

The first step in adding a custom meta box to the backend is to create the meta box and add it to the post edit screen.

[code style=”php”]
<?php
/* Create custom meta data box to the post edit screen */

function jpen_custom_post_sort( $post ){
add_meta_box(
‘custom_post_sort_box’,
‘Position in List of Posts’,
‘jpen_custom_post_order’,
‘post’ ,
‘side’
);
}
add_action( ‘add_meta_boxes’, ‘jpen_custom_post_sort’ );
?>
[/code]

That bit of code, added to your plugin file will create the custom meta box.

You’ll notices that the callback function in the bit of code above is ‘jpen_custom_post_order’. Let’s create that function next and add it to our plugin file. It will add a field to the meta box we just created.

[code style=”php”]
<?php
/* Add a field to the metabox */

function jpen_custom_post_order( $post ) {
wp_nonce_field( basename( __FILE__ ), ‘jpen_custom_post_order_nonce’ );
$current_pos = get_post_meta( $post->ID, ‘_custom_post_order’, true); ?>
<p>Enter the position at which you would like the post to appear. For exampe, post "1" will appear first, post "2" second, and so forth.</p>
<p><input type="number" name="pos" value="<?php echo $current_pos; ?>" /></p>
<?php
}
?>
[/code]
view rawadd-field-to-custom-meta-data-box.php hosted with ❤ by GitHub

That bit of code starts by setting a nonce. Next, the code creates a variable called $current_pos and assigns the value of the current post sort order to that variable. Next, two paragraph elements create the visible content of the meta box field and the current value is echoed into the field if a current value exists. Here’s what the box will look like:

screenshot of custom sort order box on post edit screen
Finally, we need to store user input to the database. We can do that by adding this bit of code to our plugin:

[code style=”php”]
<?php
/* Save the input to post_meta_data */

function jpen_save_custom_post_order( $post_id ){
if ( !isset( $_POST[‘jpen_custom_post_order_nonce’] ) || !wp_verify_nonce( $_POST[‘jpen_custom_post_order_nonce’], basename( __FILE__ ) ) ){
return;
}
if ( defined( ‘DOING_AUTOSAVE’ ) && DOING_AUTOSAVE ){
return;
}
if ( ! current_user_can( ‘edit_post’, $post_id ) ){
return;
}
if ( isset( $_REQUEST[‘pos’] ) ) {
update_post_meta( $post_id, ‘_custom_post_order’, sanitize_text_field( $_POST[‘pos’] ) );
}
}
add_action( ‘save_post’, ‘jpen_save_custom_post_order’ );
?>
[/code]
view rawsave-custom-field-to-the-database.php hosted with ❤ by GitHub
That code first checks to make sure that the nonce has been set and that the user has permission to make changes to the post. If everything checks out, the post meta data is updated with the new custom post order value.

Display the Custom Field in the Admin

In the last section we added a custom meta box to the post edit screen and programmed it to store a numeric value. A little later we’ll use that numeric value to create a custom post order. However, before we get to that, we have another problem to solve.

As things stand, to see the current post sort order value we have to open each post and take a look at the custom meta box we just added to the post edit screen. That isn’t very convenient. Let’s add the custom sort order value to the admin post list so that we can quickly see the current post order value assigned to each post.

First, we need to add a custom column to the post list in the admin area. We can do that by adding this bit of code to our plugin:

[code style=”php”]
<?php
/* Add custom post order column to post list */

function jpen_add_custom_post_order_column( $columns ){
return array_merge ( $columns,
array( ‘pos’ => ‘Position’, ));
}
add_filter(‘manage_posts_columns’ , ‘jpen_add_custom_post_order_column’);
?>
[/code]
view rawadd-custom-column-to-post-list-in-wp-admin.php hosted with ❤ by GitHub
Next, we need to pull up the custom post order value for each post and list it in the new column. That’s not too difficult, and we can do it by adding this function to our plugin file:

[code style=”php”]
<?php
/* Display custom post order in the post list */

function jpen_custom_post_order_value( $column, $post_id ){
if ($column == ‘pos’ ){
echo ‘<p>’ . get_post_meta( $post_id, ‘_custom_post_order’, true) . ‘</p>’;
}
}
add_action( ‘manage_posts_custom_column’ , ‘jpen_custom_post_order_value’ , 10 , 2 );
?>
[/pgp]
view rawadd-custom-post-order-value-to-post-list-in-wp-admin.php hosted with ❤ by GitHub<br>
Great. Now, when we visit the blog post list in the admin we can easily see which posts have been assigned a custom sort order value.<br><br>

Here’s how things are looking when we view the blog post list in the admin area:
<br><br>
list of posts with position added<br><br>
Put the Custom Post Order to Good Use<br><br>
Now that we’ve made it possible to assign a custom order to posts, it’s time to put that custom order to good use. However, before we can do that we’ll have to answer this question: “How do we want to use the custom sort order?”
<br><br>
There are several different ways you might want to implement the custom sort. Here are a few ideas:
<br><br>
Sort all of your posts into a custom order and display the custom sorted list on your blog posts page. You probably wouldn’t want to do this on a busy blog, but if you use WordPress to host a series of instructional posts that and don’t add new posts frequently, this could be a valuable way to sort posts in any order.
Create a curated list of posts and display them in the order of your choice using a custom page template. For example, you could curate the list to only include posts that also belong to a specific category and then sort them into whatever order you wish.<br><br>
Create a blog post list that begins with a few custom sorted posts and then includes all of the rest of your posts in their standard order.
Really, the sky is the limit. If you can think up a use for the custom sort order, and can figure out how to implement your idea, then it’s a viable idea. Let’s quickly walk through the three ideas above so you can see how each would be accomplished.
<br><br>
Replace Posts on the Blog Page with a Custom Sorted List
<br><br>
The easiest way to use the custom sort order is to replace the standard list of posts on your site’s blog page with the custom sorted list of posts. To do that, all you need to do is drop the following function into your plugin:
<br><br>
[code style="php"]
<?php
/* Sort posts on the blog posts page according to the custom sort order */
function jpen_custom_post_order_sort( $query ){
if ( $query->is_main_query() && is_home() ){
$query->set( ‘orderby’, ‘meta_value’ );
$query->set( ‘meta_key’, ‘_custom_post_order’ );
$query->set( ‘order’ , ‘ASC’ );
}
}
add_action( ‘pre_get_posts’ , ‘jpen_custom_post_order_sort’ );
?>
[/code]
view rawcustom-sort-posts-on-blog-page.php hosted with ❤ by GitHub

Keep in mind that this function will only turn up posts that have been assigned a custom sort order value. Any posts that haven’t been assigned a custom sort order value will not be displayed on your blog page. In other words, if you do this, you’re going to have to assign a custom sort order value to every post that you want to see displayed.

Create a Curated List of Custom Sorted Posts

Creating a curated list of custom sorted posts will require the use of the WP_Query class. What you will need to do is create a query that includes the parameter you wish to use to curate your list, and then also add the custom sort order to the query. Here’s what that might look like:

[code style=”php”]
<?php
$args = array(
‘post_type’ => ‘post’,
‘cat’ => ’94’,
‘meta_key’ => ‘_custom_post_order’,
‘orderby’ => ‘meta_value’,
‘order’ => ‘ASC’
);

$query = new WP_query ( $args );

if ( $query->have_posts() ) {
while ($query->have_posts() ) {
$query->the_post();

/* only list posts that have a current custom post order value */
if ( !empty(get_post_meta( $post->ID, ‘_custom_post_order’, true )) ) : ?>

/* insert code for rendering posts */

<?php
endif; }
wp_reset_postdata();
} ?>
[/code]

view rawcustom-query-category-and-custom-sort.php hosted with ❤ by GitHub

This query will first look for posts that belong to the category with the ID of 94. Next, it will pick out only those posts that have been assigned a custom post order value. Finally, it will sort the posts by the custom post order value.

This query could be dropped it into a custom page template or added to a custom sidebar widget to display the queried posts.

Add Sorted Posts to the Top of the Blog Posts Lists

Another option would be to add the custom sorted posts to the top of the blog posts list, and then follow the custom sorted posts with the rest of the blog posts sorted in their usual way. Doing this is a bit complex and requires that you create two custom queries using the WP_Query class.

The first query will get the custom sorted posts and display them according to their custom order value. However, we only want the list of custom sorted posts to appear on the first page of the blog, so we’ll have to wrap the entire first query in an if statement that tests whether or not we’re on the first page of blog posts.

The second query will grab all posts and sort them in the usual way, but skip over any posts that have been assigned a custom sort order value. In addition, in order to enable pagination of the posts pulled up by the second query we’ll have to perform some trickery with the global $wp_query variable.

Here’s one way we could combine two queries to produce the desired result:

[code style=”php”]
<?php
/*
* First Loop
* Returns posts with a custom post order value
*/

// First, determine if on the first page of posts
// If on first page, run query to display posts with custom sort first

$paged = (get_query_var(‘paged’)) ? get_query_var(‘paged’) : 1;
if(1 == $paged) :

$args1 = array(
‘post_type’ => ‘post’,
‘meta_key’ => ‘_custom_post_order’,
‘orderby’ => ‘meta_value’,
‘order’ => ‘ASC’
);

$query1 = new WP_query ( $args1 );

if ( $query1->have_posts() ) :
while ($query1->have_posts() ) :
$query1->the_post();

// This if statement will skip posts that were assigned a custom sort value and then had that value removed
if ( !empty(get_post_meta( $post->ID, ‘_custom_post_order’, true )) ) :

// Display the custom sorted posts ?>
<div>
<?php the_title( sprintf( ‘<h2 class="entry-title"><a href="%s" rel="bookmark">’, esc_url( get_permalink() ) ), ‘</a></h2>’ ); ?>
<?php the_excerpt(); ?>
<a href="<?php the_permalink(); ?>">Read More</a>
</div>
<hr>
<!–insert additional code for rendering posts–><?php

endif; // End displaying custom sorted posts
endwhile; // End looping through custom sorted posts
endif; // End loop 1
wp_reset_postdata(); // Set up post data for next loop
endif; // End checking for first page

/*
* Second Loop
* Returns all posts except those in the list above
*/

$args2 = array(
‘post_type’ => ‘post’,
‘orderby’ => ‘date’,
‘order’ => ‘DESC’,
‘paged’ => $paged
);

// For pagination to work, must make temporary use of global $wp_query variable
$temp = $wp_query;
$wp_query = null;
$wp_query = new WP_query ( $args2 );

if ( $wp_query->have_posts() ) :
while ($wp_query->have_posts() ) :
$wp_query->the_post();

// Skip posts with custom sort value
if ( !empty(get_post_meta( $post->ID, ‘_custom_post_order’, true )) ) { continue; }

// Display the standard sorted posts ?>
<div>
<?php the_title( sprintf( ‘<h2 class="entry-title"><a href="%s" rel="bookmark">’, esc_url( get_permalink() ) ), ‘</a></h2>’ ); ?>
<?php the_excerpt(); ?>
<a href="<?php the_permalink(); ?>">Read More</a>
</div>
<hr>
<!–insert additional code for rendering posts–><?php

endwhile; // End looping through standard sorted posts
endif; // End loop 2
wp_reset_postdata();

// Pagination functions would go here

// Reset global $wp_query variable to its original state
$wp_query = null;
$wp_query = $temp;
?>
[/code]
view rawmultiple-queries-first-custom-sort-second-standard-sort-with-pagination.php hosted with ❤ by GitHub

You could use that set of queries to replace the standard query on your blog page in three steps:

Create a home.php file as a copy of your parent theme’s index.php.
Drop those queries in to replace the content loop.
Upload the new home.php to your child theme’s root directory.
Follow those steps and when the blog page is displayed the new home.php will be used as the page template.

Scroll to Top