I was recently answering a question on WordPress StackExchange and the question of appropriate hooks came up when suggesting where to hook on your styles or scripts when you’re needing to check conditional tags, those such is_page(), is_category, and so on..
http://wordpress.stackexchange.com/questions/8260/loading-scripts-on-specific-pages/
It was my impression, that both wp_print_scripts and wp_print_styles were front facing page actions that occur at a time equivalent to their admin counterparts and a query was raised by Rarst whether this is an appropriate place for enqueues..
The codex also suggests init as appropriate for enqueues.
Warning: You can only use conditional query tags on or after the init action hook in WordPress. For themes, this means the conditional tag will never work properly if you are using it in the body of functions.php, i.e. outside of a function.
I decided to write a PHP class as an example to get the results of hooking onto different actions because i was sure init was too early.
class conditional_tags_check { private $results = array(); public function __construct() { add_action( 'wp_head', array( $this, 'conditional_check' ) ); add_action( 'template_redirect', array( $this, 'conditional_check' ) ); add_action( 'wp_enqueue_scripts', array( $this, 'conditional_check' ) ); add_action( 'wp_print_styles', array( $this, 'conditional_check' ) ); add_action( 'wp', array( $this, 'conditional_check' ) ); add_action( 'init', array( $this, 'conditional_check' ) ); add_action( 'wp_print_scripts', array( $this, 'conditional_check' ) ); add_action( 'wp_footer', array( $this, 'output' ) ); } public function conditional_check() { $action = debug_backtrace(); $action = $action[2]['args'][0]; $this->results[] = "$action :" . ( is_page() ? 'yes' : 'no' ); } public function output() { echo implode( "\n<br />", $this->results ); } } $conditional_tags_check = new conditional_tags_check;
I’ve purposely put the add action calls into a random order so you can see the natural order of the actions appear in the results(naturally the action occuring first will be the first result, and so on..).
The results for me came out as.
init :no wp :yes template_redirect :yes wp_enqueue_scripts :yes wp_print_styles :yes wp_print_scripts :yes wp_head :yes
Init is the only action that fails the test, and shows “no”, where as all others appear to run late enough to determine the request is for a page(i was of course viewing a page). The above conditional tag could be replaced by any other and replicated to show that under each condition init fires too early to determine the kind of request(page, category, tag, single, etc..).
For reference the actions shown above fire in this order.
- init
- wp
- template_redirect
- wp_print_styles
- wp_print_scripts
- wp_enqueue_scripts
- wp_head
Can anybody see any problems with the test code or disagree? Drop me a comment..
Yep, seems to be right. Init fires when core finished loading, but query variables are only started to be processed later in wp() call. Codex sucks so badly at times. π¦
Offtopic note on your test snippet – you can get current hook more easily with current_filter()
I’ll factor current_filter into the code, should of been an obvious choice really(never had a need for it – until now at least).
Codex is what it is, you’re welcome to update a page or two(i find it boring as hell writing docs myself), i can’t blame others for not being interested either… π
Rarst, how were you selectively enqueuing before? You mentioned approaching it in a more roundabout way… (i’m curious).
Wow, I just got a serious case of deja vu reading this post – even down to the comment by Rarst! Please see this post for the reason why.
I always use the
wp_prints scripts
andwp_print_styles
hooks to load javascript and stylesheets. I have not had an issue thus far. I always try to hook as late as possible without being too late and these hooks appear to be the appropriate place(s). I have read thatwp_enqueue_scripts
was a safe place and have seen many themes (by respected developers) using thetemplate_redirect
. Which one is correct? Probably all of them, they all seem to get the job done IMO.I’ve never had a problem using
wp_print_scripts
orwp_print_styles
either, i’ve always treated them as equivalents to the admin hooks with the same names(just a differing prefix). Like you Michael i’ve used them and suggested them a number of times, and i’ve yet to see any problems(but i’m willing to concede if there’s a valid reason to).It seems you did something similar in your own blog post, though i think the scope of your test was a little more involved than mine, but nonetheless my experiment and your blog have provided some illumination in terms of understanding the interal execution order of filters and hooks and i’ve been quite intrigued with the results.
It’s my impression that either of the hooks should be appropriate, assuming the enqueue fires correctly. I’ve had enqueues on
wp_head
that fire just fine – presumably the earlier hooks should be fine to, though i tend to avoid usingwp_head
(and aim for something earlier) unless there’s a specific need to….Thanks for the feedback guys.. π
@t31os
Sometimes I think about dedicating time to writing in Codex but that thought just drains life from me. The worst about it is that thing that really need clear documentation (internal APIs, low level functions) are something that probably only core developers can properly document (at least initially). It’s a pity but strong documentation does not seems to be a priority for WordPress as project.
For scripts I use variation of Scribu’s advanced stuff http://scribu.net/wordpress/optimal-script-loading.html Technically I don’t even use queue. π
@Michael
Yeah, I (vaguely) remembered your post but was too lazy to look it up and mention. π
Does anybody know a diagram which shows when the WordPress action hooks are fired in the loading process and the steps happening when WordPress is loading? This would be be essential and useful to understand the system and when to hook in custom functions.
Just to show what I basically mean, this is such a diagram for the Zend Framework.
Maybe I am just too stupid to find it on the codex? Or somebody really should create such a thing!
I know this post is over a year old, but… Thank you for this post! I seriously thought I was losing my mind trying to use is_page() on the init() hook. Moving functions with wp conditionals down into the wp hook does the trick!
Very very useful post. Thank you so much…