0

Question title completely reflects my issue. I'm build non-profit collection of poems, and want sort them alphabetical. Native Wordpress sorting in this case is unsuitable. Must sort poems by first letter of content, not title.

Excuse me for bad English, please. And thanks everyone who can help me.

  • This issue has been handled before, I think I did this once. Feel free to make use of the site search to search for a possible solution :-) – Pieter Goosen Mar 20 '15 at 18:43
0

The very simplest way to do it is to add a filter (in your theme's "functions.php") to sort by the content:

function wpse181797_posts_orderby( $orderby, $query ) {
    if ( ! is_admin() && $query->get( 'post_type' ) == 'post' /* && some other conditions probably... */ ) {
        global $wpdb;
        $pc = 'LTRIM(' . $wpdb->posts . '.post_content)';
        $orderby = 'UPPER(' . $pc . ') ASC';
    }
    return $orderby;
}
add_filter( 'posts_orderby', 'wpse181797_posts_orderby', 10, 2 );

However this won't deal with any initial punctuation or HTML markup or verse numbering/titling/epigraphs or whatever, so you're probably better off using a secondary field as well for those cases, eg post_excerpt if it's available, where you put the first line as you want it to sort in exceptionable cases, so the filter becomes:

function wpse181797_posts_orderby_excerpt( $orderby, $query ) {
    if ( ! is_admin() && $query->get( 'post_type' ) == 'post' /* && some other conditions probably... */ ) {
        global $wpdb;
        $pc = 'LTRIM(CONCAT(' . $wpdb->posts . '.post_excerpt, ' . $wpdb->posts . '.post_content))';
        $orderby = 'UPPER(' . $pc . ') ASC';
    }
    return $orderby;
}
add_filter( 'posts_orderby', 'wpse181797_posts_orderby_excerpt', 10, 2 );

If you're using the post_excerpt for other purposes you could use a custom field instead, eg 'first_line_sort', and then filter on posts_clauses (to add a join):

function wpse181797_posts_clauses( $pieces, $query ) {
    if ( ! is_admin() && $query->get( 'post_type' ) == 'post' /* && some other conditions probably... */ ) {
        global $wpdb;
        $pieces[ 'join' ] .= $wpdb->prepare(
            ' LEFT JOIN ' . $wpdb->postmeta . ' wpse_pm ON wpse_pm.post_id = ' . $wpdb->posts . '.ID'
            . ' AND wpse_pm.meta_key = %s'
            , 'first_line_sort'
        );
        $pieces[ 'orderby' ] = 'UPPER(LTRIM(IFNULL(wpse_pm.meta_value, ' . $wpdb->posts . '.post_content))) ASC';
    }
    return $pieces;
}
add_filter( 'posts_clauses', 'wpse181797_posts_clauses', 10, 2 );
| 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.