Skip to content

Instantly share code, notes, and snippets.

@apos37
Last active October 4, 2022 18:32
Show Gist options
  • Save apos37/4c169503d419c8d7e6d7aee04bb7ab7a to your computer and use it in GitHub Desktop.
Save apos37/4c169503d419c8d7e6d7aee04bb7ab7a to your computer and use it in GitHub Desktop.
WordPress Shortcode Display Posts with Tax Filter
<?php
/**
* Display posts with taxonomy filter
*
* Add file to same folder as functions.php
* Add to functions.php: get_template_part( 'class-posts-tax-filter', '' );
* USAGE: [posts_tax_filter post_type="post" qty="6"]
*/
// Exit if accessed directly.
if ( !defined( 'ABSPATH' ) ) {
exit;
}
/**
* Initiate the class
*/
new ERI_POSTS_TAX_FILTER;
/**
* The class.
*/
class ERI_POSTS_TAX_FILTER {
/**
* Constructor
* Add hooks like so: add_filter( 'filter_name', [$this, 'function_name' ] );
* Run functions directly like so: $this->fake_function();
*/
public function __construct() {
// Shortcode
add_shortcode( 'posts_tax_filter', [ $this, 'shortcode' ] );
} // End __construct()
/**
* The shortcode
*
* @return string
*/
public function shortcode( $atts ) {
// Get the attributes
$atts = shortcode_atts( [
'post_type' => 'post',
'taxonomies' => '',
'qty' => 6
], $atts );
// If we have more than one post type, let's convert to array
if ( strpos( $atts[ 'post_type' ], ',' ) !== false ) {
$post_types = explode( ',', str_replace( ' ', '', $atts[ 'post_type' ] ) );
// Add the single post type to an array
} else {
$post_types = [ $atts[ 'post_type' ] ];
}
// Iter the post types
foreach ( $post_types as $post_type ) {
// Get the taxonomies
$this_taxonomies = get_object_taxonomies( $post_type );
// Add the taxonomies
foreach ( $this_taxonomies as $t ) {
$taxonomies[] = $t;
}
}
// Add some CSS
$results = '<style>
.ptf-outer-container {
display: flex;
justify-content: space-between;
align-items: stretch;
flex-direction: row;
flex-wrap: wrap;
align-content: flex-start;
height: 100%;
gap: 20px;
}
.ptf-outer-container .post-container {
border: 1px solid #ddd;
border-radius: 10px;
box-shadow: 2px 2px 10px #ddd;
padding: 20px;
width: 30%;
}
.ptf-outer-container h4 {
margin-top: 0;
}
</style>';
// Get the current page
$page = get_query_var( 'paged' );
// Get the current url
global $wp;
$current_url = home_url( $wp->request );
$pos = strpos( $current_url , '/page' );
$current_url = substr( $current_url, 0, $pos );
// Capture the filtered terms
if ( isset( $_GET[ 'term' ] ) && $_GET[ 'term' ] != '' ) {
$search_term = sanitize_text_field( $_GET[ 'term' ] );
} else {
$search_term = false;
}
// Start the filter
$results .= '<form method="get" action="'.$current_url.'">
<label for="pft-filter"></label>
<select id="pft-filter" name="term">
<option>-- Select a Taxonomy Term to Filter --</option>';
// Add the taxonomies
foreach ( $taxonomies as $taxonomy ) {
// Get all terms for this taxonomy
$this_terms = get_terms( $taxonomy, array(
'hide_empty' => true,
) );
// Get the tax object
$taxonomy = get_taxonomy( $taxonomy );
// dpr( $taxonomy );
// Iter the terms
foreach ( $this_terms as $this_term ) {
// Mark selected
if ( $search_term && $this_term->term_id == $search_term ) {
$selected = ' selected';
} else {
$selected = '';
}
// Add the option
$results .= '<option value="'.$this_term->term_id.'"'.$selected.'>'.$taxonomy->labels->singular_name.': '.$this_term->name.'</option>';
}
}
// Add the view button
$results .= '<input type="submit" value="View" />';
// End the filter
$results .= '</select>
</form>';
// Start the query args
$args = [
'post_type' => $post_types,
'posts_per_page' => $atts[ 'qty' ],
'paged' => $page
];
// Are we filtering by tax?
if ( $search_term ) {
// Get the tax
$this_term = get_term( $search_term );
// Start the tax query
$tax_query = [
'taxonomy' => $this_term->taxonomy,
'field' => 'term_id',
'terms' => $search_term
];
// Are we filtering by term?
if ( $search_term ) {
$tax_query[ 'terms' ] = $search_term;
}
// Add the tax query to the args
$args[ 'tax_query' ] = [ $tax_query ];
}
// Run the query
$posts = new WP_Query( $args );
// Make sure we found posts
if ( $posts->have_posts() ) {
// Add the count
$results .= '<strong>Total: '.$posts->found_posts.'</strong><br><br>';
// Start the outer container
$results .= '<div class="ptf-outer-container">';
// Iter the posts
while ( $posts->have_posts() ) {
// Initiate the post
$posts->the_post();
// Set the id
$post_id = get_the_ID();
// Get the title
$title = get_the_title();
// Check if there is a featured image
$featured_img_url = get_the_post_thumbnail_url( $post_id, 'full' );
if ( $featured_img_url ) {
// Get the image id
$image_id = get_post_thumbnail_id();
// Get alt text
if ( get_post_meta( $image_id, '_wp_attachment_image_alt', true ) && get_post_meta( $image_id, '_wp_attachment_image_alt', true ) != '' ) {
$image_alt = get_post_meta( $image_id, '_wp_attachment_image_alt', true );
} else {
$image_alt = $title;
}
// Get the image title
if ( get_the_title( $image_id ) && get_the_title( $image_id ) != '' ) {
$image_title = get_the_title( $image_id );
} else {
$image_title = $title;
}
// Add the featured image
$add_featured_image = '<div class="featured-img">
<a href="'.get_the_permalink().'" title="'.$image_title.'" style="outline: none;"><img src="'.$featured_img_url.'" alt="'.$image_alt.'"></a>
</div>';
} else {
$add_featured_image = '';
}
// Get the excerpt
if ( get_the_excerpt() && get_the_excerpt() != '' && get_the_excerpt() != ' ...' ) {
$excerpt = '<p>'.get_the_excerpt().'</p><br>';
} else {
$excerpt = '';
}
// Start the post container, add the title, excerpt, and thumbnail
$container = '<div class="post-container">
'.$add_featured_image.'
<h4><a href="'.get_the_permalink().'">'.$title.'</a></h4>
'.$excerpt;
// Store the terms here
$add_terms = [];
// Iter the taxonomies
foreach ( $taxonomies as $taxonomy ) {
// Get the terms
$terms = get_the_terms( $post_id, $taxonomy );
// Iter the terms
foreach ( $terms as $term ) {
// Add the term to the array with current url link
$add_terms[] = '<a href="'.$current_url.'?tax='.$taxonomy.'&term='.$term->term_id.'">'.$term->name.'</a>';
}
}
// Add the terms to the container
$container .= implode( ', ', $add_terms );
// End the container
$container .= '</div>';
// Add the container
$results .= $container;
}
// End the outer container
$results .= '</div>';
// Add pagination links
$results .= '<br></br><div class="page-nav-container">
'.paginate_links( [
'base' => preg_replace( '/\?.*/', '/', get_pagenum_link(1) ) . '%_%',
'current' => max( 1, get_query_var( 'paged' ) ),
'format' => 'page/%#%',
'total' => $posts->max_num_pages,
'prev_text' => __('<'),
'next_text' => __('>'),
'add_args' => array(
'term' => get_query_var( 'term' )
)
] ) . '</div>';
// Else say it isn't so
} else {
$results .= 'No posts found.';
}
// Return the results
return $results;
} // End shortcode()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment