0

I want to view & update the buffer with html "<head>" data section in it, after the head has been generated.

Problem statement:

I have created some shortcodes in a plug-in which, if present on a page, also require some CSS formatting to be included. The CSS should be included in the section as a link to a CSS file. In the shortcode processing, I wp_enqueue_style()'ed the CSS, but since the shortcode processing occurs during the body processing, (after the wp_header processing is complete), the enqueued style is inserted in the html at the end of the <body> section, not in the <head> section.

The Goal:

Insert a script in the <head> section only if the shortcode is used in the page.

The Approach:

I want to get the memory variable that holds the html during the body processing, and insert my script reference just before the </head> tag.

Key factors

The CSS significantly changes the look & feel of the page, so not having the CSS preloaded via the <head> section reference makes the page change and jump about unpleasantly as it is being loaded. And CSS should not be loaded in the body anyway.

Other approaches I could use ...

1) Load the CSS before I know that the shortcode is actual in use in the page. It is bad practice to load stuff that is only used on a couple pages out of 30 pages. (I could share multiple examples of popular plugins that do this and cause noticeable performance degradation on every page)

2) Embed my styling in the html, or enough of it to not have the page change and jump about. Yeah, but that’s bad practice also.

Current (undesired) Code - my-plugin.php

function tf_schedule_load_scripts() {    
    // this CSS gets put in the <body> - I need it in the <head>
    wp_enqueue_style( 'tf-sched', plugins_url ( 'tf-sched.css', __FILE__ ) );
}    

function tf_phonebook_shortcode() {
    add_action( 'wp_enqueue_scripts', 'tf_schedule_load_scripts' );

    ob_start();
    echo "<div class='tf-sched'> ...important stuff here... </div>";
    return ob_get_clean();
}
add_shortcode('TF_PHONE_BOOK', 'tf_phonebook_shortcode');

Potential Version of Desired Code

function tf_phonebook_shortcode() {
    // create the css script reference to add to the already generated <head> section
    $scr_name =  plugins_url ( 'tf-sched.js', __FILE__ );
    $embed_scr = "<link rel='stylesheet' id='tf-sched-css'  href='". $scr_name ."' type='text/css' media='all' />";
    $embed_scr .= "</header>";

    // add to the header after it have been generated.
    // But this buffer name doesn't really exist
    global $HTML_BUFFER;                        
    str_ireplace( "</header>",  $embed_scr, $HTML_BUFFER);

    ob_start();
    echo "<div class='tf-sched'> ...important stuff here... </div>";
    return ob_get_clean();
}
add_shortcode('TF_PHONE_BOOK', 'tf_phonebook_shortcode');
5
  • There's no such thing as a "memory variable that holds the html during the body processing". Not sure where that idea comes from. To do what you're asking you'd need to capture the output of the page, preventing it from being displayed, until you've detected whether or not the shortcode has been used. This will have a considerably bigger impact on performance than just loading a CSS file because nothing could be sent to the browser until the entire page has been rendered. Feb 2, 2019 at 3:32
  • 2
    Possible duplicate of Enqueue Scripts / Styles when shortcode is present Feb 2, 2019 at 3:33
  • Thanks @Jacob! I've been looking all day, that post is perfect.
    – GaryL
    Feb 2, 2019 at 3:47
  • @Jacob - To your first comment - I invented that idea as I spent the entire day on this problem. I would still like to understand the html content generation process, so your ..."you'd need to capture the output of the page"... WP already must do that to send it back to the http requestor, right? Do you know where/how that is done by WP? (Thanks again)
    – GaryL
    Feb 2, 2019 at 3:53
  • "WP already must do that" No, it doesn't. WordPress is essentially just a PHP script that prints stuff out, like any other PHP script/application. The web server would be responsible for sending that output to the browser. And it does it in smaller chunks than just the head and body. Feb 2, 2019 at 3:56

0

Your Answer

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