Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I am using the following code to display a random post from the current category in category archive page (using archive.php). However, when in Tag or Taxonomy archive pages, the post is not correctly displayed from the current Tag or Taxonomy (due to the limitation of category only). How can I modify to make it work with Tag and Taxonomy (or just Taxonomy since Category and Tag are also Taxonomies). Thanks!

// assign the variable as current category
$currentcategory = $cat;

// concatenate the query
$args = 'showposts=1&cat=' . $currentcategory . '&orderby=rand';

$random_query = new WP_Query( $args );

// The Loop

if ( $random_query->have_posts() ) {
while ( $random_query->have_posts() ) {
$random_query->the_post();

// custom template for the random post

}

} else {

// no posts found

}

// Restore original Post Data
wp_reset_postdata();

Edited code in regarding to s_ha_dum's answer:

<?php // The Query

if (is_tax() || is_category() || is_tag() ){
    $qobj = $wp_query->get_queried_object();

// concatenate the query
    $args = array(
        'posts_per_page' => 1,
        'orderby' => 'rand',
        'tax_query' => array(
            array(
                'taxonomy' => $qobj->taxonomy,
                'field' => 'id',
                'terms' => $qobj->term_id
                )
            )
        );
}

$random_query = new WP_Query( $args );

// The Loop
if ( $random_query->have_posts() ) {
    while ( $random_query->have_posts() ) {
        $random_query->the_post(); ?>

//HTML tempalte

<?php   }
} else {
    // no posts found
}
/* Restore original Post Data */
wp_reset_postdata(); ?>
share|improve this question
add comment

2 Answers

up vote 0 down vote accepted

You will need to grab the queried object for the page and fill in your taxonomy information dynamically.

if (is_tax() || is_category() || is_tag() ){
    $qobj = get_queried_object();
    // var_dump($qobj); // debugging only

    // concatenate the query
    $args = array(
      'posts_per_page' => 1,
      'orderby' => 'rand',
      'tax_query' => array(
        array(
          'taxonomy' => $qobj->taxonomy,
          'field' => 'id',
          'terms' => $qobj->term_id,
    //    using a slug is also possible
    //    'field' => 'slug', 
    //    'terms' => $qobj->name
        )
      )
    );

    $random_query = new WP_Query( $args );
    // var_dump($random_query); // debugging only

    if ($random_query->have_posts()) {
        while ($random_query->have_posts()) {
          $random_query->the_post();
          // Display
        }
    }
} 

It is not clear if you need this Loop in addition to the main Loop or as a replacement for it. I am assume this is "in addition" as it would effectively remove archive functionality if it were to replace the main query. You;d have no real archives, just a random post from the archive which isn't very friendly all by itself.

You could use the category.php and the tag.php archive templates to process tags and categories separately. You don't need to use archive.php.

Reference

http://codex.wordpress.org/Class_Reference/WP_Query#Taxonomy_Parameters
http://codex.wordpress.org/Function_Reference/get_queried_object

share|improve this answer
    
Thanks! The code is awesome but output the whole "object" of the current taxonomy (due to var_dump?). I modified it a bit to get rid of var_dump and it works well without the output "object". I am not sure whether the following code is correct in logic and please help to check it out. –  Milo Jun 8 '13 at 18:35
    
Yes, a var_dump is almost always going to be debugging. I put that in there so you could "see" what you are dealing with. What "following code"? –  s_ha_dum Jun 8 '13 at 18:36
    
Oops, I cannot add code in comment. I've added the modified code in the original question. –  Milo Jun 8 '13 at 18:43
    
@Milo : You want that query inside the conditional as well as the Loop that uses it. See the edit. My Fault. –  s_ha_dum Jun 8 '13 at 18:48
    
Thanks for the correction! –  Milo Jun 8 '13 at 19:03
add comment

You could consider using the main query with a custom pre_get_posts hook:

add_action( 'pre_get_posts', 'custom_pre_get_posts' );

function custom_pre_get_posts( $query ) {
    if ( is_admin() or ! $query->is_main_query() )
        return;

    if ( is_archive() ) {
        $query->set( 'orderby', 'rand' );
        $query->set( 'posts_per_page',  1 );
    }

}

and the usual loop, instead of the additional WP_Query().

share|improve this answer
    
Thanks! pre_get_posts is great but it modifies the main loop and I won't be able to display posts on archive pages. But really good an idea to achieve the goal in a smart way. –  Milo Jun 8 '13 at 18:14
    
ok, if you need the extra WP_Query you should check out the nice answer given by @s_ha_dum below. –  birgire Jun 8 '13 at 18:40
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.