• Hi, I’m trying to develop a custom plugin along with a custom shortcode. The goal is to generate dynamic content based on a query parameter in the page URL.

    For example: https://www.example.com/product?id=12345

    My shortcode function would decode the $_GET[‘id’] parameter and output something related. I can do that in my plugin like this:

    function scode_func() {
       if (isset($_GET['id']))
       {
       ...
       }
       return $output;
    }
    add_action( 'init', function() {
      add_shortcode( 'test', 'scode_func');
    });

    So the code above does work as I need. Now, I’m trying to figure out how to have this function return an error in the form of a response code like 301 or 404 if ‘id’ is invalid or missing. However, I can’t seem to figure out how to change the response code as the headers have already been written by the time this function fires. For example:

    if (!isset($_GET['id'])
    {
      header('HTTP/1.1 404 Not Found');
      return;
    }

    returns an error that the headers have already been written. I’ve also tried $wp_query->set_404() and also status_header(404, ‘Not found’), but nothing seems to work. Thanks for any suggestions!

Viewing 3 replies - 1 through 3 (of 3 total)
  • Moderator bcworkz

    (@bcworkz)

    As you’ve identified, it’s a “catch 22” (impossible) situation as the headers have already been sent. All you could possibly do is invoke a JS redirect, but it still wouldn’t change the current page’s status response. Or simply output some sort of error message, but you cannot change the status from a shortcode.

    Here’s an idea, albeit rather clunky: Check the request early on, before headers are sent. If it’s one where there should be an ID but it’s missing or invalid, alter the status header before it’s sent. “wp_headers” filter I believe. I don’t think 301 is appropriate for a bad request. 400 is bad request, or the usual 404.

    If you send 404, WP may return its error page, bypassing your shortcode. You may need to unset the 404 query vars through “pre_get_posts” and reset the requested page name.

    Thread Starter jyl087

    (@jyl087)

    Thank you bcworkz for taking a look at my question. I think I tried the wp_headers filter, but maybe I didn’t do it right. In other applications in the past, I’ve used ob_start() in PHP to buffer output for cases just like this. Is that a possibility to set page buffering on globally in WP? I may poke around and hack something.

    The thinking about 301 is for the case where one ID has been replaced by a new one. And, the desire to return proper response codes rather than use JS is for SEO purposes.

    [EDIT] I just found this article that sheds light on what I’m trying to do.

    • This reply was modified 1 year, 7 months ago by jyl087.
    Moderator bcworkz

    (@bcworkz)

    Ah, my bad, status is sent separately before wp_headers. Use the ‘status_header’ filter.

    Output buffering is a good idea! I’m not sure if re-sending status will override a prior send, but now that we’ve identified the right filter, it’s kind of moot.

    301 is for the case where one ID has been replaced by a new one

    Agreed. But what about missing or invalid ID where an appropriate new one is unknown?

Viewing 3 replies - 1 through 3 (of 3 total)
  • The topic ‘How to change page response code (e.g. 404, 301) in custom plugin’ is closed to new replies.