# Sort Menu for Blog and Archive Pages

> Adds a "Sort by" menu above the blog and archive lists so visitors can switch between newest, oldest, A to Z and most discussed posts.

- Type: PHP
- Runs: Run everywhere
- Category: [Archives](https://wpide.com/library/category/archive/)
- Tags: archives, sorting, navigation
- Author: WPIDE Team
- Installs: 0
- Updated: 2026-10-28
- Page: https://wpide.com/library/archive-sort-menu/

## Code

```php
// Sort choices offered to visitors: key => array( label, orderby, order ).
$wpide_archive_sorts = array(
    'newest'    => array( 'Newest first', 'date', 'DESC' ),
    'oldest'    => array( 'Oldest first', 'date', 'ASC' ),
    'title'     => array( 'Title (A–Z)', 'title', 'ASC' ),
    'discussed' => array( 'Most discussed', 'comment_count', 'DESC' ),
);

$wpide_archive_sort_key = function () use ( $wpide_archive_sorts ) {
    $key = isset( $_GET['sort'] ) ? sanitize_key( wp_unslash( $_GET['sort'] ) ) : '';

    return isset( $wpide_archive_sorts[ $key ] ) ? $key : '';
};

add_action( 'pre_get_posts', function ( $query ) use ( $wpide_archive_sorts, $wpide_archive_sort_key ) {
    $key = $wpide_archive_sort_key();

    if ( '' === $key || is_admin() || ! $query->is_main_query() || ! ( $query->is_home() || $query->is_archive() ) ) {
        return;
    }

    $query->set( 'orderby', $wpide_archive_sorts[ $key ][1] );
    $query->set( 'order', $wpide_archive_sorts[ $key ][2] );
    $query->set( 'ignore_sticky_posts', true );
} );

// Sorted copies of a list are not separate pages for search engines.
add_filter( 'wp_robots', function ( $robots ) use ( $wpide_archive_sort_key ) {
    if ( '' !== $wpide_archive_sort_key() ) {
        $robots['noindex'] = true;
        $robots['follow']  = true;
    }

    return $robots;
} );

$wpide_archive_sort_form = function () use ( $wpide_archive_sorts, $wpide_archive_sort_key ) {
    $current = $wpide_archive_sort_key();
    $id      = wp_unique_id( 'wpide-sort-' );
    $action  = remove_query_arg( array( 'sort', 'paged' ), get_pagenum_link( 1, false ) );
    $html    = '<form class="wpide-archive-sort" method="get" action="' . esc_url( $action ) . '" style="display:flex;flex-wrap:wrap;gap:.5em;align-items:center;justify-content:flex-end;margin:0 0 1.5em;">';
    $html   .= '<label for="' . esc_attr( $id ) . '">Sort by</label><select id="' . esc_attr( $id ) . '" name="sort">';

    foreach ( $wpide_archive_sorts as $key => $sort ) {
        $html .= '<option value="' . esc_attr( $key ) . '"' . selected( $current ? $current : 'newest', $key, false ) . '>' . esc_html( $sort[0] ) . '</option>';
    }

    $html .= '</select>';

    // A GET form drops the query string of its action, so keep those values (plain permalinks: ?cat=3 and so on).
    parse_str( (string) wp_parse_url( $action, PHP_URL_QUERY ), $args );

    foreach ( $args as $name => $value ) {
        if ( is_string( $value ) ) {
            $html .= '<input type="hidden" name="' . esc_attr( $name ) . '" value="' . esc_attr( $value ) . '" />';
        }
    }

    return $html . '<button type="submit" class="wp-element-button button">Sort</button></form>';
};

// Classic themes: above the first post.
add_action( 'loop_start', function ( $query ) use ( $wpide_archive_sort_form ) {
    static $done = false;

    if ( $done || wp_is_block_theme() || ! $query->is_main_query() || ! ( is_home() || is_archive() ) || ! $query->have_posts() ) {
        return;
    }

    $done = true;
    echo $wpide_archive_sort_form(); // phpcs:ignore WordPress.Security.EscapeOutput -- escaped when built.
} );

// Block themes: above Query Loops that show the page's own posts.
add_filter( 'render_block_core/query', function ( $content, $block ) use ( $wpide_archive_sort_form ) {
    static $done = false;

    if ( $done || empty( $block['attrs']['query']['inherit'] ) || ! ( is_home() || is_archive() ) ) {
        return $content;
    }

    $done = true;

    return $wpide_archive_sort_form() . $content;
}, 10, 2 );
```

## Notes

Sorted pages are marked noindex so search engines keep the default order; edit the list to offer other sorts.

## How to use it

Install the free WPIDE plugin (https://wordpress.org/plugins/wpide/), find "Sort Menu for Blog and Archive Pages" in its snippet library and add it in one click; or create a new PHP snippet in WPIDE (or any code snippets plugin) and paste the code above. More snippets: https://wpide.com/library/
