Applying the customized order when using the Post Types Order plugin

Last updated on: December 1, 2025 2:31 am

Share on FacebookTweet about this on TwitterShare on Google+Share on LinkedInPrint this page
  • If you enable Auto Apply Sort in the plugin, you don’t need to change any code — the plugin will override compatible queries and apply the saved order automatically.
  • The Post Types Order plugin stores a custom sequence using WordPress’ built-in menu_order field. To retrieve posts in that order inside your templates or code, use a WP query with orderby => ‘menu_order’ (and order => ‘ASC’ or ‘DESC’).
  • Use suppress_filters => false or the main-query hook (pre_get_posts) if your custom queries ignore filters. If you only want the order applied on a specific page (home/archive/custom), use pre_get_posts conditionals.

 

Table of contents

  1. Quick example
  2. Where to put the code
  3. Apply ordering only to selected queries (recommended)
  4. Using Post Types Order with the REST API
  5. Programmatically setting a menu order
  6. Troubleshooting & caching
  7. Advanced: ignore AutoSort for specific queries
  8. Performance notes & best practices
  9. Full example snippets

 

1) Quick example

If you already have a custom loop and want the posts in the order you arranged in the plugin:

    $args = array(
                    'post_type' => 'feature', // or 'post', or your CPT
                    'orderby' => 'menu_order',
                    'order' => 'ASC',
                    'posts_per_page' => -1,
                    );
    $my_query = new WP_Query( $args );
    if ( $my_query->have_posts() ) {
        while ( $my_query->have_posts() ) {
        $my_query->the_post();
        // your template code
        }
        wp_reset_postdata();
    }

Notes:

  • orderby => ‘menu_order’ will return posts ordered by the value managed by Post Types Order.
  • Use ‘order’ => ‘DESC’ to reverse.

2) Where to put the code

  • Theme: functions.php (for hooks) or in a template file for a specific loop.
  • Plugin: create a tiny mu-plugin or functionality plugin if you need the behavior to survive theme changes.

3) Apply ordering only to selected queries (recommended)

If you want to apply the menu_order ordering only to a specific query (for example the main blog/home page), and not change all queries globally. Use pre_get_posts:

add_action( 'pre_get_posts', function( $query ) {
    // safety checks: only modify frontend main query
    if ( is_admin() || ! $query->is_main_query() ) {
        return;
    }


    // apply only on the blog home page
    if ( $query->is_home() ) {
            $query->set( 'orderby', 'menu_order' );
            $query->set( 'order', 'ASC' );
            // optionally force posts_per_page
            // $query->set( 'posts_per_page', 10 );
        }
});

Common conditional uses: is_home(), is_post_type_archive(‘feature’), is_tax(), is_singular(), etc.

If you need only one custom WP_Query instance to respect the order, set orderby => ‘menu_order’ directly on that call instead of relying on global hooks.

4) Using Post Types Order with the REST API

Problem: WP REST API’s orderby parameter does not include menu_order by default for many post types. That means a request like GET /wp-json/wp/v2/posts?orderby=menu_order may be rejected or ignored.

Solution: add menu_order to the allowed orderby values for the REST collection. Hook into rest_{$post_type}_collection_params (or rest_post_collection_params for posts) and append menu_order.

/**
* Allow orderby=menu_order in the REST API for posts.
*/
function my_rest_add_menu_order( $params ) {
    if ( isset( $params['orderby']['enum'] ) && is_array( $params['orderby']['enum'] ) ) {
        $params['orderby']['enum'][] = 'menu_order';
    }
    return $params;
}
add_filter( 'rest_post_collection_params', 'my_rest_add_menu_order' );
// for custom post type 'feature' use rest_feature_collection_params
add_filter( 'rest_feature_collection_params', 'my_rest_add_menu_order' );

After adding this you can call:

GET /wp-json/wp/v2/feature?orderby=menu_order&order=asc

(If you use Advanced Post Types Order it already provide the same behavior automatically.)

5) Programmatically set or update menu order

If you need to set or change positions by code (bulk import, migration), update each post’s menu_order using wp_update_post():

