0

I have added a custom action hook into my theme. I want to be able to enter a shortcode anywhere in the_content() and have the shortcode print were the custom action hook is rather then the point from where the shortcode was entered.

The shortcode displays a gallery and the custom hook in the header.

It works if I do_shortcode() directly in the action callback but the shortcode displays on all pages. So I know the hook it working but I only want the gallery to display in the header of pages that the shortcode is entered into the_content().

3
  • Your header is going to execute and print to the screen before the content is processed. You will have to do something like this (which answers a question that is a duplicate in all but the fine details): wordpress.stackexchange.com/a/101515/21376 – s_ha_dum Sep 11 '13 at 23:28
  • I should add, a hack like suggested (by me :) ) in that other thread should be avoided if at possible. If you can explain what you are doing there is probably another way to go about this. – s_ha_dum Sep 11 '13 at 23:31
  • I was so busy looking for a fast, quick solution that I overlooked the load order. I ended up using a custom meta box. To was to busy focusing on a fast solution. – Jason Sep 14 '13 at 21:37
1

I think I'd use a meta box:

// create the meta box
function dht_box() {
    add_meta_box(
        'dht_box', // id, used as the html id att
        __( 'Do Header Thing' ), // meta box title
        'dht_cb', // callback function, spits out the content
        'post' // post type or page. This adds to posts only
    );
}
function dht_cb($post) {
  $meta = get_post_meta($post->ID,'do_header_thing',true);
  echo '<input type="checkbox" name="do_header_thing" ',checked($meta),' />';
}
add_action( 'add_meta_boxes', 'dht_box' );

// save the data
add_action(
  'save_post',
  function ($post_id) {
    if (isset($_POST['do_header_thing'])) {
      add_post_meta($post_id,'do_header_thing',true);
    } else {
      delete_post_meta($post_id,'do_header_thing',true);
    }
  }
);

Then, in your template file or on an appropriate hook use:

if (is_single()) {
  $obj = get_queried_object();
  $dht = get_post_meta($obj->ID,'do_header_thing',true);
  if (!empty($dht)) { 
    echo 'Yay';
  }
}

Very crude code but that should give you the idea.

2
  • Thanks, I ended up using a meta box, it worked perfectly...fyi I did not test you code, I used mine. – Jason Sep 14 '13 at 21:35
  • I tested the code (like most code I post here) and it does work but it is very crude. Glad it helped. – s_ha_dum Sep 14 '13 at 22:26
0

So you call a custom action like do_action('print_gallery'); in the header, now you want that when this action is triggered it prints the content of a shorcode inserted anywhere in the post content.

Off course, when you print the_content() you don't want the shortcode is printed again.

So, in the function that hooks print_gallery action you can insert something like this:

add_action('print_gallery', 'print_gallery_shortcode');

function print_gallery_shortcode() {
  if ( ! is_single() ) return;
  $shortcode_name = 'gallery';
  $content = get_queried_object()->post_content;
  if (
    preg_match_all( '/'. get_shortcode_regex() .'/s', $content, $matches )
    && array_key_exists( 2, $matches ) && in_array( $shortcode_name, $matches[2] )
  ) {
    foreach ( $matches[2] as $i => $sc ) {
      if ( $sc == $shortcode_name ) {
        echo do_shortcode( $matches[0][$i] );
        // prevent shortcode is printed again in the post content
        add_shortcode($shortcode_name, '__return_false'); 
      }
    }
  }
}

I've used the standard wordpress [gallery] shortcode, if you use a custom one, just replace the name of shortcode in the $shortcode_name variable.

Now you can insert the shortcode everywhere you want in the content and the shortcode output is printed whre you have do_action('print_gallery') instead of in the content.

(Of course, if the function the_content() is called before than do_action('print_gallery') you'll get a duplicate of shortcode: my function cannot prevent something that already happened..)

Note that the function doesn't interfere with other shortcodes inserted in the post content that are printed normally in the content.

1
  • Thanks, I took that into consideration but decided to just build a custom meta box. I worked perfectly. – Jason Sep 14 '13 at 21:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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