Q: pre_get_posts : 'post__not_in' doesn't work with global variable I'm trying to set a post__not_in which use a global $popular variable, defined in the index.php.
-index.php-
$popular[] = 1 //post id=1
$popular[] = 2 //post id=2
$popular[] = 3 //post id=3

-functions.php-
function modify_query_exclude_popular($query) {
    if ($query->is_main_query() && $query->is_home()){
        global $popular;
        $query->set('post__not_in', $popular);
    }
}
add_action('pre_get_posts', 'modify_query_exclude_popular' );

I just can't make it work, the loop is working, but popular post_ids aren't exluded. I tried everything: define a constant, using "create_function" etc...
PS: If I set $popular array inside the function modify_query_exclude_popular() it does work, but I absolutely need to set the array in index.php (the $popular use post_id of another loop).

A: You have to declare $popular to be global before you use it. Based on the code you've posted you haven't done that.
global $popular;
$popular[] = 1 //post id=1
$popular[] = 2 //post id=2
$popular[] = 3 //post id=3

However, if you mean the index.php in the theme, that file is not always used. You may be defining the variable in a file that does not load when you need it to. It is hard to tell whether this is the case due to the limited code you posted.
pre_get_posts is going to run before any of the theme files anyway, except, if functions.php (or any files included from there). You can echo values out from that filter and from header.php to prove that to yourself.
Also, there may be a better way to do this than to declare a global variable. Again, due to the limited code it is hard to say.
Overall, it sounds like you need to rethink how you are going to accomplish this. A much better description of what you are trying to accomplish would help.
Reference
http://php.net/manual/en/language.variables.scope.php

A: INDEX.php file is refined far after the pre_get_posts hook... so, you should define the $popular variable before that hook.
