0

I have created a mailer template for my my single post.

I can view the mailer version of my post using a url variable ?mailer

I've configured the above using the code below within my single.php...

if ( isset($_GET["mailer"]) ) {  

    get_template_part( 'mailer/template', 'post' );

} else {
/**
 * @package WordPress
 * @subpackage Josh 2014
 * @since MyTheme 1.0
*/
get_header();

Quite simple really.

I then use the get_permalink().'/?mailer' which I then pass to campaign monitor to import my mailer template by url.

Within my mailer/template-single.php I use this the basic loop to pull in my post data.

<?php

    if ( have_posts() ) :                                       
    while ( have_posts() ) : the_post();
?>

<!-- MY POST -->

<?php
    endwhile;                       
    endif;
?>

Everything above is working OK.


My problem I have ran into today is with scheduled posts.

I would like to be able to view my post still (when not logged in) in the mailer template only, and not on the website.

So I amended the code in my mailer template to this...

<?php

    $args = array(
                'post_status' => array('publish','pending','draft','future','private')
            );

    query_posts( $args );
    if ( have_posts() ) :                                       
    while ( have_posts() ) : the_post();

?>

<!-- MY POST -->

<?php
    endwhile;                       
    endif;
?>

I then visited my scheduled post permalink with my mailer variable in a new browser where I am not logged in. And I just get 404 error on my site.

http://www.mywebsite.com/scheduled-test-post/?mailer

So I'm guessing my query_posts above is not working.

Does any one have any ideas in how to amend my query to show scheduled posts in my mailer template?

2 Answers 2

1

First, don't use query_posts().

Note: This function isn't meant to be used by plugins or themes. As explained later, there are better, more performant options to alter the main query. query_posts() is overly simplistic and problematic way to modify main query of a page by replacing it with new instance of the query.

http://codex.wordpress.org/Function_Reference/query_posts

The problem is here though.

http://www.mywebsite.com/scheduled-test-post/?mailer

You are attempting to access a scheduled post when you are not logged in. The problem is not with your code above. This is built into WordPress. Logically, a scheduled posts should not show up to ordinary users until its scheduled date. That logic is made long before your template loads. The code in that template will have no effect.

And to complicate things, the post statuses are rabidly protected. You will notice that that code comes after the query itself, and actually blocks content that might have been returned. The obvious solution...

function allow_scheduled($qry) {
  if (
    $qry->is_main_query()
    && $qry->is_single()
    && isset($_GET['mailer'])
  ) {
    $qry->set('post_status',array('publish','future'));
    echo 'fired';
  }
}
add_action('pre_get_posts','allow_scheduled');

... doesn't work.

The only easy way I know around that is to grab the post directly with get_post().

So you are going to have to interrupt the process early and bypass some of the Core. Something like:

function allow_scheduled($posts) {
  remove_action('posts_results','allow_scheduled');
  if (
    isset($_GET['mailer'])
    && 1 == count($posts)
    && 'future' == $posts[0]->post_status
  ) {
    add_action(
      'template_include',
      function() use ($posts) {
        get_header();
        $q = get_post( $posts[0]->ID );
        var_dump($q);
        // do stuff
        get_footer();
        exit;
      }
    );
  }
}
add_action('posts_results','allow_scheduled');

You are essentially giving everyone access to your scheduled posts, once they discover the ?mailer trick. I don't especially like that, and honestly, this is all a bit convoluted. I'd consider something like an endpoint or possibly leverage the AJAX API.

1
  • Thank you this works great, thanks for taking the time on this, I will reconsider the ?mailer and look into your suggestions. Thank again.
    – Joshc
    Commented Mar 18, 2014 at 15:08
0

When editing your post, click "Preview post". This will take you to a URL with a query string. You should then be able to append:

&mailer=1

Edit, this will work without you query - you should never really do a query in that way on a single template.

7
  • I get this message when view... You do not have permission to preview drafts.
    – Joshc
    Commented Mar 18, 2014 at 13:30
  • What user role are you?
    – James Kemp
    Commented Mar 18, 2014 at 13:30
  • Administrator - but I need it to visible to public, so basically not logged in
    – Joshc
    Commented Mar 18, 2014 at 13:31
  • Ah, I see, that makes it more complicated. You might be better off making a custom page, where you can pass: ?pid=12&mailer=1 where pid is the Post ID. You could then load the post into the page using a custom query?
    – James Kemp
    Commented Mar 18, 2014 at 13:32
  • Perhaps: yourdomain.com/mailer/?pid=12
    – James Kemp
    Commented Mar 18, 2014 at 13:34

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.