Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I'm building a small gallery plugin and I'd like to only load scripts/styles onto the page IF the gallery has been loaded via the template tag. The template tag can take a post ID parameter when used to call a post's gallery from wherever you need within the theme.

I know how to do this on singular pages (I can just lookup the meta_key and match it against the currently viewed post) but detecting if there's a gallery present on say the homepage (or any other page) is proving more difficult.

So let's assume the template tag looks something like this:

if ( function_exists( 'my_gallery' ) )
    echo my_gallery( '100' ); // gallery of image from post 100 will be shown

And the gallery function looks like this (simplified):

function my_gallery( $post_id = '' ) {
    // whole bunch of stuff in here which is returned
}

The scripts and styles for the gallery would look like this (simplified):

function my_gallery_scripts() {

   wp_register_script( 'my-gallery-js', MY_GALLERY_URL . 'js/my-gallery.js', array( 'jquery' ), '1.0', true );
   wp_register_style( 'my-gallery-css', MY_GALLERY_URL . 'css/my-gallery.css', '', '1.0', 'screen' );

    // need to load these conditionally, but how?
    wp_enqueue_style( 'my-gallery-js' );
    wp_enqueue_script( 'my-gallery-css' );

}
add_action( 'wp_enqueue_scripts', 'my_gallery_scripts' );

I've tried using set_query_var inside my_gallery() like this to kind of set a global variable inside $wp_query.

 function my_gallery( $post_id = '' ) {

    set_query_var( 'has_gallery', true );

    // whole bunch of stuff in here which is returned
}    

The problem though is that I can't use get_query_var inside the wp_enqueue_scripts action.

