Trouble passing arguments to WordPress pre_get_posts

I need your help! I am having trouble passing arguments to a function using pre_get_posts.

Purpose of passing arguments:
I have a custom taxonony-$taxonomy.php page which I use to list posts related to a particular category within the specified taxonomy. On this page I also retrieve & setup tags assigned to each post from a custom non hierarchical taxonomy and list them as links on the side. I have another taxonomy-$taxonomy.php (for the custom non hierarchical taxonomy mentioned above) setup so when a user chooses a link he/she clicks on a tag it will direct them to this taxonomy page. This is all working fine.

Read More

However, here’s where I’m having issues. The posts listed on the non hierarchical taxonomy page are those associate to a particular tag but from multiple categories. What I’m trying to achieve is to list posts associates to the tag chosen and from the category previously being viewed. So for example: Lets say the user clicks on category ‘Accounting’, then chooses the tag ‘Creative Services’. All posts listed should not only be associated with ‘Creative Services’ must also be assigned to only the ‘Accounting’ category. This is where I’ve been trying to pass arguments to the function used by pre_get_posts.

How have I tried passing arguments?:

1- Setup globals: This way no arguments have to be past via the function being invoked. It did not work because the timing is off. The globals are not yet set when the action is called. Below is my code with example post_type and taxonomy. Notice $category is the global variable which hold the category within that taxonomy.

// Alter main query on doc_tag taxonomy templates
function only_query_doc_tag_posts( $query ) {
    global $category;
    if ( is_tax(array('doc_tag')) && !is_admin() ) {
        if($query->is_main_query()) {
            $query->set( 'post_type', 'post_type' );
            $query->set( 'taxonomy', 'taxonomy_array' );
            $query->set( 'taxonomy_name', $category ); //global
        }
    }
}
add_action( 'pre_get_posts', 'only_query_doc_tag_posts' );

Results:
When I view the main query it shows all the changes except the one using the global. If I manually insert the value into the function, instead of using the a global variable then it works. However, I’d like to be able to change this on the fly. Just so you’re aware I do get the posts related to the tag but not those only associated to the category indicated by the global (when using the global).

2- do_action:

// Alter main query on doc_tag taxonomy templates
function only_query_doc_tag_posts( $query,
                                   $post_types,  //array
                                   $taxonomies,  //array
                                   $category     //global var
                                   ) {
    global $category;
    if ( is_tax(array('doc_tag')) && !is_admin() ) {
        if($query->is_main_query()) {
            $query->set( 'post_type', $post_types );
            $query->set( 'taxonomy',  $taxonomies );
            $query->set( 'taxonomy_name', $category ); //global
        }
    }
}
add_action( 'pre_get_posts', 'only_query_doc_tag_posts', 10, 4 );

Then on the custom non hierarchical taxonomy page template I add the following:

do_action( 'pre_get_post', $post_types, $taxonomies, $category );

I have a feeling my second approach is not technically but I could be wrong, which is why I’m posting it here in hopes that someone can provide some direction. If I missed information that would help you help me please let me know.

Thank you in advance for helping me with this.

FYI: I’ve read these posts but did not get find a solution. Maybe it’s there and I missed it? Please let me know.

Related posts

Leave a Reply

1 comment

  1. I think I understand what you try to do.
    Long in short – no, you can not do (do_action) by yourself, it is called by wp query parts.

    If you try to pass arguments, you need look into [$query->query_vars].
    I think a proper solution, for you need, is write a proper url rewrite rules, it can auto pick the taxonomy, and put it into url list, then values can auto show in [$query->query_vars] .
    Which is [add_filter(‘rewrite_rules_array’, ‘set_url_rule’);]

    You may also need install plugin [rewrite-rules-inspector] to help you inspect the rewrite status.

    Anyway, it could take you an afternoon to find the logical behind it, but then, it all makes sense.

    If you just looking for a quick solution, you can inject some code into query_vars, you just need to :

    add_filter('query_vars', 'insert_query_vars');
    function insert_query_vars( $vars ){
        array_push($vars, 'c_type');
        array_push($vars, 'c_tax');
        array_push($vars, 'c_term');
        return $vars;
    }