0

WordPress beginner here. I'm trying to check if a shortcode exists in the page being requested by the user, then if it does, redirect if the user is not signed in.

function redirect_to_home() {
  if (has_shortcode(get_the_content(), 'shortcode')) {
    if(!is_admin() && !is_user_logged_in()) {
      //redirect
      exit();
    }
  }
}
add_action('template_redirect', 'redirect_to_home');

Is this close? And currently this code is placed in the functions.php files, is this correct?

1
  • You might also want to add an additional is_single() conditional before checking if the shortcode exists or not.
    – Johansson
    Commented May 7, 2018 at 21:17

2 Answers 2

1

If you look at the source code of add_shortcode you will see this function doing little more than store the name of the shortcode in a global array. So, checking if a shortcode exists means looking it up in the array.

Hence, if you want to check for a specific shortcode in the_content you must be sure that shortcode has already been added at the point you need it. Else has_shortcode will say it doesn't exist.

Luckily, looking at the hook order, you see template_redirect being executed after after_setup_theme, the default hook to load theme related stuff. If you use that hook to add your shortcode (in functions.php), you can be sure your shortcode exists by the time you get to template_redirect.

So, yes, you are on the right track. You're using the right hook and the data you need is available at that point in WP's execution order.

0

I assume that you have looked at the docs: https://codex.wordpress.org/Shortcode_API

...which would show you the proper code to check for a shortcode. Let's say your shortcode is called 'redirectme'. So the code you would use in your functions.php would be something like:

// redirect for the [redirectme] shortcode
function redirect_me( $atts ){
    // do something if the shortcode is found
}
add_shortcode( 'redirectme', 'redirect_me' );

The redirect_me function will be called if the shortcode [redirectme] is found. You would then modify the function to do the needed redirect.

For instance, if you wanted to redirect to http://example.com/the-new-page , you would put this inside the redirect_me function

$url = 'http://example.com/the-new-page';
wp_redirect( $url );
exit;

Check out the docs on the wp_redirect function: https://developer.wordpress.org/reference/functions/wp_redirect/ . Note that the exit is required, or the rest of the code for that page will execute.

Added

As mentioned in a comment to this answer, the wp_redirect() won't work - it will cause a 'Headers already sent' error. This is because output has already started before the wp_redirect() function is called by the appearance of the shortcode in the content.

So, you have to buffer the output before WP starts sending output. You can do that with this code:

function app_output_buffer() {
    ob_start();
}  
add_action('init', 'app_output_buffer');

...which I got from here https://tommcfarlin.com/wp_redirect-headers-already-sent/ (see that for more info). And there are probably similar references to ob_start() here. Because that function will 'fire' before WP output starts, the wp_redirect() will work if fired by the shortcode.

So, add the above code to your functions.php file, and you will be able to do a wp_redirect() after WP has started output.

Another approach would be to change the template used for the post/page to check for valid user login, and redirect if the user has not logged in. You still might need the ob_start() function, depending on where you check for user login.

4
  • Thank you! For some reason when I change redirectme to my shortcode, the function (redirect_me) still does not get called..
    – now_world
    Commented May 7, 2018 at 23:23
  • Look at the docs for add_shortcode. The first parameter is the shortcode 'value' (inside the brackets), and the second parameter is the function called. The shortcode function is called when the post/page content is returned in The Loop. Shortcodes don't work outside page/post content. Commented May 8, 2018 at 1:33
  • This cannot work, because the shortcode is rendered long, long, long after the HTTP headers have been sent.
    – fuxia
    Commented May 8, 2018 at 13:00
  • Ah, that is true @fuxia -- so I have modified the answer to (hopefully) get rid of your downvote. Commented May 8, 2018 at 19:17

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.