So the following would be ideal for me I believe, loading has_gallery into the $wp_query object which would be available to me on every page (except it doesn't work).

 function my_gallery_scripts() {

   wp_register_script( 'my-gallery-js', MY_GALLERY_URL . 'js/my-gallery.js', array( 'jquery' ), '1.0', true );
   wp_register_style( 'my-gallery-css', MY_GALLERY_URL . 'css/my-gallery.css', '', '1.0', 'screen' );

    // does not work
    $has_gallery = get_query_var( 'has_gallery' );

    if ( $has_gallery ) {
        wp_enqueue_style( 'my-gallery-js' );
        wp_enqueue_script( 'my-gallery-css' );
    }
}
add_action( 'wp_enqueue_scripts', 'my_gallery_scripts' );

Is there another way to set a global option similar to set_query_var but will work in my scenario? I'd like to obviously avoid the use of a global variable. I've also tried setting a constant to no avail.

share|improve this question
    
Why don't you use the conditional tag is_home() inside your function to check if you're on the homepage or, pass an additional argument to your gallery function for which you would check the existence of within your function, if found/set/not null then you can assume the function is set from the homepage. –  userabuser Jul 6 '13 at 12:39
    
@userabuser Because it might not be just on the homepage, the template tag could be called from anywhere –  Andrew Jul 6 '13 at 21:41
    
@Andrew Could you show us that meta key? –  kaiser Jul 7 '13 at 11:55

3 Answers 3

For scripts this is no-brainer - just enqueue inside my_gallery() function and they will be output in footer (since header already passed).

However stylesheets are a challenge, they are only supposed to work in head section and enqueueing for footer is not supported.

Essentially you need to know if function was called before it was called. This has no simple solution for conditions given.

I would probably try to load stylesheet from JS code to achieve this in form you are describing.

share|improve this answer
    
Ahh didn't realise you could enqueue inside another function like that, that's good news. Looks like I can get half way there and just leave the CSS as is, loading on every page. Don't want to attempt any hacky way of loading the CSS –  Andrew Jul 6 '13 at 21:44

The best way that I could imagine (and with best I mean "working", not "fast"), is to check the post contents for the existence of that shortcode. Using the core Regex function makes that quite easy.

Step 1: Register

/**
 * Register the needed assets
 */
add_action( 'wp_enqueue_scripts', 'wpse_105537_register_assets', 0 );
function wpse_105537_register_assests()
{
    wp_register_script(
        'wpse_105537_script',
        // ETC.
    );
    wp_register_style(
        'wpse_105537_style',
        // ETC.
    );
}

Step 2: Enqueue

/**
 * Enqueue the needed assets if the shortcode is present anywhere
 */
add_action( 'wp_enqueue_scripts', 'wpse_105537_register_assets' );
function wpse_105537_enqueue_assets()
{
    if ( ! wpse_105537_check_content() )
        return;

    wp_enqueue_script( 'wpse_105537_script' );
    wp_enqueue_style( 'wpse_105537_style' );
}

Helper: Search the shortcode inside the post contents

This helper function aborts after the first match.

/**
 * Check if any of the posts has the shortcode in its post_content
 * @return bool
 */
function wpse_105537_check_content()
{
    global $wp_query;

    foreach ( $GLOBALS['wp_query']->posts as $post )
    {
        $pattern = get_shortcode_regex();
        if (
            preg_match_all( '/'. $pattern .'/s', $post->post_content, $matches )
            AND array_key_exists( 2, $matches )
            AND in_array( 'gallery', $matches[2] )
        )
            return true;
    }

    return false;
}
share|improve this answer
    
Not sure I follow on this. I'm not using a shortcode, but rather a template tag, and this would be called outside of the post content area. It could be potentially displayed anywhere. –  Andrew Jul 6 '13 at 21:40
    
@Andrew Sorry, misunderstanding on my side... –  kaiser Jul 6 '13 at 21:44
    
no problem, good to know actually because I'll most likely want to do something with the shortcode usuage in the future. –  Andrew Jul 6 '13 at 21:54

I know how to do this on singular pages (I can just lookup the meta_key and match it against the currently viewed post) but detecting if there's a gallery present on say the homepage (or any other page) is proving more difficult.

So if there's a meta key, it would be even more simple: Just grab it early. The first two functions can be taken from the other answer. Just the check itself would be replaced with the following function:

/**
 * Check if any of the posts has the needed gallery meta data attached
 * @return bool
 */
function wpse_105537_check_meta()
{
    global $wp_query;

    foreach ( $GLOBALS['wp_query']->posts as $post )
    {
        if ( '' !== get_post_meta( $post->ID, 'your_meta_key', true ) )
            return true;
    }

    return false;
}
share|improve this answer
    
the meta_key would be _image_gallery. This meta_key holds the ID's of all the image attachments associated with the post. So you're saying that your function above would detect if there's any post on the page (no matter where we are) that has that specific meta key? –  Andrew Jul 7 '13 at 22:20
    
@Andrew Sorry, from the code you showed above I thought you're a developer and familiar with code. To answer your question: Yes, get_post_meta() returns empty (updated answer). –  kaiser Jul 7 '13 at 22:24
    
I'm familiar with get_post_meta but just checking how it all works as never used $wp_query to look up the meta key that early on, great idea. Going to give this a go soon. –  Andrew Jul 7 '13 at 23:06
    
This isn't working and I can see why. Lets say the "hello world" post (ID of 1) had a meta_key "_image_gallery" with 3 images associated with it. What I'd like to do is take that gallery and show it on a completely different page. So if I use the template tag echo my_gallery( '1' ); and include it into the contact page for example, which has a slug of /contact, the $wp_query object will not have the post ID of hello world inside, therefore I cannot look up the post meta for it. –  Andrew Jul 8 '13 at 0:06
    
I was hoping I could somehow set a global variable called has_gallery = true if the parameter in the function call was entered, in this case 1 for the hello world post ID. Then no matter what page I'm on, eg contact, I could simply look for the presence of the variable and load the required scripts/styles. –  Andrew Jul 8 '13 at 0:09

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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