Post titles have numbers from 1 to 50 and i want to sort them in order, it's not possible to use 2 digits, the sequence goes like: 1,2,3,4,5...50.

So i use:

$query->set('orderby', array( 'title' => 'ASC'));

But that sorts them like this: 1,10,11,12....19,2,20,21 That isn't good for humans.

Is there a way to make the orderby do 1,2,3,4,5...9,10,11,12....50?

  • 2
    The query seems to be treating the titles as strings, not integers, which is to be expected. You should probably sort by meta field or possibly by menu_order, if you need a numeric sorting. – Michael Sep 25 '18 at 21:32
  • What does menu_order do exactly? It's misleading cos these aren't menus, usually a codex or wp site explains all but couldn't find details for this. – Michael Rogers Sep 26 '18 at 8:58
  • As far as I know, menu_order is used to numerically sort post (types). A few custom post order plugins make use of it. Since it's a default field from the _posts table, it's always present in your post object and doesn't require an additional meta query. – Michael Sep 26 '18 at 11:20
  • This could solve your problem: wordpress.stackexchange.com/questions/91866/…. Once you add the support for it, you get an input field Order which let's you add your digit, so you can actually give meaningful titles to your posts. – Michael Sep 26 '18 at 11:26

Alternatively one could apply the general idea from @majick here and adjust the slug with some left padding.


Here's an example with left padding of length 5:

Title   Slug
1       nr-00001
2       nr-00002
10      nr-00010
11      nr-00011
12      nr-00012

Note that if we used pure numeric like 00001 then it would be saved as 00001-2, to avoid collisions with default year routes, so that's why we prefixed it with some string, like nr-.

Then one could order by slug, i.e. the post_name column:

$query->set( 'orderby', [ 'name' => 'ASC' ] );

This doesn't need a join on the meta table, as if a custom field was used as an order field.

The user interface is already available to change the slug:

slug with lpad

but this method becomes a problem if e.g. the number exceeds the padding length, if the user changes it and it might also be harder to maintain for large number of posts.

The posts_orderby filter

For a more dynamic way, one could also use the posts_orderby filter and apply the various ideas from here, e.g. the LPAD MySQL function.

Sorting in PHP

Taking the sorting to PHP, one could consider usort() on the posts array, with the strnatcmp() on the post_title attribute, for natural (human) string comparison. This would be more suitable for few posts.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.