// Re-order an array of post IDs to match a desired sequence
$post_ids = array( 12, 45, 23, 9 );
$position = 0;
foreach ( $post_ids as $post_id ) {
        wp_update_post( array(
            'ID' => $post_id,
            'menu_order' => $position,
            ) );
        $position++;
    }

Important: run this in a safe context (CLI, admin request, or WP-CLI) for large lists and disable expensive actions or cache flushes while bulk updating.

6) Troubleshooting & caching

  • No visible changes after reordering?
    • Clear any page cache / object cache (Redis, Memcached). Plugins like WP Super Cache, W3 Total Cache, and host-level caches can hold old HTML.
    • If you used query_posts() (discouraged) or get_posts() with suppress_filters => true, the plugin’s filters may be bypassed; use suppress_filters => false or a proper WP_Query.
    • Check the plugin setting AutoSort / Admin Auto Apply Sort — enabling this applies the saved order automatically without code.
  • Next / Previous links not matching the new order?
    • Use previous_post_link() and next_post_link() (they will respect the plugin if the plugin option that applies next/previous is enabled). Otherwise use manual arrays of post IDs built from a menu_order query.
  • Only some queries are sorted:
    • If a theme/plugin creates a custom query and sets suppress_filters to true, the plugin won’t be able to modify the SQL. Modify that query to set suppress_filters => false or add orderby => ‘menu_order’ explicitly.

7) Advanced: ignore AutoSort for specific queries

If AutoSort is ON but you want to prevent the plugin from altering a specific query, use the filter the plugin exposes to ignore certain queries. Example filter (plugin provides pto/posts_orderby/ignore):

// ignore Post Types Order autosort for queries containing post_type 'reports'
add_filter( 'pto/posts_orderby/ignore', 'my_pto_ignore', 10, 3 );
function my_pto_ignore( $ignore, $orderBy, $query ) {
        $pt = isset( $query->query_vars['post_type'] ) ? $query->query_vars['post_type'] : '';
        if ( ( ! is_array( $pt ) && $pt === 'reports' ) || ( is_array( $pt ) && in_array( 'reports', $pt ) ) ) {
            return true; // skip plugin ordering for this query
        }
        return $ignore;
    }

If you use Advanced Post Types Order, you can use the visual conditionals.

8) Performance notes & best practices

  • Prefer posts_per_page limited rather than -1 if the front-end does not need every post. Fetching thousands of posts at once can be slow and memory intensive.
  • For very large lists, store the ordered list of IDs and page the front-end requests against that list (or a transient/cache) instead of running heavy SQL every request.
  • Avoid modifying menu_order for frequently updated posts programmatically on every request; update only on reorder events.

9) Full example snippets

Example A — WP_Query within a template

$loop = new WP_Query( array(
    'post_type' => 'portfolio',
    'orderby' => 'menu_order title', // secondary sort by title
    'order' => 'ASC',
    'posts_per_page' => 12,
    ) );
    
if ( $loop->have_posts() ) :
    while ( $loop->have_posts() ) : $loop->the_post();
        get_template_part( 'template-parts/content', get_post_type() );
    endwhile;
    wp_reset_postdata();
endif;

Example B — REST API orderby allow + default order for a CPT

// allow menu_order as orderby
add_filter( 'rest_feature_collection_params', function( $params ) {
        $params['orderby']['enum'][] = 'menu_order';
        return $params;
    } );


// optional: force default order for REST collection (filter returns args before query)
add_filter( 'rest_feature_query', function( $args, $request ) {
    if ( empty( $request['orderby'] ) ) {
            $args['orderby'] = 'menu_order';
            $args['order'] = 'ASC';
        }
    return $args;
    }, 10, 2 );

FAQ

Q — I reordered posts but page still shows the old order.
A — Flush caches and make sure your template query is not overriding the order or suppressing filters.

Q — Does this work with pages?
A — Yes. WordPress pages use menu_order by default; Post Types Order extends this concept to posts and custom post types.

Q — Will this survive theme switches?
A — Yes, because the order is stored in the DB (menu_order). Reordering is independent of the theme. If you add code to functions.php, prefer placing it in a small functionality plugin if you will swap themes.

For advanced queries and sorts see the Advanced Post Types Order and it’s Documentation.