1

This is a music website with multiple artist pages - one page per artist. New content is added as a post with a Wordpress tag to denote the artist. This is so that I can add a Wordpress loop on each artist page to show all the posts filtered with that artist's tag.

I've got the filtered loop working correctly, but unfortunately it's currently hardwritten inside the page template's HTML, so it's only filtering for one tag. I don't want to create a new page template for each artist, so I'd like to add it to my functions.php file instead, where I can instead create a new shortcode for each artist.

Here's the current code in my page template, which filters the loop for all posts with our seefour tag:

<?php
query_posts( "tag=seefour" );
if ( have_posts() ) { ?>
  <?php while ( have_posts() ) { ?>
    <?php the_post(); { ?>
    <div class="jd-box">
      <a href="<?php the_permalink(); ?>">
        <?php the_post_thumbnail( ); ?>
        <div class="jd-overlay"></div>
        <div class="jd-overlay-text">
          <?php the_title(); ?>
        </div>
      </a>
    </div>
<?php } ?>
<?php } ?>
<?php } ?>

I'm assuming the best option is to turn this into a seefour shortcode inside my functions.php file - how can I achieve this?

Bonus question: is this sustainable in the long run (with 30-50+ artists) or will it cause a lot of redundant code? Open to suggestions...

P.S. I know this kind of question has been answered already (starting with raw PHP), but since I'm starting with a mix of HTML/PHP (and I'm a PHP newb), I just can't get it to work. So my apologies for asking again.

2 Answers 2

2

First of all, you should never ever use query_posts(). It is internal WordPress function to create and maintain the main WordPress cycle. Using it, you can crash your site in unpredictable manner. You should use get_posts() or WP_Query instead.

To have your custom shortcode, add the following to your functions.php:

function showtag_shortcode( $atts ) {
    $atts = shortcode_atts( array(
        'tag' => '', // Default value.
    ), $atts );

    $posts = get_posts( 'tag=' . $atts['tag'] );
    if ( $posts ) {
        $output = '';
        foreach ( $posts as $post ) {
            setup_postdata( $post );
            $output .= '<div class="jd-box">';
            $output .= '<a href="' . get_the_permalink( $post ) . '">';
            $output .= get_the_post_thumbnail( $post );
            $output .= '<div class="jd-overlay"></div>';
            $output .= '<div class="jd-overlay-text">';
            $output .= get_the_title( $post );
            $output .= '</div>';
            $output .= '</a>';
            $output .= '</div>';
        }
    } else {
        $output = 'no data';
    }
    wp_reset_postdata();

    return $output;
}

add_shortcode( 'showtag', 'showtag_shortcode' );

This function created [showtag] shortcode with one parameter: tag. You can use this shortcode on any page as follows:

[showtag tag="seefour"]
[showtag tag="disco"]

etc. You will have posts with relevant tags to be shown in place of your shortcode.

Sign up to request clarification or add additional context in comments.

6 Comments

I somehow didn't see your answer until I had already marked Junaid's correct above. I trust your judgment on get_posts() vs query_posts() but after adding your code exactly to my functions.php file, and then adding [showtag tag="seefour"] to my SeeFour page, it drops the shortcode in as plain text. Perhaps I missed something?
If you see shortcode as a plain text, it means that probably you have missed to add add_shortcode... line to your functions.php. Anyway, I have found some mistakes in my code during testing and updated the answer. Please copy code from answer and try again.
Circling back to this, your code works EXCELLENTLY with a hardcoded shortcode <?php echo do_shortcode("[showtag tag='seefour']"); ?> inside the page template. I just can't figure out why it won't work properly as a normal [shortcode] in the WP text editor.
It is strange, on my test site everything is OK. What theme do you use?
This is on a custom theme I'm actively building from scratch. I uploaded the files directly to `\wp-content\themes` directory. It's admittedly my first attempt, but I have such minimal custom php in place that I'm not sure what could be interfering. The theme is still in its infancy. Do I need to declare support for it or something?
|
0

Putting a whole loop in a shortcode will make it messy, I know you can use shortcodes in Widgets etc as well but I guess that's not what you're after.

If so, the best option would be to make this code a page template say Artist and pass a variable in URL i.e. http://example.com/artist?t=seefour and then use the following code in the page template.

<?php
/**
 * Template Name: Artist
 */

query_posts( "tag=" . $_GET['t'] );
if ( have_posts() ) {
?>
  <?php while ( have_posts() ) { ?>
    <?php the_post(); { ?>
    <div class="jd-box">
      <a href="<?php the_permalink(); ?>">
        <?php the_post_thumbnail( ); ?>
        <div class="jd-overlay"></div>
        <div class="jd-overlay-text">
          <?php the_title(); ?>
        </div>
      </a>
    </div>
<?php
    }
  }
}
?>

This can be used for any number of artists, totally flexible because it is dependant on a variable that is provided on run time (when accessed).

10 Comments

Thanks for the input. I implemented your code as written, and then added the following snippet to my functions.php file: function add_query_vars_filter( $vars ){ $vars[] = "t"; return $vars; } add_filter( 'query_vars', 'add_query_vars_filter' ); But when I try to add ?t=seefour to the end of the URL - in this case, localhost/dev/gang/?t=seefour - it keeps getting rewritten as localhost/dev/gang/tseefour instead. I know I'm missing something here... any idea what it is?
Never saw that one before. Please check if any of the plugin you use are putting in some kind of rewrite rules.
No active plugins on the site at the moment. Does my functions.php code at least look like what you'd expect for passing the custom t variable to my URL? Am I supposed to be adding ?t=seefour directly inside the Permalink edit below the Page title?
@John No, you shouldn't add it there. Just set up this page once. E.g. create a page called "Artist", assign the template and then pass ?t=seefour on run time.
This is why I suggested this method. So, you don't have to create hundreds of pages for each artist you add.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.