Hook for URL Request

I would like to make XML files downloadable, instead of allowing the browser to displaying them inline.

I know I can use the Content-Disposition: attachment HTTP header (of course, better solutions are welcome!). I want to add this header in all HTTP responses when a user tries to download an XML file.

Read More

I can use the following PHP code:

header('Content-Disposition: attachment; filename="the_filename.xml"');

The problem is: when I can call this instruction? What hook should I use and how?

Related posts

Leave a Reply

3 comments

  1. Actually, my recommendation would be to do things a bit differently. You can add a custom rewrite endpoint to WordPress to handle these files specifically.

    For example, the URL http://site.com/download-xml/the_filename would automatically download the specified file as an attachment.

    First, you need to add a custom rewrite endpoint to set this up:

    function add_endpoint() {
        add_rewrite_endpoint( 'download-xml', EP_ALL );
    }
    add_action( 'init', 'add_endpoint' );
    

    This conveniently also adds a query variable so we can check to see if this endpoint is being used during a standard template redirect.

    function download_redirect() {
        global $wp_query;
    
        // If this isn't the right kind of request, bail.
        if ( ! isset( $wp_query->query_vars['download-xml'] ) || empty( $wp_query->query_vars['download-xml'] ) )
            return;
    
        // Download the file.
    
        exit();
    }
    add_action( 'template_redirect', 'download_redirect' );
    

    In the function above, you can do whatever you need to download the file. Load it from the /wp-content/uploads directory as a stream, set the file headers (with content-disposition set to “attachment”), dynamically generate content based on something in the database, whatever you want.

    Just be sure to have the exit() call at the end, otherwise WordPress will try to execute its regular template redirection calls and you’ll get some ugly “headers already sent” errors later down the road.