I have a typical shortcode which prints some html on a page. The shortcode will only be used on pages where visitors are logged in.

As a separate operation, I've been using a custom field to trigger an action which performs that test and then does the redirect.

But I was wondering if it was possible to combine that action into the shortcode and get rid of the custom field.

IOW: Can I make the shortcode print code in some tag in the header which tests to see if the visitor is logged in and if not, redirect them to the home page.


function jchForm() { 
  add_action( 'no idea where this would go', 'my_redirect_function' );

  $s ='<div class="clearboth">';
  $s .='<form id="my_form" action="" method="post">';
  $s .='<p><label>Your Name</label><input id="user_name" type="text"     name="user_name" class="text" value="" /></p>';
  $s .='<p><label>Your Email Address</label><input id="user_email" type="text" name="user_email" class="text" value="" /></p>';
  $s .='<p><input type="submit" id="my_submit" name="submit"     value="Register" /></p>';
  $s .='</form>';
 $s .='</div>';

return $s;


UPDATE: I tried this, per the has_shortcode() function reference, but although it fires, $post always returns NULL. How do I get this to print -before- any other html but -after- the query grabs $post?

function custom_shortcode_script() {
global $post;
if( is_user_logged_in() && has_shortcode( $post->post_content, 'jchForm') ) {
  var_dump($post->post_content); // always prints NULL
    wp_redirect( '/someplace');

 add_action( 'init', 'custom_shortcode_script' );  
  • Brief answer below, but also see if your logic is correct. Do you really want to redirect for these users if the shortcode is used, or is there another condition instead? If it's a particular page that you want the redirect on, for example, then test for that rather than for the shortcode. Jul 2, 2016 at 8:56

2 Answers 2


Shortcode functions are only called when the content of the visual editor is processed and displayed, so nothing in your shortcode function will run early enough.

Have a look at the has_shortcode function. If you hook in early enough to send headers and late enough for the query to be set up you can check if the content contains your shortcode and redirect then. The template_redirect hook is handy for this as it's about the last hook to be called before your theme sends output to the browser, which triggers PHP to send the headers.

  • See my updated question. I tried this but $post always returns NULL. Where do I put my action so I'm -before- anything is output but -after- the query gets the $post->content?
    – jchwebdev
    Jul 2, 2016 at 21:54
  • Maybe my bad. I've updated the answer. Jul 2, 2016 at 22:10
  • That seems to have done the trick. Is there a reference doc that shows the heirarchy of these hooks? I'm coming from Drupal and they have a (huge) diagram which shows exactly where each hook fires. Does WP have something similar?
    – jchwebdev
    Jul 3, 2016 at 2:47
  • Cool. Sorry for the stupid moment with init. Various people have compiled lists online and the WP Codex has a reasonable list of actions that fire on a typical page request. There are so many though, and some are dynamic based on post type and the like. template_redirect is great for firing code only on the front end after WP and the query are set up. init is good to load code after WP has set its code up but before the query is sorted out. Jul 3, 2016 at 8:04
  • 1
    This is a good beginner's guide, too basic for a seasoned programmer, but helpful if you're new to WP anyhow code.tutsplus.com/articles/… and this might be handy: wordpress.stackexchange.com/questions/71406/… Jul 3, 2016 at 8:43

not a wp_redirect(), but you could do a JavaScript redirect:


won't do anything if the user has JS disabled, so make sure to provide a link for the redirect.

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.