[wp-trac] [WordPress Trac] #64467: Grid view displays attachments in the wrong order when an order query var is present but not normalized (was: Media Library Grid view displays attachments in the wrong order when an order query var is present but not normalized (e.g. `order=desc` or `order=pizza`). Not a `WP_Query` / database issue: the server returns correctly ordered results; the UI reverses them client‑side in JavaScript.)
WordPress Trac
noreply at wordpress.org
Thu Jan 1 16:30:34 UTC 2026
#64467: Grid view displays attachments in the wrong order when an order query var
is present but not normalized
-----------------------------+-----------------------------------------
Reporter: trivedikavit | Owner: (none)
Type: defect (bug) | Status: new
Priority: normal | Milestone: Awaiting Review
Component: Media | Version:
Severity: minor | Resolution:
Keywords: has-screenshots | Focuses: javascript, administration
-----------------------------+-----------------------------------------
Changes (by sabernhardt):
* keywords: has-patch needs-testing has-test-info has-screenshots
javascript => has-screenshots
* focuses: javascript => javascript, administration
Old description:
> = Are you using either the latest version of WordPress, or the latest
> development version? =
>
> Yes. Reproduced on:
>
> * A clean ''local'' WordPress install running WordPress '''6.9'''
> * Multiple production sites, showing the same behavior. The local
> reproduction confirms this is core behavior and not environment-specific.
>
> === Direct URL reproduction (most deterministic) ===
>
> Visit: `/wp-admin/upload.php?mode=grid&orderby=date&order=desc`
>
> Observe the ordering displayed in the grid.
> Control cases:
>
> * Works as expected:
> * `/wp-admin/upload.php?mode=grid&orderby=date&order=DESC`
> * `/wp-admin/upload.php?mode=grid&orderby=date`
> * Also triggers incorrect ordering:
> * `/wp-admin/upload.php?mode=grid&orderby=date&order=pizza`
>
> === Screenshots ===
>
> ** Incorrect Order: `order=desc` **
> [[Image(https://iili.io/fhBAuFs.png)]]
>
> ** Correct Order: `order=DESC` **
> [[Image(https://iili.io/fhBAAcG.png)]]
>
> === Common User Path (List Mode with Filters => Grid Mode) ===
>
> * Visit List mode with sorting: `/wp-
> admin/upload.php?mode=list&orderby=date&order=desc`
> * Click the ''Grid view'' toggle (the generated link preserves
> orderby/order).
> * Grid view renders the first batch of attachments in the wrong order.
>
> = Does the problem occur even when you deactivate all plugins and use the
> default theme? =
>
> Yes. Reproduced on a clean local install with:
>
> * Default theme (twentytwentyfive)
> * No plugins
>
> = What steps should be taken to consistently reproduce the problem? =
> ''Precondition:'' Media Library contains a few images where this sorting
> issue would be apparent.
>
> = What is the expected output or result? What did you see instead? =
>
> === Expected ===
>
> For: `mode=grid&orderby=date&order=desc` The grid should display
> attachments newest-first (DESC), consistent with server-side behavior and
> the AJAX response.
>
> === Actual ===
>
> With `order=desc` (lowercase) or invalid values such as `order=pizza`:
>
> The server-side query and the AJAX response contain attachments in the
> correct order (DESC by date).
>
> The Grid UI renders them reversed (appears ASC / oldest-first).
>
> This demonstrates the defect is ''not'' in `WP_Query` and not in SQL
> ordering; it is a ''client-side UI sorting issue'' in the Media Library
> grid JavaScript.
>
> = Please provide any additional information that you think we'd find
> useful. =
>
> * Tested primarily in Chrome on macOS (but this is browser-independent)
> * Grid view uses AJAX via `wp_ajax_query_attachments()` (admin-ajax).
> When reproducing, the network response data array arrives in the correct
> (DESC) order even when the URL contains lowercase/invalid order values.
> * Root cause appears to be a normalization mismatch: ** PHP / `WP_Query`
> normalizes order to uppercase (ASC/DESC) and defaults invalid values to
> DESC. ** Media grid JS uses a case-sensitive 'DESC' `===` order check;
> lowercase/invalid values fall through to the ascending branch and reverse
> the display order.
> * Relevant core code (6.9):
> * `wp.media.model.Query.prototype.filters.order`:
> * https://github.com/WordPress/WordPress/blob/6.9/wp-includes/js/media-
> models.js#L34-L76
> * `wp.media.model.Attachments.comparator`:
> * https://github.com/WordPress/WordPress/blob/6.9/wp-includes/js/media-
> models.js#L1092-L1112
>
> = Patch =
>
> Here's the patch:
> {{{
> --- a/wp-includes/js/media-models.js
> +++ b/wp-includes/js/media-models.js
> @@ -43,7 +43,7 @@ Query = Attachments.extend(/** @lends
> wp.media.model.Query.prototype */{
>
> this.filters.order = function( attachment ) {
> var orderby = this.props.get('orderby'),
> - order = this.props.get('order');
> + order = ( this.props.get('order') ||
> 'DESC' ).toUpperCase();
>
> if ( ! this.comparator ) {
> return true;
> @@ -1091,7 +1091,7 @@ var Attachments = Backbone.Collection.extend(/**
> @lends wp.media.model.Attachmen
> */
> comparator: function( a, b, options ) {
> var key = this.props.get('orderby'),
> - order = this.props.get('order') || 'DESC',
> + order = ( this.props.get('order') || 'DESC'
> ).toUpperCase(),
> ac = a.cid,
> bc = b.cid;
>
> @@ -1108,7 +1108,7 @@ var Attachments = Backbone.Collection.extend(/**
> @lends wp.media.model.Attachmen
> ac = bc = null;
> }
>
> - return ( 'DESC' === order ) ? wp.media.compare( a, b, ac,
> bc ) : wp.media.compare( b, a, bc, ac );
> + return ( 'ASC' === order ) ? wp.media.compare( b, a, bc,
> ac ) : wp.media.compare( a, b, ac, bc );
> },
> /** @namespace wp.media.model.Attachments.filters */
> filters: {
> }}}
>
> == What the patch changes ==
> The patch makes two small but important changes in wp-includes/js/media-
> models.js:
>
> === 1) Normalize order to uppercase in the media models ===
> It changes:
> {{{
> order = this.props.get('order');
> }}}
> and
> {{{
> order = this.props.get('order') || 'DESC';
> }}}
> to:
> {{{
> order = ( this.props.get('order') || 'DESC' ).toUpperCase();
> }}}
>
> So:
>
> 'desc' becomes 'DESC'
> 'asc' becomes 'ASC'
> undefined becomes 'DESC'
> 'pizza' becomes 'PIZZA' (still invalid, but now handled consistently)
> This ensures the subsequent comparisons behave deterministically.
>
> === 2) Change the comparator to treat only explicit ASC as ascending
> (default everything else to DESC) ===
> It changes the comparator decision from:
> {{{
> return ( 'DESC' === order ) ? DESC_logic : ASC_logic;
> }}}
> to:
> {{{
> return ( 'ASC' === order ) ? ASC_logic : DESC_logic;
> }}}
>
> Effect:
>
> If order is exactly 'ASC', the Grid sorts ascending.
> For 'DESC' (and for any unexpected/invalid value), the Grid sorts
> descending.
> That default-to-DESC behavior matches how WP_Query behaves when order is
> missing or invalid, which prevents the UI from "flipping" the already-
> correct server ordering.
>
> == Testing Instructions ==
>
> Since this patch modifies the unminified JavaScript file `wp-includes/js
> /media-models.js`, to test it properly:
>
> 1. Set `define( 'SCRIPT_DEBUG', true );` in your `wp-config.php` to
> ensure WordPress loads unminified JavaScript files instead of the
> minified versions (otherwise you need to rebuild or patch the minified
> file too.)
> 2. Apply the patch to `wp-includes/js/media-models.js`.
> 3. Clear your browser cache or use an incognito/private browsing window
> to avoid cached scripts.
> 4. Follow the reproduction steps above to verify the fix:
> * Visit `/wp-admin/upload.php?mode=grid&orderby=date&order=desc` and
> confirm attachments display newest-first.
> * Test control cases: `order=DESC`, `order=asc`, and invalid values
> like `order=pizza` should all behave correctly (defaulting to DESC where
> appropriate).
>
> == Net Result ==
>
> * Grid view displays attachments in the same order as the AJAX response.
> * `order=desc` and `order=DESC` behave identically.
> * Invalid order values no longer cause the Grid UI to reverse the display
> order; they fall back to descending behavior instead.
New description:
Media Library Grid view displays attachments in the wrong order when an
order query var is present but not normalized (e.g. `order=desc` or
`order=pizza`). Not a `WP_Query` / database issue: the server returns
correctly ordered results; the UI reverses them client‑side in JavaScript.
==== Are you using either the latest version of WordPress, or the latest
development version? ====
Yes. Reproduced on:
* A clean ''local'' WordPress install running WordPress '''6.9'''
* Multiple production sites, showing the same behavior. The local
reproduction confirms this is core behavior and not environment-specific.
===== Direct URL reproduction (most deterministic) =====
Visit: `/wp-admin/upload.php?mode=grid&orderby=date&order=desc`
Observe the ordering displayed in the grid.
Control cases:
* Works as expected:
* `/wp-admin/upload.php?mode=grid&orderby=date&order=DESC`
* `/wp-admin/upload.php?mode=grid&orderby=date`
* Also triggers incorrect ordering:
* `/wp-admin/upload.php?mode=grid&orderby=date&order=pizza`
==== Screenshots ====
** Incorrect Order: `order=desc` **
[[Image(https://core.trac.wordpress.org/raw-attachment/ticket/64467
/incorrect-order.png, alt="Incorrect Order in Grid View with order=desc
(lowercase)", title="")]]
** Correct Order: `order=DESC` **
[[Image(https://core.trac.wordpress.org/raw-attachment/ticket/64467
/correct-order.png, alt="Correct Order in Grid View with order=DESC
(uppercase)", title="")]]
==== Common User Path (List Mode with Filters => Grid Mode) ====
* Visit List mode with sorting: `/wp-
admin/upload.php?mode=list&orderby=date&order=desc`
* Click the ''Grid view'' toggle (the generated link preserves
orderby/order).
* Grid view renders the first batch of attachments in the wrong order.
==== Does the problem occur even when you deactivate all plugins and use
the default theme? ====
Yes. Reproduced on a clean local install with:
* Default theme (twentytwentyfive)
* No plugins
==== What steps should be taken to consistently reproduce the problem?
====
''Precondition:'' Media Library contains a few images where this sorting
issue would be apparent.
==== What is the expected output or result? What did you see instead? ====
===== Expected =====
For: `mode=grid&orderby=date&order=desc` The grid should display
attachments newest-first (DESC), consistent with server-side behavior and
the AJAX response.
===== Actual =====
With `order=desc` (lowercase) or invalid values such as `order=pizza`:
The server-side query and the AJAX response contain attachments in the
correct order (DESC by date).
The Grid UI renders them reversed (appears ASC / oldest-first).
This demonstrates the defect is ''not'' in `WP_Query` and not in SQL
ordering; it is a ''client-side UI sorting issue'' in the Media Library
grid JavaScript.
==== Please provide any additional information that you think we'd find
useful. ====
* Tested primarily in Chrome on macOS (but this is browser-independent)
* Grid view uses AJAX via `wp_ajax_query_attachments()` (admin-ajax). When
reproducing, the network response data array arrives in the correct (DESC)
order even when the URL contains lowercase/invalid order values.
* Root cause appears to be a normalization mismatch: ** PHP / `WP_Query`
normalizes order to uppercase (ASC/DESC) and defaults invalid values to
DESC. ** Media grid JS uses a case-sensitive 'DESC' `===` order check;
lowercase/invalid values fall through to the ascending branch and reverse
the display order.
* Relevant core code (6.9):
* `wp.media.model.Query.prototype.filters.order`: \\
https://github.com/WordPress/WordPress/blob/6.9/wp-includes/js/media-
models.js#L34-L76
* `wp.media.model.Attachments.comparator`: \\
https://github.com/WordPress/WordPress/blob/6.9/wp-includes/js/media-
models.js#L1092-L1112
=== Patch ===
Here's the patch:
{{{
--- a/wp-includes/js/media-models.js
+++ b/wp-includes/js/media-models.js
@@ -43,7 +43,7 @@ Query = Attachments.extend(/** @lends
wp.media.model.Query.prototype */{
this.filters.order = function( attachment ) {
var orderby = this.props.get('orderby'),
- order = this.props.get('order');
+ order = ( this.props.get('order') || 'DESC'
).toUpperCase();
if ( ! this.comparator ) {
return true;
@@ -1091,7 +1091,7 @@ var Attachments = Backbone.Collection.extend(/**
@lends wp.media.model.Attachmen
*/
comparator: function( a, b, options ) {
var key = this.props.get('orderby'),
- order = this.props.get('order') || 'DESC',
+ order = ( this.props.get('order') || 'DESC'
).toUpperCase(),
ac = a.cid,
bc = b.cid;
@@ -1108,7 +1108,7 @@ var Attachments = Backbone.Collection.extend(/**
@lends wp.media.model.Attachmen
ac = bc = null;
}
- return ( 'DESC' === order ) ? wp.media.compare( a, b, ac,
bc ) : wp.media.compare( b, a, bc, ac );
+ return ( 'ASC' === order ) ? wp.media.compare( b, a, bc, ac
) : wp.media.compare( a, b, ac, bc );
},
/** @namespace wp.media.model.Attachments.filters */
filters: {
}}}
==== What the patch changes ====
The patch makes two small but important changes in `wp-includes/js/media-
models.js`:
===== 1) Normalize order to uppercase in the media models =====
It changes:
{{{
order = this.props.get('order');
}}}
and
{{{
order = this.props.get('order') || 'DESC';
}}}
to:
{{{
order = ( this.props.get('order') || 'DESC' ).toUpperCase();
}}}
So:
- 'desc' becomes 'DESC'
- 'asc' becomes 'ASC'
- undefined becomes 'DESC'
- 'pizza' becomes 'PIZZA' (still invalid, but now handled consistently)
- This ensures the subsequent comparisons behave deterministically.
===== 2) Change the comparator to treat only explicit ASC as ascending
(default everything else to DESC) =====
It changes the comparator decision from:
{{{
return ( 'DESC' === order ) ? DESC_logic : ASC_logic;
}}}
to:
{{{
return ( 'ASC' === order ) ? ASC_logic : DESC_logic;
}}}
Effect:
- If order is exactly 'ASC', the Grid sorts ascending.
- For 'DESC' (and for any unexpected/invalid value), the Grid sorts
descending.
- That default-to-DESC behavior matches how `WP_Query` behaves when order
is missing or invalid, which prevents the UI from "flipping" the already-
correct server ordering.
==== Testing Instructions ====
Since this patch modifies the unminified JavaScript file `wp-includes/js
/media-models.js`, to test it properly:
1. Set `define( 'SCRIPT_DEBUG', true );` in your `wp-config.php` to ensure
WordPress loads unminified JavaScript files instead of the minified
versions (otherwise you need to rebuild or patch the minified file too.)
2. Apply the patch to `wp-includes/js/media-models.js`.
3. Clear your browser cache or use an incognito/private browsing window to
avoid cached scripts.
4. Follow the reproduction steps above to verify the fix:
* Visit `/wp-admin/upload.php?mode=grid&orderby=date&order=desc` and
confirm attachments display newest-first.
* Test control cases: `order=DESC`, `order=asc`, and invalid values
like `order=pizza` should all behave correctly (defaulting to DESC where
appropriate).
==== Net Result ====
* Grid view displays attachments in the same order as the AJAX response.
* `order=desc` and `order=DESC` behave identically.
* Invalid order values no longer cause the Grid UI to reverse the display
order; they fall back to descending behavior instead.
--
Comment:
Hi and welcome to WordPress Core Trac!
In trunk, the script involves both
[https://core.trac.wordpress.org/browser/trunk/src/js/media/models/query.js?rev=51632&marks=40#L40
query.js] and
[https://core.trac.wordpress.org/browser/trunk/src/js/media/models/attachments.js?rev=51191&marks=497,514#L497
attachments.js].
There is also a
[https://core.trac.wordpress.org/browser/trunk/src/js/media/models/query.js?rev=51632&marks=40#L40
'menuOrder' option] that relies on `ASC` uppercase.
--
Ticket URL: <https://core.trac.wordpress.org/ticket/64467#comment:1>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform
More information about the wp-trac
mailing list