0
add_action( 'wp_enqueue_scripts', 
function ( ) {
    global $post,$pageparent;
    if(in_array($pageparent, array($post->ID,$post->post_parent))){
        wp_enqueue_style( 'products_pages', urlto.'products_pages.css' );
        wp_enqueue_script('tooltipster',    urlto.'js/jquery.tooltipster.min.js',   array( 'jquery' ));
    }
} 
, 1, 0 );

I've tried hooking this to many different hooks like wp, etc. I cant figure out where to hook so that A. The $post is set up and 2. the style and script get included in the header. With this, they are included in the footer.

It works in the footer, at least the css does, I havent tried this script yet. But, best practices and all.

3
  • urlto is not set.
    – s_ha_dum
    Commented Oct 16, 2014 at 17:54
  • What is global $pageparent? I can't seem to find any reference to that in WordPress, is that something you set?
    – Howdy_McGee
    Commented Oct 16, 2014 at 19:31
  • $pageparent is just an ID that I set outside the action. It's nothing to do with the question. either is urlto. Commented Oct 16, 2014 at 20:31

3 Answers 3

2

It seems that you need to add styles and scripts to a single post. The best way to achieve this is to make use of the conditional tag is_single() With that you target specific single posts or all single posts.

Styles should always be loaded in the header. <link> tags outside the <head></head> tags are invalid HTML. You should check this recent post on this subject.

On the other hand, scripts can be loaded in the footer of header, though many agree that it should be loaded in the footer.

I would also replace your $priority of 1 with PHP_INT_MAX to load your custom styles and scripts after all the other styles and scripts have loaded. This will avoid that your custom scripts and styles will be overwritten by other scripts and styles

Just one note, I don't know what does urlto in your code means, but I should accept that you know that this should either be get_template_directory_uri() or get_stylesheet_directory_uri() depending on parent theme or child theme and I also accept that you have changed this to make your code simpler for the sake of the question

This is an idea of how your code should look like:

add_action( 'wp_enqueue_scripts', 
function ( ) {
    if( is_single() ){
        wp_enqueue_style( 'products_pages', urlto.'/products_pages.css' );
        wp_enqueue_script('tooltipster',    urlto.'/js/jquery.tooltipster.min.js',   array( 'jquery' ));
    }
} 
, PHP_INT_MAX, 0 );

References:

EDIT

From the comments to this answer, it seems that your method works. I have one concern though targeting a post through $post variable. If you specifically need to target justy the single view pages, you are going to run into some issues.

You have to remember, on any page, $post will hold the value of the last post in the loop. What this means is, if , for instance, the specific post you need to target is the last post on the home page, all changes will affect the home page too, and not just the single page view of the post.

That is why you should make use of is_single() to target single posts, and not $post global

6
  • You could go even further and add a at the top of the function global $post then in your if statement, if OP wanted to only add this on a single post you could say: if( isset($post) && $post->ID == 123).
    – Howdy_McGee
    Commented Oct 16, 2014 at 19:34
  • AFAIK, $post is set by the_post()during the loop. Commented Oct 16, 2014 at 20:21
  • I've never had a problem accessing it via wp_enqueu_scripts. I can access it after wp_head() in the header file. I'm not entirely sure when or where global $post is actually set but from just running around printing the global post, it seems like it's set way before the actual loop. Even if I don't have a loop on a page, global $post still seems to be set.
    – Howdy_McGee
    Commented Oct 16, 2014 at 20:26
  • @Howdy_McGee I must still do some tests, but I have one concern that I just thought of, you have to remember, on any page, $post will have the value of the last post on that particular page. This will be problematic if you want to specifically target a post's single page. If that post is the last post on a post page, you changes will affect that post page too, not just that specific post's single page Commented Oct 17, 2014 at 4:41
  • See my update. This should explain it a bit more Commented Oct 17, 2014 at 4:48
0

I cant figure out where to hook so that A. The $post is set up and 2. the style and script get included in the header.

Those two things are mutually exclusive. The global $post won't be set up until the main Loop starts, which is well after the header has already been output.

Edit for comments clarification:

Again, the actual global $post isn't set until the Loop starts. So if you need the actual contents of that variable, you have to wait until then.

But functions like is_single() are only checking if the current query is for a single post or not. It doesn't depend on the actual contents of the post.

The functions called "Conditional Tags" are not looking at the actual $post from the Loop, they are looking at the query. Now, the query has run by this point, so the data is in memory, it's just not in the global $post. So, if you wanted to check if this is the single post for the post named "Example", then yes, is_single('Example') will work just fine at this early point in the code.

The global $post is not set up yet. But the data does exist in the main $wp_query and yes, it can be read and accessed in various ways by the time the theme template has loaded. And yes, you can base conditions like loading stuff on it.

But it's not the global $post, and it has not gone through the Loop, and thus it hasn't gone through the assorted WP filter functions yet. So if you do something like look ahead to the content in the post, then what you get will be straight data from the database, not the filtered pretty data that WordPress produces. Shortcodes won't be processed. Plugins won't have filtered the post and added their magic. Embedded videos won't be embedded yet. That sort of thing.

9
  • Ok, so this is just the way it has to be, then? Is there a problem with inlcuding js and css in the footer? FOUC? Commented Oct 16, 2014 at 16:43
  • If you're absolutely dependent on enqueueing only for certain posts, then yeah, that's how it has to be. Nothing wrong with putting JS/CSS in the footer, as such. Or, change your script and styles to be on all pages instead of only some of them. You can use is_single() and other template tags as well, if you want to limit it to certain types of pages, like single post pages and not archives or the main blog page.
    – Otto
    Commented Oct 16, 2014 at 18:20
  • I'm just tryna not include css/js everywhere when only these few pages need it. So, is_single() will work before $post is setup? That seems counter-intuitive. Commented Oct 16, 2014 at 18:26
  • Edited my post to answer your question because comments are not big enough.
    – Otto
    Commented Oct 16, 2014 at 18:41
  • @Otto it looks like the global $post is set up before the actually main loop. So you should still be able to get it in the header.php. So saying that global $post is only accessible during The Loop is incorrect.
    – Howdy_McGee
    Commented Oct 16, 2014 at 19:27
0

One of the parameters of the enqueue_script function is the $in_footer

take a look of the function usage arguments:

wp_enqueue_script( $handle, $src, $deps, $ver, $in_footer )

So to add your script(or css) to the header instead of footer you should try something like:

wp_enqueue_script('tooltipster', urlto.'/jsjquery.tooltipster.min.js',   array( 'jquery' ),'',false);

Generally scripts are better to be loaded at the bottom while css is usually found on top, consider that if your script is jquery dependent you're probably better off setting $in_footer value to true,

4
  • $in_footer is default to false. Therefore, I am wanting it to be in the header, by not specifying. However, I am too late. Commented Oct 16, 2014 at 20:35
  • Setting the jquery dependency might lead to loading the script after jquery is loaded, even is $in_footer is set to false .. you need to analize your source to see where the scripts are placed, consider that the hooks are wp_head(in header.php) and wp_footer (footer.php)
    – maioman
    Commented Oct 16, 2014 at 21:03
  • Good guess, but jquery is loaded in the head. And that wouldnt account for the css. Commented Oct 16, 2014 at 22:17
  • It happend to me once
    – maioman
    Commented Oct 17, 2014 at 8:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.