• I am attempting to use projects as an additional form of simple post to create a glossary. I’m trying not to mix the Glossary posts with normal Blog Posts.

    This all works fine, except I can’t seem to influence the ORDER of my project posts on the Glossary page when adding code to my functions.php. I have tried various permutations of the following:

    //SORT PROJECTS BY TITLE
    
    add_action( 'pre_get_posts', 'sort_by_title'); 
       
    function sort_by_title($query){
    
    //target the glossary page
     if (get_the_ID() !=1523) return;
    
            //$query-> set('post_type' ,'project');
            $query->set( 'orderby', 'title' );
            $query->set( 'order', 'ASC' );
    };

    The impresssion I have is that posts, pages and projects are all generic types of ‘post’, but I must be missing something.

    I will be very grateful for any help.

    Thank you
    David

    The page I need help with: [log in to see the link]

Viewing 6 replies - 1 through 6 (of 6 total)
  • Try changing this bit:

    
    //target the glossary page
     if (get_the_ID() !=1523) return;
    

    To this:

    
    // target the glossary page
    if ( ! $query->is_main_query() || 1523 !== $query->get_queried_object_id() ) {
    	return;
    }
    

    I’m kind of assuming this is the main query for the page. If it’s a secondary query, that might not work.

    Moderator bcworkz

    (@bcworkz)

    Getting the ID is indeed the issue, but depending on the request, it may not yet be available in “pre_get_posts” because the query is yet to be made. If “project” is the post type, why not let the default example.com/project/ archive query work for you? Then your callback can check for main query and if the “post_type” query var is “project”. If so, then you can alter the ordering.

    If you desire some unique template layout for this glossary, create a custom template named archive-project.php.

    Thread Starter davideno

    (@davideno)

    Justin

    I tried your suggested addition to the code and it is indeed the main query I need to change. I added a break point before

    `$query->set( ‘orderby’, ‘title’ );
    $query->set( ‘order’, ‘ASC’ );`

    and it is reaching this point.

    I dumped $query and ‘orderby’ is being set as ‘title’, but not having any effect.

    bcworkz

    I guess the above probably proves the point you are making, but I’m a little out of my depth in following your suggestion.

    I am using the theme ‘Extra’ (Divi) and have set up the main Glossary page how I want it using their Blog module selecting ‘projects’ as the Post Type. I’m not sure if this has a bearing on what you are suggesting? Everything is perfect apart from the Order.

    You helped me with another ORDER problem on my main page recently where a filter was the answer:

    add_filter('posts_orderby', 'seasonal_posts_orderby');
    
    function seasonal_posts_orderby($sortorder) {
       
        $sortorder = "CASE WHEN DAYOFYEAR(post_date) < DAYOFYEAR(NOW())-18 THEN 1 ELSE 0 END , DAYOFYEAR(post_date) ";
        return $sortorder;   
    }

    Should I try to adapt this? I had a quick try but it didn’t seem to work.

    Thank you both for your help

    Thread Starter davideno

    (@davideno)

    Further to above I now have this working. The complication is there are two similar functions which need to be targeting separate querys.

    //ORDER BLOG POSTS BY SPECIAL SORT

    add_filter(‘posts_orderby’, ‘seasonal_posts_orderby’);

    function seasonal_posts_orderby($sortorder) {
    //target all pages apart from glossary page main query
    $sortorder = “CASE WHEN DAYOFYEAR(post_date) < DAYOFYEAR(NOW())-18 THEN 1 ELSE 0 END , DAYOFYEAR(post_date) “;
    return $sortorder;

    }

    //ORDER PROJECTS BY TITLE

    add_filter(‘posts_orderby’, ‘glossary_orderby’);

    function glossary_orderby($sortorder) {
    // target the glossary page main query
    if (get_the_ID() !=1523) return;

    $sortorder = “post_title”;
    return $sortorder;
    }

    It’s fine if the first filter targets all queries, apart from the glossary main query. The second function must

      only

    target the glossary main query. I guess the could both be combined.

    Thread Starter davideno

    (@davideno)

    Sleep has clarified my thoughts. For each WordPress page a number of database queries are generated to populate main content, widgets, etc., etc. The key to my particular problem is to know what queries are being generated and how to identify and address them individually. Then I will be able to target my functions, which seem to work now, to particular circumstances.

    Thank you for your help and patience.

    Moderator bcworkz

    (@bcworkz)

    You’ve encountered the common problem of determining which queries to leave alone and which to modify. All the various is_*() methods can help but often don’t go far enough. Sometimes you can distinguish the right query from specific query var values or a combination thereof.

    Another useful technique is “just in time coding”. (not sure if that’s really a thing) Essentially, add the action callback just before it’s needed in some context that’s unique to the situation you are targeting. For example, if we’re targeting a secondary query made from a specific template, add the action callback right on the template just before WP_Query is instantiated or get_posts() is called. The callback can then remove itself from the call stack when it’s done so it will not influence any other query. This way, it’s rare that the callback needs to do any additional checking.

    It dawned on me that I may have already described these concepts to you before. Sorry for the redundancy if so. It might help others landing here from search, so it’s not entirely superfluous.

Viewing 6 replies - 1 through 6 (of 6 total)
  • The topic ‘Ordering projects by title’ is closed to new replies.